Skip to content

refactor: replace O(n) children scans with O(1) firstNamedChild/childForFieldName lookups#427

Merged
askpt merged 2 commits into
mainfrom
repo-assist/improve-o1-child-scans-20260628-15f6c572679a91a2
Jul 2, 2026
Merged

refactor: replace O(n) children scans with O(1) firstNamedChild/childForFieldName lookups#427
askpt merged 2 commits into
mainfrom
repo-assist/improve-o1-child-scans-20260628-15f6c572679a91a2

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

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

Summary

Replaces the remaining linear .some()/.find() scans over node.children with O(1) tree-sitter field-access alternatives across three language analyzers. These hot paths run on every keystroke in the VS Code CodeLens provider, so reducing per-node allocation and iteration has a direct latency benefit.

Changes

goAnalyzer.ts

  • hasLabel(): node.children.some(c => c.type === "label_name")node.firstNamedChild?.type === "label_name"
    In Go's AST, label_name is the only named child of a labeled break/continue, so firstNamedChild gives an O(1) membership test.
  • pointer receiver type extraction: typeNode.children.find(c => c.type === "type_identifier")typeNode.firstNamedChild with a type check
    pointer_type has exactly one named child (the pointee type), so firstNamedChild avoids the linear scan.

rustAnalyzer.ts

  • hasLabel(): node.children.some(c => c.type === "label" || c.type === "loop_label")firstNamedChild?.type equality check
    Rust break_expression/continue_expression nodes have the loop label as their first (and only) named child.
  • getComplexityReason() else_clause case: .some(c => c.type === "if_expression")node.firstNamedChild?.type === "if_expression"
    The first named child of an else_clause is either an if_expression (else-if) or a block (plain else).

jsLikeAnalyzer.ts

  • getComplexityIncrement() break_statement/continue_statement: .some(c => c.type === "statement_identifier")node.firstNamedChild?.type === "statement_identifier"
    JS/TS labeled break/continue have statement_identifier as their only named child.
  • getComplexityReason() else_clause case: .some(c => c.type === "if_statement")node.firstNamedChild?.type === "if_statement"
    Same pattern as Rust above.
  • getFunctionName() pair key extraction: parent.children.find(c => c.type === "property_identifier" || c.type === "identifier")parent.childForFieldName("key") with type guard
    tree-sitter-javascript exposes the key field on pair nodes; childForFieldName is O(1) and more clearly expresses the intent.

Test Status

npm run compile  ✅  (0 errors)
npm run lint     ✅  (0 warnings)
npm run test:unit  ✅  159 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

…ForFieldName lookups

Replace linear .some()/.find() scans over node.children with O(1) alternatives
in Go, Rust, and JS/TS analyzers:

- goAnalyzer: hasLabel() uses firstNamedChild?.type instead of children.some()
- goAnalyzer: pointer_type inner type uses firstNamedChild instead of children.find()
- rustAnalyzer: hasLabel() uses firstNamedChild?.type instead of children.some()
- rustAnalyzer: getComplexityReason() else_clause uses firstNamedChild?.type
- jsLikeAnalyzer: labeled break/continue uses firstNamedChild?.type
- jsLikeAnalyzer: else_clause reason uses firstNamedChild?.type
- jsLikeAnalyzer: pair key lookup uses childForFieldName('key') for semantic clarity

All 159 unit tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@askpt askpt changed the title [repo-assist] refactor: replace O(n) children scans with O(1) firstNamedChild/childForFieldName lookups refactor: replace O(n) children scans with O(1) firstNamedChild/childForFieldName lookups Jul 2, 2026
@codecov

codecov Bot commented Jul 2, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.54839% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 78.59%. Comparing base (9fc6c11) to head (435bd1d).

Files with missing lines Patch % Lines
src/metricsAnalyzer/languages/jsLikeAnalyzer.ts 83.33% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #427      +/-   ##
==========================================
+ Coverage   78.57%   78.59%   +0.02%     
==========================================
  Files          13       13              
  Lines        4201     4205       +4     
  Branches      472      469       -3     
==========================================
+ Hits         3301     3305       +4     
- Misses        897      898       +1     
+ Partials        3        2       -1     

☔ 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 July 2, 2026 08:57
@askpt askpt self-requested a review as a code owner July 2, 2026 08:57
Copilot AI review requested due to automatic review settings July 2, 2026 08:57

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 optimizes several hot-path AST checks in the language analyzers by replacing linear scans over node.children with tree-sitter O(1) accessors (firstNamedChild, childForFieldName). This aligns with the extension’s real-time, per-keystroke analysis needs by reducing per-node iteration and allocation.

Changes:

  • Rust analyzer: use firstNamedChild for else_clause classification and labeled break/continue detection.
  • JS-like analyzer: use childForFieldName("key") to extract arrow-function property keys, and firstNamedChild for labeled break/continue and else_clause classification.
  • Go analyzer: use firstNamedChild for pointer receiver inner-type extraction and labeled break/continue detection.

Reviewed changes

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

File Description
src/metricsAnalyzer/languages/rustAnalyzer.ts Replaces children.some(...) scans with firstNamedChild checks for else_clause and loop labels.
src/metricsAnalyzer/languages/jsLikeAnalyzer.ts Switches object-pair key lookup to childForFieldName("key") and uses firstNamedChild for labeled control-flow checks and else_clause classification.
src/metricsAnalyzer/languages/goAnalyzer.ts Uses firstNamedChild for pointer receiver inner type and labeled control-flow detection to avoid linear child scans.

@askpt askpt merged commit 09c078a into main Jul 2, 2026
10 checks passed
@askpt askpt deleted the repo-assist/improve-o1-child-scans-20260628-15f6c572679a91a2 branch July 2, 2026 09:17
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