Add parser modules
Some checks failed
CI / test (push) Failing after 6s

This commit is contained in:
2026-01-30 00:57:43 +00:00
parent b088216147
commit 15bbff8f3a

View File

@@ -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<typeof createASTUtils>;
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<any>(
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<any>(
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<any>(
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(/</g) || []).length * 3;
return score;
}
isUnionType(typeAlias: TypeAlias): boolean {
return typeAlias.typeAnnotation.includes('|');
}
isIntersectionType(typeAlias: TypeAlias): boolean {
return typeAlias.typeAnnotation.includes('&');
}
isGenericType(typeAlias: TypeAlias): boolean {
return typeAlias.generics.length > 0;
}
getReferencedTypes(typeAlias: TypeAlias): string[] {
return typeAlias.dependencies;
}
}
export function createTypeAliasParser(options?: TypeAliasParserOptions): TypeAliasParser {
return new TypeAliasParser(options);
}