export function generateId()

in tools/apiview/emitters/typespec-apiview/src/namespace-model.ts [174:285]


export function generateId(obj: BaseNode | NamespaceModel | undefined): string | undefined {
  let node;
  if (obj === undefined) {
    return undefined;
  }
  if (obj instanceof NamespaceModel) {
    return obj.name;
  }
  let name: string;
  let parentId: string | undefined;
  switch (obj.kind) {
    case SyntaxKind.NamespaceStatement:
      node = obj as NamespaceStatementNode;
      name = node.id.sv;
      parentId = generateId(node.parent);
      break;
    case SyntaxKind.DecoratorExpression:
      node = obj as DecoratorExpressionNode;
      switch (node.target.kind) {
        case SyntaxKind.Identifier:
          return `@${node.target.sv}`;
        case SyntaxKind.MemberExpression:
          return generateId(node.target);
      }
    case SyntaxKind.EnumMember:
      node = obj as EnumMemberNode;
      name = node.id.sv;
      parentId = generateId(node.parent);
      break;
    case SyntaxKind.EnumSpreadMember:
      node = obj as EnumSpreadMemberNode;
      return generateId(node.target);
    case SyntaxKind.EnumStatement:
      node = obj as EnumStatementNode;
      name = node.id.sv;
      parentId = generateId(node.parent);
      break;
    case SyntaxKind.Identifier:
      node = obj as IdentifierNode;
      return node.sv;
    case SyntaxKind.InterfaceStatement:
      node = obj as InterfaceStatementNode;
      name = node.id.sv;
      parentId = generateId(node.parent);
      break;
    case SyntaxKind.MemberExpression:
      node = obj as MemberExpressionNode;
      name = node.id.sv;
      parentId = generateId(node.base);
      break;
    case SyntaxKind.ModelProperty:
      node = obj as ModelPropertyNode;
      name = node.id.sv;
      parentId = generateId(node.parent);
      break;
    case SyntaxKind.ModelSpreadProperty:
      node = obj as ModelSpreadPropertyNode;
      name = generateId(node.target)!;
      parentId = generateId(node.parent);
      break;
    case SyntaxKind.ModelStatement:
      node = obj as ModelStatementNode;
      name = node.id.sv;
      parentId = generateId(node.parent);
      break;
    case SyntaxKind.OperationStatement:
      node = obj as OperationStatementNode;
      name = node.id.sv;
      parentId = generateId(node.parent);
      break;
    case SyntaxKind.StringLiteral:
      node = obj as StringLiteralNode;
      name = node.value;
      parentId = undefined;
      break;
    case SyntaxKind.UnionStatement:
      node = obj as UnionStatementNode;
      name = node.id.sv;
      parentId = generateId(node.parent);
      break;
    case SyntaxKind.UnionVariant:
      node = obj as UnionVariantNode;
      if (node.id?.sv !== undefined) {
        name = node.id.sv;
      } else {
        // TODO: Should never have default value of _
        name = generateId(node.value) ?? "_";
      }
      parentId = generateId(node.parent);
      break;
    case SyntaxKind.TypeReference:
      node = obj as TypeReferenceNode;
      name = generateId(node.target)!;
      parentId = undefined;
      break;
    case SyntaxKind.DirectiveExpression:
      node = obj as DirectiveExpressionNode;
      name = `#${generateId(node.target)!}`;
      for (const arg of node.arguments) {
        name += `_${generateId(arg)}`;
      }
      parentId = generateId(node.parent);
      break;
    default:
      return undefined;
  }
  if (parentId !== undefined) {
    return `${parentId}.${name}`;
  } else {
    return name;
  }
}