import { TypeScriptParser } from '../parsers/typescript-parser.js';
import { PythonParser } from '../parsers/python-parser.js';
import { BaseParser } from '../parsers/base-parser.js';
import { FileUtils } from '../utils/file-utils.js';
import { AnalysisResult, SupportedLanguage } from '../types/index.js';
export class CodebaseAnalyzer {
private parsers: Map<SupportedLanguage, BaseParser>;
constructor() {
this.parsers = new Map<SupportedLanguage, BaseParser>([
['typescript', new TypeScriptParser()],
['javascript', new TypeScriptParser()],
['python', new PythonParser()]
]);
}
async analyzeFile(filePath: string): Promise<AnalysisResult | null> {
const language = await FileUtils.getLanguage(filePath);
if (!language) {
return null;
}
const parser = this.parsers.get(language);
if (!parser) {
throw new Error(`No parser available for language: ${language}`);
}
const sourceCode = await FileUtils.readFileContent(filePath);
const elements = parser.parse(sourceCode, filePath);
const documentedElements = elements.filter(e => e.hasDocumentation).length;
const totalElements = elements.length;
const coverage = totalElements > 0 ? (documentedElements / totalElements) * 100 : 0;
return {
language,
filePath,
elements,
totalElements,
documentedElements,
documentationCoverage: Math.round(coverage * 100) / 100
};
}
async analyzeDirectory(dirPath: string): Promise<AnalysisResult[]> {
const files = await FileUtils.findSourceFiles(dirPath);
const results: AnalysisResult[] = [];
for (const file of files) {
const result = await this.analyzeFile(file);
if (result) {
results.push(result);
}
}
return results;
}
async analyzePath(path: string): Promise<AnalysisResult[]> {
const isDir = await FileUtils.isDirectory(path);
if (isDir) {
return this.analyzeDirectory(path);
} else {
const result = await this.analyzeFile(path);
return result ? [result] : [];
}
}
}