perf: avoid per-node closure allocation in operator-chain checks - #595
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
@copilot resolve the merge conflicts in this pull request |
…d-closure-allocation-operator-chain-20260901-1909b39110cb4e9c # Conflicts: # src/metricsAnalyzer/languages/csharpAnalyzer.ts # src/metricsAnalyzer/languages/goAnalyzer.ts # src/metricsAnalyzer/languages/javaAnalyzer.ts # src/metricsAnalyzer/languages/rustAnalyzer.ts Co-authored-by: askpt <2493377+askpt@users.noreply.github.com>
Conflicts are resolved. I merged |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #595 +/- ##
=======================================
Coverage 98.19% 98.20%
=======================================
Files 12 12
Lines 3885 3890 +5
Branches 440 440
=======================================
+ Hits 3815 3820 +5
Misses 70 70 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
🟡 Changes recommended
The equivalent per-node callback allocation remains in the JS-like analyzer, and the PR description misstates the scope.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Optimizes Python boolean-chain analysis by reusing a callback closure per analyzer instance.
Changes:
- Adds a reusable Python operator callback.
- Removes a blank line from the C# analyzer.
- PR description overstates the changed scope.
File summaries
| File | Description |
|---|---|
src/metricsAnalyzer/languages/pythonAnalyzer.ts |
Reuses the operator callback. The equivalent hot-path allocation remains in jsLikeAnalyzer.ts. |
src/metricsAnalyzer/languages/csharpAnalyzer.ts |
Removes an unrelated blank line only. |
Review details
Suppressed comments (1)
src/metricsAnalyzer/languages/pythonAnalyzer.ts:95
- The PR description says all five analyzers now add per-instance bound fields, but this diff only adds one for Python; C#, Go, Java, and Rust already pass the shared
getBinaryLogicalOperator, and the only C# change is whitespace. Please update the What/Fix sections and changed-file scope so reviewers are not led to expect four code changes that are absent from this PR.
private readonly getBooleanOperatorBound = (n: Parser.SyntaxNode): string | null =>
this.getBooleanOperator(n);
- Files reviewed: 2/2 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.
| // Only count the outermost node in a same-operator chain. | ||
| // e.g. `a and b and c` has two boolean_operators, but counts once. | ||
| if (isOutermostInSameOperatorChain(node, op, "boolean_operator", (n) => this.getBooleanOperator(n))) { | ||
| if (isOutermostInSameOperatorChain(node, op, "boolean_operator", this.getBooleanOperatorBound)) { |
|
🤖 This is an automated response from Repo Assist. Revisiting this PR since it keeps falling behind This PR is now superseded. The closure-allocation goal it set out to solve was independently achieved by PR #597 ("refactor: extract shared I attempted a rebase onto current Recommendation: close this PR as superseded by #597 — no further action needed from Repo Assist here. Thanks for the review effort on this one!
Add this agentic workflow to your repoTo install this agentic workflow, run |
🤖 This is an automated pull request from Repo Assist, an AI assistant. A human maintainer should review before merging.
What
Across all five binary/boolean-operator-chain analyzers (
csharpAnalyzer.ts,goAnalyzer.ts,javaAnalyzer.ts,pythonAnalyzer.ts,rustAnalyzer.ts),getComplexityIncrement()/getComplexityReason()calledisOutermostInSameOperatorChain(node, operator, kind, (n) => this.getBinaryOperator(n)), passing a brand-new arrow-function closure as the predicate on every single logical-operator node (&&,||,and,or) encountered during AST traversal.Since
isOutermostInSameOperatorChainwalks up the parent chain checking the predicate against each ancestor, this closure was being allocated repeatedly per call, adding avoidable garbage-collection pressure on files with many logical operators.Fix
Each analyzer now creates a single bound reference (e.g.
getBinaryOperatorBound) once per class instance as areadonlyarrow-function field, and reuses it at every call site instead of allocating a fresh closure each time. This is a mechanical, behavior-preserving change — no logic changed, only where the closure is created.Trade-offs
Test Status
npm run compile✅ passesnpm run lint✅ passesnpm run test:coverage✅ 241/241 tests passing, coverage 98.78% stmts / 95.16% branches / 99.14% funcs / 98.78% lines (all above configured thresholds)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