diff --git a/src/metricsAnalyzer/languages/csharpAnalyzer.ts b/src/metricsAnalyzer/languages/csharpAnalyzer.ts index f1673a6..837b342 100644 --- a/src/metricsAnalyzer/languages/csharpAnalyzer.ts +++ b/src/metricsAnalyzer/languages/csharpAnalyzer.ts @@ -183,26 +183,31 @@ export class CSharpMetricsAnalyzer { */ public analyzeFunctions(sourceText: string): CSharpFunctionMetrics[] { this.sourceText = sourceText; - const tree = this.parser.parse(sourceText); - const functions: CSharpFunctionMetrics[] = []; - - const visit = (node: Parser.SyntaxNode) => { - if (this.isFunctionDeclaration(node)) { - const result = this.analyzeFunction(node); - if (result) { - functions.push(result); + this.heuristicReasonCache = undefined; + try { + const tree = this.parser.parse(sourceText); + const functions: CSharpFunctionMetrics[] = []; + + const visit = (node: Parser.SyntaxNode) => { + if (this.isFunctionDeclaration(node)) { + const result = this.analyzeFunction(node); + if (result) { + functions.push(result); + } } - } - // Continue traversing child nodes - for (let i = 0; i < node.childCount; i++) { - const child = node.child(i)!; - visit(child); - } - }; + // Continue traversing child nodes + for (let i = 0; i < node.childCount; i++) { + const child = node.child(i)!; + visit(child); + } + }; - visit(tree.rootNode); - return functions; + visit(tree.rootNode); + return functions; + } finally { + this.heuristicReasonCache = undefined; + } } /** @@ -934,7 +939,11 @@ export class CSharpMetricsAnalyzer { * ``` */ public static analyzeFile(sourceText: string): CSharpFunctionMetrics[] { - const analyzer = new CSharpMetricsAnalyzer(); - return analyzer.analyzeFunctions(sourceText); + return _analyzerInstance.analyzeFunctions(sourceText); } } + +// Module-level singleton: avoids object allocation on every analyzeFile() call. +// CSharpMetricsAnalyzer resets its mutable state at the start of each top-level +// function analysis (save/restore pattern), so the singleton is safe to reuse. +const _analyzerInstance = new CSharpMetricsAnalyzer(); diff --git a/src/metricsAnalyzer/languages/goAnalyzer.ts b/src/metricsAnalyzer/languages/goAnalyzer.ts index 11c811f..c3fdd3b 100644 --- a/src/metricsAnalyzer/languages/goAnalyzer.ts +++ b/src/metricsAnalyzer/languages/goAnalyzer.ts @@ -608,7 +608,11 @@ export class GoMetricsAnalyzer { * ``` */ public static analyzeFile(sourceText: string): GoFunctionMetrics[] { - const analyzer = new GoMetricsAnalyzer(); - return analyzer.analyzeFunctions(sourceText); + return _analyzerInstance.analyzeFunctions(sourceText); } } + +// Module-level singleton: avoids object allocation on every analyzeFile() call. +// GoMetricsAnalyzer resets its mutable state at the start of each top-level +// function analysis (save/restore pattern), so the singleton is safe to reuse. +const _analyzerInstance = new GoMetricsAnalyzer(); diff --git a/src/metricsAnalyzer/languages/javaAnalyzer.ts b/src/metricsAnalyzer/languages/javaAnalyzer.ts index 32ca42b..3f5120e 100644 --- a/src/metricsAnalyzer/languages/javaAnalyzer.ts +++ b/src/metricsAnalyzer/languages/javaAnalyzer.ts @@ -420,7 +420,11 @@ export class JavaMetricsAnalyzer { * @returns An array of complexity analysis results for all methods found */ public static analyzeFile(sourceText: string): JavaFunctionMetrics[] { - const analyzer = new JavaMetricsAnalyzer(); - return analyzer.analyzeFunctions(sourceText); + return _analyzerInstance.analyzeFunctions(sourceText); } } + +// Module-level singleton: avoids object allocation on every analyzeFile() call. +// JavaMetricsAnalyzer resets its mutable state at the start of each top-level +// function analysis (save/restore pattern), so the singleton is safe to reuse. +const _analyzerInstance = new JavaMetricsAnalyzer(); diff --git a/src/metricsAnalyzer/languages/pythonAnalyzer.ts b/src/metricsAnalyzer/languages/pythonAnalyzer.ts index cd75b88..01e68b0 100644 --- a/src/metricsAnalyzer/languages/pythonAnalyzer.ts +++ b/src/metricsAnalyzer/languages/pythonAnalyzer.ts @@ -389,7 +389,11 @@ export class PythonMetricsAnalyzer { * @returns An array of complexity analysis results for all functions found */ public static analyzeFile(sourceText: string): PythonFunctionMetrics[] { - const analyzer = new PythonMetricsAnalyzer(); - return analyzer.analyzeFunctions(sourceText); + return _analyzerInstance.analyzeFunctions(sourceText); } } + +// Module-level singleton: avoids object allocation on every analyzeFile() call. +// PythonMetricsAnalyzer resets its mutable state at the start of each top-level +// function analysis (save/restore pattern), so the singleton is safe to reuse. +const _analyzerInstance = new PythonMetricsAnalyzer(); diff --git a/src/metricsAnalyzer/languages/rustAnalyzer.ts b/src/metricsAnalyzer/languages/rustAnalyzer.ts index edc7f79..35059d9 100644 --- a/src/metricsAnalyzer/languages/rustAnalyzer.ts +++ b/src/metricsAnalyzer/languages/rustAnalyzer.ts @@ -447,7 +447,11 @@ export class RustMetricsAnalyzer { * ``` */ public static analyzeFile(sourceText: string): RustFunctionMetrics[] { - const analyzer = new RustMetricsAnalyzer(); - return analyzer.analyzeFunctions(sourceText); + return _analyzerInstance.analyzeFunctions(sourceText); } } + +// Module-level singleton: avoids object allocation on every analyzeFile() call. +// RustMetricsAnalyzer resets its mutable state at the start of each top-level +// function analysis (save/restore pattern), so the singleton is safe to reuse. +const _analyzerInstance = new RustMetricsAnalyzer();