From 15bbff8f3a7bb55ef02b8cedbd29146e518c9a80 Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Fri, 30 Jan 2026 00:57:43 +0000 Subject: [PATCH] Add parser modules --- src/parsers/typeAliasParser.ts | 144 +++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 src/parsers/typeAliasParser.ts diff --git a/src/parsers/typeAliasParser.ts b/src/parsers/typeAliasParser.ts new file mode 100644 index 0000000..76e07d7 --- /dev/null +++ b/src/parsers/typeAliasParser.ts @@ -0,0 +1,144 @@ +import { createASTUtils } from '../utils/astUtils'; +import { typeToString } from '../utils/typeUtils'; +import { TypeAlias, GenericParameter } from '../types'; + +export interface TypeAliasParserOptions { + expandUnions?: boolean; + expandIntersections?: boolean; + inlineObjects?: boolean; +} + +export class TypeAliasParser { + private astUtils: ReturnType; + private options: TypeAliasParserOptions; + + constructor(options: TypeAliasParserOptions = {}) { + this.astUtils = createASTUtils(); + this.options = { + expandUnions: options.expandUnions ?? false, + expandIntersections: options.expandIntersections ?? false, + inlineObjects: options.inlineObjects ?? true + }; + } + + parse(source: string, filePath: string): TypeAlias[] { + const ast = this.astUtils.parse(source, filePath); + const typeAliases = this.astUtils.getTypeAliases(ast); + + return typeAliases.map((typeAlias) => this.parseTypeAlias(typeAlias)); + } + + parseTypeAlias(node: any): TypeAlias { + const typeAnnotation = typeToString(node.typeAnnotation); + const generics = this.parseGenericParameters(node.typeParameters); + const dependencies = this.extractDependencies(node); + + return { + name: node.id.name, + filePath: '', + startLine: node.loc?.start?.line ?? 0, + endLine: node.loc?.end?.line ?? 0, + kind: 'type_alias', + dependencies, + typeAnnotation, + extends: [], + generics, + rawNode: node + }; + } + + private parseGenericParameters(params: any | null): GenericParameter[] { + if (!params || !params.params) { + return []; + } + return params.params.map((param: any) => ({ + name: param.name.name, + constraint: param.constraint ? typeToString(param.constraint) : undefined, + default: param.default ? typeToString(param.default) : undefined + })); + } + + private extractDependencies(node: any): string[] { + const dependencies: string[] = []; + + const typeRefs = this.astUtils.findNodes( + node, + (n): n is any => n.type === 'TSTypeReference' + ); + + for (const ref of typeRefs) { + if (ref.typeName.type === 'Identifier') { + const name = ref.typeName.name; + if (!dependencies.includes(name)) { + dependencies.push(name); + } + } + } + + const unions = this.astUtils.findNodes( + node, + (n): n is any => n.type === 'TSUnionType' + ); + + for (const union of unions) { + for (const type of union.types) { + if (type.type === 'TSTypeReference' && type.typeName.type === 'Identifier') { + const name = type.typeName.name; + if (!dependencies.includes(name)) { + dependencies.push(name); + } + } + } + } + + const intersections = this.astUtils.findNodes( + node, + (n): n is any => n.type === 'TSIntersectionType' + ); + + for (const intersection of intersections) { + for (const type of intersection.types) { + if (type.type === 'TSTypeReference' && type.typeName.type === 'Identifier') { + const name = type.typeName.name; + if (!dependencies.includes(name)) { + dependencies.push(name); + } + } + } + } + + return dependencies; + } + + getComplexityScore(typeAlias: TypeAlias): number { + let score = 1; + const typeStr = typeAlias.typeAnnotation; + + score += (typeStr.match(/\|/g) || []).length * 2; + score += (typeStr.match(/&/g) || []).length * 2; + score += (typeStr.match(/{/g) || []).length; + score += (typeStr.match(/ 0; + } + + getReferencedTypes(typeAlias: TypeAlias): string[] { + return typeAlias.dependencies; + } +} + +export function createTypeAliasParser(options?: TypeAliasParserOptions): TypeAliasParser { + return new TypeAliasParser(options); +}