import type { Identifier, MethodDeclaration, MethodSignature, TypeChecker, } from 'typescript'; import ts from 'typescript'; import { MethodMeta, MethodTypeInfo } from '../../plugins/ComponentMeta.js'; import { isUndefined } from '../unit.js'; import { getDocumentation } from './meta-doc.js'; import { getDocTags, hasDocTag } from './meta-doc-tag.js'; import { getPropTypeInfo } from './meta-prop.js'; import { getTypeReferences, typeTextFromTSType, typeToString, } from './meta-type.js'; export function buildMethodMetaFromDeclarationOrSignature( checker: TypeChecker, declaration: MethodDeclaration | MethodSignature, ): MethodMeta { const method: Partial = {}; const identifier = declaration.name as Identifier; const symbol = checker.getSymbolAtLocation(identifier); const name = symbol!.escapedName as string; const signature = checker.getSignatureFromDeclaration(declaration)!; const returnType = checker.getReturnTypeOfSignature(signature); const returnTypeNode = checker.typeToTypeNode( returnType, declaration, ts.NodeBuilderFlags.NoTruncation | ts.NodeBuilderFlags.NoTypeReduction, )!; const returnText = typeToString(checker, returnType); const signatureText = checker.signatureToString( signature, declaration, ts.TypeFormatFlags.WriteArrowStyleSignature | ts.TypeFormatFlags.NoTruncation, ts.SignatureKind.Call, ); const isStatic = declaration.modifiers?.some(m => m.kind === ts.SyntaxKind.StaticKeyword) ?? false; const typeInfo: MethodTypeInfo = { signatureText, returnText, references: { ...getTypeReferences(declaration), ...getTypeReferences(returnTypeNode, declaration.getSourceFile()), }, }; const parameters = declaration.parameters.map(parameter => ({ node: parameter, name: (parameter.name as Identifier).escapedText as string, typeText: typeTextFromTSType(checker.getTypeAtLocation(parameter)), typeInfo: getPropTypeInfo( checker, parameter, checker.getTypeAtLocation(parameter), ), optional: !isUndefined(parameter.questionToken), defaultValue: parameter.initializer?.getText(), })); method.node = declaration; method.name = name; method.static = isStatic; method.typeInfo = typeInfo; method.parameters = parameters; method.signature = signature; method.returnType = returnType; method.docTags = getDocTags(declaration); method.internal = hasDocTag(method.docTags, 'internal'); method.deprecated = hasDocTag(method.docTags, 'deprecated'); method.documentation = getDocumentation(checker, identifier); return method as MethodMeta; }