perf: reuse singleton analyzer instances in C#/Go/Java/Python/Rust analyzeFile() - #580
Conversation
…alyzeFile() Applies the same module-level singleton pattern already used by the JS/TS/TSX analyzers (see #578) to the remaining five language analyzers. Each previously allocated a new analyzer instance on every analyzeFile() call; since analyzeFunctions() resets all mutable state (nesting, complexity, details) at the start of each top-level function analysis, reusing one instance per language is safe and avoids unnecessary allocations on every file analyzed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #580 +/- ##
==========================================
+ Coverage 98.02% 98.03% +0.01%
==========================================
Files 12 12
Lines 3901 3926 +25
Branches 450 450
==========================================
+ Hits 3824 3849 +25
Misses 77 77 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
🟡 Changes recommended
The C# singleton can retain a cached syntax node and its parse tree indefinitely.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Reuses module-level analyzer instances to reduce allocations during repeated file analysis.
Changes:
- Adds singleton reuse for C#, Go, Java, Python, and Rust analyzers.
- Documents the singleton rationale.
File summaries
| File | Description |
|---|---|
csharpAnalyzer.ts |
Reuses a C# analyzer singleton. |
goAnalyzer.ts |
Reuses a Go analyzer singleton. |
javaAnalyzer.ts |
Reuses a Java analyzer singleton. |
pythonAnalyzer.ts |
Reuses a Python analyzer singleton. |
rustAnalyzer.ts |
Reuses a Rust analyzer singleton. |
Review details
- Files reviewed: 5/5 changed files
- Comments generated: 1
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Co-authored-by: askpt <2493377+askpt@users.noreply.github.com>
There was a problem hiding this comment.
🔵 Needs a closer look
The singletons retain the last source text and detail array indefinitely, introducing avoidable memory retention.
Review details
Suppressed comments (5)
Previously missed (4) — in code that hasn't changed since the last review.
src/metricsAnalyzer/languages/goAnalyzer.ts:611
- Reusing this analyzer now keeps the entire last Go source string and the final function's detail array reachable for the lifetime of the loaded module (and an empty subsequent file does not reset
details). Previously the per-call analyzer released this state once its result was no longer referenced. Clear both reference fields in afinallyblock after the synchronous analysis.
return _analyzerInstance.analyzeFunctions(sourceText);
src/metricsAnalyzer/languages/javaAnalyzer.ts:423
- Reusing this analyzer now keeps the entire last Java source string and the final method's detail array reachable for the lifetime of the loaded module (and an empty subsequent file does not reset
details). Previously the per-call analyzer released this state once its result was no longer referenced. Clear both reference fields in afinallyblock after the synchronous analysis.
return _analyzerInstance.analyzeFunctions(sourceText);
src/metricsAnalyzer/languages/pythonAnalyzer.ts:392
- Reusing this analyzer now keeps the entire last Python source string and the final function's detail array reachable for the lifetime of the loaded module (and an empty subsequent file does not reset
details). Previously the per-call analyzer released this state once its result was no longer referenced. Clear both reference fields in afinallyblock after the synchronous analysis.
return _analyzerInstance.analyzeFunctions(sourceText);
src/metricsAnalyzer/languages/rustAnalyzer.ts:450
- Reusing this analyzer now keeps the entire last Rust source string and the final function's detail array reachable for the lifetime of the loaded module (and an empty subsequent file does not reset
details). Previously the per-call analyzer released this state once its result was no longer referenced. Clear both reference fields in afinallyblock after the synchronous analysis.
return _analyzerInstance.analyzeFunctions(sourceText);
src/metricsAnalyzer/languages/csharpAnalyzer.ts:942
- Reusing this analyzer now keeps the entire last C# source string and the final function's detail array reachable for the lifetime of the loaded module (and an empty subsequent file does not reset
details). Previously the per-call analyzer released this state once its result was no longer referenced. Clear both reference fields in afinallyblock after the synchronous analysis.
return _analyzerInstance.analyzeFunctions(sourceText);
- Files reviewed: 5/5 changed files
- Comments generated: 0 new
- Review effort level: Balanced
🤖 This PR was created by Repo Assist, an automated AI assistant.
What
Extends the module-level singleton pattern (already applied to the JS/TS/TSX analyzers in #578) to the five remaining language analyzers: C#, Go, Java, Python, and Rust.
Why
Each of these
analyzeFile()static methods allocated a brand-new analyzer instance on every call, even thoughanalyzeFunctions()already resets all mutable per-analysis state (nesting,complexity,details, etc.) at the start of each top-level function analysis. Reusing a single module-level instance avoids an unnecessary object allocation on every file the CodeLens provider analyzes, which happens frequently during editing.Trade-offs
Parserinstance was already a module-level singleton in every language analyzer; only the outer*MetricsAnalyzerwrapper object is now also reused.Test Status
npm run compile: cleannpm run lint: cleannpm run test:unit: 236 passing (unchanged)Warning
Firewall blocked 1 domain
The following domain was blocked by the firewall during workflow execution:
releaseassets.githubusercontent.comTo allow these domains, add them to the
network.allowedlist in your workflow frontmatter:See Network Configuration for more information.
Add this agentic workflow to your repo
To install this agentic workflow, run