export function hoistTypeAnnotations()

in compiler/src/model/utils.ts [724:778]


export function hoistTypeAnnotations (type: model.TypeDefinition, jsDocs: JSDoc[]): void {
  // in most of the cases the jsDocs comes in a single block,
  // but it can happen that the user defines multiple single line jsDoc.
  // We want to enforce a single jsDoc block.
  assert(jsDocs, jsDocs.length < 2, 'Use a single multiline jsDoc block instead of multiple single line blocks')

  const validTags = ['class_serializer', 'doc_url', 'doc_id', 'behavior', 'variants', 'variant', 'shortcut_property',
    'codegen_names', 'non_exhaustive', 'es_quirk', 'behavior_meta', 'ext_doc_id']
  const tags = parseJsDocTags(jsDocs)
  if (jsDocs.length === 1) {
    const description = jsDocs[0].getDescription()
    if (description.length > 0) type.description = description.trim().replace(/\r/g, '')
  }

  setTags(jsDocs, type, tags, validTags, (tags, tag, value) => {
    if (tag === 'stability') {
    } else if (tag.endsWith('_serializer')) {
    } else if (tag === 'shortcut_property') {
      if (type.kind === 'interface') {
        type.shortcutProperty = value
      } else {
        assert(jsDocs, false, 'Request and Responses cannot have @shortcut_property')
      }
    } else if (tag === 'variants') {
    } else if (tag === 'variant') {
    } else if (tag === 'non_exhaustive') {
      assert(jsDocs, typeof tags.variants === 'string', '@non_exhaustive only applies to enums and @variants')
    } else if (tag === 'doc_url') {
      assert(jsDocs, isValidUrl(value), '@doc_url is not a valid url')
      type.docUrl = value.replace(/\r/g, '')
    } else if (tag === 'doc_id') {
      assert(jsDocs, value.trim() !== '', `Type ${type.name.namespace}.${type.name.name}'s @doc_id cannot be empty`)
      type.docId = value.trim()
      const docUrl = docIds.find(entry => entry[0] === value.trim())
      assert(jsDocs, docUrl != null, `The @doc_id '${value.trim()}' is not present in _doc_ids/table.csv`)
      type.docUrl = docUrl[1].replace(/\r/g, '')
    } else if (tag === 'ext_doc_id') {
      assert(jsDocs, value.trim() !== '', `Type ${type.name.namespace}.${type.name.name}'s @ext_doc_id cannot be empty`)
      type.extDocId = value.trim()
      const docUrl = docIds.find(entry => entry[0] === value.trim())
      assert(jsDocs, docUrl != null, `The @ext_doc_id '${value.trim()}' is not present in _doc_ids/table.csv`)
      type.extDocUrl = docUrl[1].replace(/\r/g, '')
    } else if (tag === 'codegen_names') {
      type.codegenNames = parseCommaSeparated(value)
      assert(jsDocs,
        type.kind === 'type_alias' && type.type.kind === 'union_of' && type.type.items.length === type.codegenNames.length,
        '@codegen_names must have the number of items as the union definition'
      )
    } else if (tag === 'es_quirk') {
      type.esQuirk = value.replace(/\r/g, '')
    } else {
      assert(jsDocs, false, `Unhandled tag: '${tag}' with value: '${value}' on type ${type.name.name}`)
    }
  })
}