Skip to content

perf: hoist C# type-declaration Set to static readonly and use childForFieldName in Go receiver lookup#419

Open
github-actions[bot] wants to merge 2 commits into
mainfrom
repo-assist/perf-static-set-and-fieldfn-20260627-9934802bccab092c
Open

perf: hoist C# type-declaration Set to static readonly and use childForFieldName in Go receiver lookup#419
github-actions[bot] wants to merge 2 commits into
mainfrom
repo-assist/perf-static-set-and-fieldfn-20260627-9934802bccab092c

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

🤖 This PR was created by Repo Assist, an automated AI assistant.

Summary

Two targeted micro-optimisations across csharpAnalyzer.ts and goAnalyzer.ts
that eliminate per-call heap allocations and O(n) child scans.


1. C# — hoist typeDeclarations Set to static readonly

getEnclosingTypeName() is called once per C# method/accessor/operator found
during analysis. It previously started every call with:

const typeDeclarations = new Set([
  "class_declaration",
  "struct_declaration",
  "interface_declaration",
  "record_declaration",
  "enum_declaration",
]);

This allocates a new Set object (and re-inserts 5 strings into it) on every
single invocation. Moving it to a private static readonly class field
(TYPE_DECLARATION_TYPES) means the set is allocated once at class load time
and shared across all calls, all analyzer instances, and all files analysed
in a session.


2. Go — replace .children.find() with childForFieldName("type") in receiver lookup

findTypeInParameterList() extracted the receiver type from a method's
parameter list by scanning parameter_declaration.children with a hard-coded
list of accepted node kinds:

child.children.find(c =>
  c.type === "type_identifier" ||
  c.type === "pointer_type"   ||
  c.type === "qualified_type"
)

Replacing this with child.childForFieldName("type") gives an O(1) tree-sitter
field lookup instead of an O(n) linear scan, and correctly handles any type form
the grammar may produce (slice types, map types, channel types, etc.) without
needing an explicit allowlist.


Test Status

npm run compile   ✅  0 errors
npm run lint      ✅  0 warnings
npm run test:unit ✅  153 passing, 0 failing

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • releaseassets.githubusercontent.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "releaseassets.githubusercontent.com"

See Network Configuration for more information.

Generated by 🌈 Repo Assist, see workflow run. Learn more.

Add this agentic workflows to your repo

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repo-assist.md@5d1811880f4e924f367e64502f3c5870742892a3

…orFieldName in Go receiver lookup

- csharpAnalyzer: move the inline `new Set([...])` in `getEnclosingTypeName` to a
  `private static readonly` class field (TYPE_DECLARATION_TYPES).  The set was
  reallocated on every call to `getEnclosingTypeName`, which is invoked once per
  method/accessor/operator in every C# file analysed.  A static field is
  allocated once at class load time and reused across all calls.

- goAnalyzer: replace the linear `.children.find(c => c.type === ...)` scan in
  `findTypeInParameterList` with `child.childForFieldName("type")` — an O(1)
  tree-sitter field lookup.  This also removes the hard-coded list of receiver
  type node kinds (type_identifier, pointer_type, qualified_type), making the
  lookup correctly handle any type form the grammar may return (slice, map,
  channel, etc.).

Both changes are pure performance micro-optimisations with no semantic effect;
all 153 unit tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@askpt askpt changed the title [repo-assist] perf: hoist C# type-declaration Set to static readonly and use childForFieldName in Go receiver lookup perf: hoist C# type-declaration Set to static readonly and use childForFieldName in Go receiver lookup Jun 27, 2026
@codecov

codecov Bot commented Jun 27, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78.33%. Comparing base (3144f62) to head (3bc3501).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #419      +/-   ##
==========================================
- Coverage   78.34%   78.33%   -0.02%     
==========================================
  Files          13       13              
  Lines        4156     4154       -2     
  Branches      469      466       -3     
==========================================
- Hits         3256     3254       -2     
  Misses        897      897              
  Partials        3        3              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@askpt askpt marked this pull request as ready for review June 27, 2026 10:27
@askpt askpt self-requested a review as a code owner June 27, 2026 10:27
Copilot AI review requested due to automatic review settings June 27, 2026 10:27

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR applies two small performance-focused refinements to the language analyzers used by the VS Code extension’s cognitive complexity engine, aiming to reduce per-node allocations in the C# analyzer and avoid linear child scans in the Go analyzer.

Changes:

  • C#: Hoists the set of type-declaration node kinds into a private static readonly class field to avoid re-allocating it on each getEnclosingTypeName() call.
  • Go: Uses childForFieldName("type") when extracting receiver types, avoiding a manual .children.find(...) scan and broadening compatibility with more Go type forms.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/metricsAnalyzer/languages/csharpAnalyzer.ts Hoists type-declaration node kind set to a static field for reuse across calls/instances.
src/metricsAnalyzer/languages/goAnalyzer.ts Switches receiver type lookup to childForFieldName("type") instead of scanning children.

Comment on lines +281 to +283
// Use childForFieldName for O(1) field access rather than a linear
// scan over the parameter's children.
const typeNode = child.childForFieldName("type");
*/
export class CSharpMetricsAnalyzer {
/** Node types that represent type declarations (class, struct, interface, record, enum). */
private static readonly TYPE_DECLARATION_TYPES = new Set([
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants