UNPKG

code-auditor-mcp

Version:

Multi-language code quality auditor with MCP server - Analyze TypeScript, JavaScript, and Go code for SOLID principles, DRY violations, security patterns, and more

103 lines 3.88 kB
/** * Universal Analyzer Base Class * * Implements the architecture plan for multi-language analyzers. * Each analyzer extends this class and implements language-agnostic analysis logic. */ import { promises as fs } from 'fs'; import { LanguageRegistry } from './LanguageAdapter.js'; export class UniversalAnalyzer { registry = LanguageRegistry.getInstance(); async analyze(files, config, options = {}) { const violations = []; let filesProcessed = 0; let executionTime = 0; const startTime = Date.now(); console.error(`[DEBUG] ${this.name}: UniversalAnalyzer.analyze() called with files:`, files.map(f => f.substring(f.lastIndexOf('/') + 1))); for (const file of files) { try { console.error(`[DEBUG] ${this.name}: Processing file: ${file}`); const adapter = this.getAdapter(file); if (!adapter) { console.error(`[DEBUG] ${this.name}: No adapter found for file: ${file}`); continue; } console.error(`[DEBUG] ${this.name}: Using adapter: ${adapter.name} for file: ${file}`); const content = await fs.readFile(file, 'utf8'); const ast = await adapter.parse(file, content); console.error(`[DEBUG] ${this.name}: About to call analyzeAST for: ${file}`); const fileViolations = await this.analyzeAST(ast, adapter, config); console.error(`[DEBUG] ${this.name}: analyzeAST returned ${fileViolations.length} violations for: ${file}`); violations.push(...fileViolations); filesProcessed++; } catch (error) { console.error(`[DEBUG] ${this.name}: Error processing file ${file}:`, error); // Continue processing other files even if one fails } } executionTime = Date.now() - startTime; console.error(`[DEBUG] ${this.name}: Analysis complete. ${violations.length} total violations found.`); return { violations, filesProcessed, executionTime }; } /** * Get the appropriate language adapter for a file */ getAdapter(file) { const adapter = this.registry.getAdapterForFile(file); if (!adapter) { console.warn(`[UniversalAnalyzer] No adapter found for file: ${file}`); } return adapter; } /** * Helper method to create violations with consistent formatting */ createViolation(file, line, column, message, severity = 'warning', rule, fix) { return { file, line, column, severity, message, rule: rule || this.name, analyzer: this.name, ...(fix && { fix }) }; } /** * Helper method to check if a node matches a specific pattern */ nodeMatches(node, adapter, pattern) { if (pattern.type && adapter.getNodeType(node) !== pattern.type) { return false; } if (pattern.name) { const nodeName = adapter.getNodeName(node); if (!nodeName) return false; if (typeof pattern.name === 'string') { return nodeName === pattern.name; } else if (pattern.name instanceof RegExp) { return pattern.name.test(nodeName); } } return true; } /** * Helper method to get source location for violations */ getSourceLocation(adapter, node) { const location = adapter.getNodeLocation(node); return { line: location.start.line, column: location.start.column }; } } //# sourceMappingURL=UniversalAnalyzer.js.map