Skip to content

fix: JS/TS scope-resolution coverage gaps — F44, F83, F85, F86, F87 (#1929)#1968

Open
magyargergo wants to merge 6 commits into
mainfrom
fix/js-parsing-coverage-main
Open

fix: JS/TS scope-resolution coverage gaps — F44, F83, F85, F86, F87 (#1929)#1968
magyargergo wants to merge 6 commits into
mainfrom
fix/js-parsing-coverage-main

Conversation

@magyargergo
Copy link
Copy Markdown
Collaborator

Supersedes #1962 with main as the base branch.

#1962 could not be retargeted in place because it was closed after its previous base branch (fix/1951-extends-implements-edges) was deleted. The original fork head had also merged that deleted branch, so this PR cherry-picks only the substantive JS/TS coverage commit onto current main (bench baseline commit omitted — TypeScript is not in the scope-capture bench on main yet).

Closes #1929 (parent epic #1919).

Summary

Fixes 6 JS/TS scope-resolution (registry-primary path only) coverage gaps:

F44 [HIGH] — Class expression scope

Added (class) @scope.class to TypeScript query. tree-sitter-typescript uses (class) (NOT class_expression) for class expressions — same node name as tree-sitter-javascript. The JS query already had it.

F83 [MEDIUM] — Qualified new_expression name capture

new ns.Foo() now captures Foo as @reference.name on the property_identifier inside the member_expression constructor. Fixed in both TS and JS queries.

F85 [MEDIUM] — Enum member declarations

Two patterns added: bare members (Red, Blue without = value) are property_identifier nodes directly inside enum_body; valued members (Green = 1) are enum_assignment nodes. Both emit @declaration.property.

F86 [MEDIUM] — Class expression methods

Unblocked by F44. method_definition already matches everywhere; the missing @scope.class for class expressions was the only gap.

F87 [LOW] — Optional parameter type annotations

Added 4 missing optional_parameter type annotation patterns matching the same variants already present for required_parameter: predefined_type, union_type, array_type, readonly_type.

F42 [MEDIUM] — Already fixed

generator_function_declaration was already captured at lines 132-133.

Tests

9 new tests in js-parsing-coverage.test.ts — each FAILS on main and PASSES on this branch.
Existing TS scope (198) + JS scope (27) tests: all pass.

Made with Cursor

…1929)

F44: Add (class) @scope.class for class expressions in TS query.
F83: Fix qualified new_expression (new ns.Foo()) to capture @reference.name.
F85: Add enum member declaration patterns (bare + valued) as @declaration.property.
F86: Unblocked by F44 — class expression methods get correct Class scope.
F87: Add 4 missing optional_parameter type annotation patterns (predefined_type,
     union_type, array_type, readonly_type) matching required_parameter.

Grammar verification via node-types.json confirms all node types exist.
9 new tests proving each fix fails on main and passes on the branch.
@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 1, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
gitnexus Ready Ready Preview, Comment Jun 2, 2026 4:57am

Request Review

Copy link
Copy Markdown
Collaborator Author

@magyargergo magyargergo left a comment

Choose a reason for hiding this comment

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

Methods

6 review lanes: GitNexus swarm (risk, test/CI) + Compound Engineering (correctness, adversarial, testing) + Codex (live).

Engine breakdown: 1 independent engine (Codex) + 5 Claude persona lanes. Claude-only agreement is treated as consistent across personas, not independent confirmation.

Problem (#1929)

Close JS/TS registry-primary scope-query gaps: class-expression scope (F44), qualified new name capture (F83), enum members (F85/F86), optional-parameter type shapes (F87).

PR state

3 files (+183/−5): typescript/query.ts, javascript/query.ts, new js-parsing-coverage.test.ts. Supersedes closed #1962 with main base.

Merge status

Merge state classification: checks failing

  • FAIL: tests / benchmarks (GITNEXUS_BENCH) — root cause not confirmed in this review (local bench/scope-capture/measure.mjs --check and bench/python-scope/measure.mjs --check both PASS on PR HEAD; failure may be another step in that job).
  • PASS: typecheck, lint, format, tests / ubuntu / coverage (9/9 new tests included), platform smokes, tree-sitter ABI, CodeQL, gitleaks.
  • PENDING: scope-parity / scope-resolution parity.

Branch hygiene

Branch hygiene classification: clean feature/fix PR — substantive fix is one cherry-picked commit on main; merge-from-main commit is administrative.

What's solid

  • Correctness [code-read]: F44 (class) @scope.class, F85 enum patterns, F87 optional-parameter variants, and F83 qualified-new property capture align with tree-sitter-typescript grammar shapes. Enum bare members (enum_body direct children) vs assigned members (enum_assignment) do not double-match (correctness lane AST probes; Codex probes).
  • Red→green tests: Coordinator verified 8/9 new tests fail with BASE typescript/query.ts restored; F86 alone passes on main — refutes PR claim that all nine fixtures fail on main.
  • Bench fingerprints: Local scope-capture + python-scope --check pass with unchanged committed fingerprints for this diff (separate from unresolved CI BENCH job failure).

Headline findings (inline)

  1. P2 — F86 test is a false guard for the behavior it documents.
  2. P2 — F83 narrows qualified new to property_identifier tails; computed-property constructors lose constructor tags.
  3. P3javascript/query.ts F83 mirror has no emitJsScopeCaptures regression test.

Lower priority (body only)

  • PR body overstates "each fixture FAILS on main" (F86 passes).
  • Enum header comment (typescript/query.ts:36-37) documents only enum_assignment, not bare enum_body members.
  • Deep new a.b.Foo() still resolves by leaf simple name at resolution time (pre-existing model; F83 improves shallow qualify).
  • (class) @scope.class breadth mirrors existing JS query tradeoff (IIFE / inline heritage class literals get Class scopes).

Refuted suspicions

  • Enum double-capture on Green = 1 — refuted (direct-child vs enum_assignment split).
  • (class) matching every class_declaration — refuted (keyword leaf lacks body field).
  • Mandatory baselines.json re-baseline for scope-capture — refuted for this diff (local --check pass); does not explain CI BENCH failure.

Open questions

  • Why did GITNEXUS_BENCH fail in CI while local bench --check steps pass?
  • Will scope-parity stay green once it completes?

Current visible state is incomplete. I could verify format/lint/typecheck/ubuntu-coverage/CodeQL/gitleaks and local bench --check, but not BENCH root cause or final scope-parity outcome.

Verdict

production-ready with minor follow-ups

Query fixes are structurally sound and 8/9 regressions are genuine. Before merge: fix or drop the F86 false guard, add a JS F83 capture test, triage the CI BENCH failure, and wait for scope-parity green. Computed-property constructor narrowing is acceptable if documented or covered by an explicit negative test.

Automated multi-tool digest — verify before acting.

* On fix: (class) @scope.class (F44) gives the method a proper Class parent.
*/
describe('F86 — class expression method ownership', () => {
it('class expression method has @declaration.method and @declaration.name', () => {
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

P2 [code-read] F86 test is a false guard for the behavior it documents.

Risk: The suite can regress on class-expression scope ownership without failing CI — this block passes on main without (class) @scope.class.

Evidence: Test only asserts @declaration.method + @declaration.name (lines 56–58). Coordinator ran it with BASE typescript/query.ts: 1 passed / 8 skipped under -t F86.

Recommended fix: Assert scope ownership (e.g. co-require @scope.class === 1 in the same fixture, or an extractParsedFile check that the method's parent scope kind is Class).

Blocks merge: maybe

@@ -934,7 +970,8 @@ const TYPESCRIPT_SCOPE_QUERY = `
constructor: (identifier) @reference.name) @reference.call.constructor

(new_expression
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

P2 [code-read] Qualified new pattern now requires property: (property_identifier).

Risk: new obj[computedKey]() / subscript constructors no longer emit @reference.call.constructor (old pattern matched any member_expression constructor child).

Evidence: Diff at lines 972–974 vs pre-change (member_expression) @reference.call.constructor.qualified without a property_identifier constraint.

Recommended fix: Add a fallback arm for non-property_identifier member constructors, or an explicit negative test documenting intentional exclusion.

Blocks merge: no

@@ -446,7 +446,8 @@ const JAVASCRIPT_SCOPE_QUERY = `
constructor: (identifier) @reference.name) @reference.call.constructor

(new_expression
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

P3 [code-read] JS F83 mirror is untested.

Risk: Future TS-only edits could desync the mirrored 3-line JS query change.

Evidence: All 9 new tests import emitTsScopeCaptures only; javascript/query.ts lines 448–451 mirror the TS qualified-new fix.

Recommended fix: Add one emitJsScopeCaptures('function f(){ return new ns.User(); }', 'test.js') assertion that @reference.name === 'User'.

Blocks merge: no

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 1, 2026

CI Report

All checks passed

Pipeline Status

Stage Status Details
✅ Typecheck success tsc --noEmit
✅ Tests success unit tests, 3 platforms
✅ E2E success gitnexus-web changes only

Test Results

Tests Passed Failed Skipped Duration
10780 10770 0 10 650s

✅ All 10770 tests passed

10 test(s) skipped — expand for details
  • COBOL pipeline benchmark > scales with file count
  • C# pipeline benchmark > scales with file count — namespaces spread across the solution
  • C# pipeline benchmark > scales with file count — all types in one (global) namespace bucket
  • C# pipeline benchmark > scales with file count — all types in one (named) namespace bucket
  • Go pipeline benchmark > scales with file count (workers enabled)
  • Go pipeline benchmark — worker pool (issue Worker idle timeout kills long Go scope extraction and surfaces as Napi::Error during analyze #1848) > does not quarantine the large generated Go file on sub-batch idle timeout
  • PHP pipeline benchmark > scales with file count (workers enabled)
  • Ruby pipeline benchmark > scales with file count (workers enabled)
  • Rust pipeline benchmark > scales with file count (workers enabled)
  • buildTypeEnv > known limitations (documented skip tests) > Ruby block parameter: users.each { |user| } — closure param inference, different feature

Code Coverage

Tests

Metric Coverage Covered Base Delta Status
Statements 80.35% 37498/46667 79.84% 📈 +0.5 🟢 ████████████████░░░░
Branches 68.9% 23870/34642 68.5% 📈 +0.4 🟢 █████████████░░░░░░░
Functions 85.45% 3885/4546 84.94% 📈 +0.5 🟢 █████████████████░░░
Lines 83.92% 33741/40205 83.36% 📈 +0.6 🟢 ████████████████░░░░

📋 View full run · Generated by CI

@prajapatisparsh
Copy link
Copy Markdown
Contributor

can i fix the CI here ?

@magyargergo
Copy link
Copy Markdown
Collaborator Author

can i fix the CI here ?

You just need to update the golden of the baseline.

@prajapatisparsh
Copy link
Copy Markdown
Contributor

Updated TypeScript scope-capture fingerprint at prajapatisparsh:fix/js-parsing-coverage-main (c4b81e1). Please pull or cherry-pick.

Copy link
Copy Markdown
Collaborator Author

@magyargergo magyargergo left a comment

Choose a reason for hiding this comment

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

Methods

Delta review (prior tri-review 2026-06-01 @ 15bfb8c7). 6 lanes: GitNexus swarm (risk, test/CI) + Compound Engineering (correctness, adversarial, previous-comments) + Codex (live).

Engine breakdown: 1 independent engine (Codex) + 5 Claude persona lanes. Claude-only agreement = consistent across personas, not independent confirmation. This run swaps CE testing for ce-previous-comments-reviewer to audit prior inline threads.

Problem (#1929)

Close JS/TS registry-primary scope-query gaps: F44 class-expression scope, F83 qualified new name capture, F85/F86 enum members, F87 optional-parameter type shapes.

PR state (HEAD faf6180b)

4 files (+186/−7): typescript/query.ts, javascript/query.ts, new js-parsing-coverage.test.ts, baselines.json. Since prior review: +1 commit (faf6180b) rebasing TypeScript scope-capture fingerprint.

Merge status

Merge state classification: checks pendingscope-parity / scope-resolution parity still pending at review time; all other CI jobs green including tests / benchmarks (GITNEXUS_BENCH) and tests / ubuntu / coverage (9/9 new tests).

Branch hygiene

Branch hygiene classification: clean feature/fix PR — substantive fix + baseline chore; merge-from-main commits are administrative.

Prior inline comment resolution

Prior comment Status Evidence
F86 false guard (js-parsing-coverage.test.ts:49) NOT ADDRESSED Test still asserts only @declaration.method + @declaration.name. [reproduced] Restored main typescript/query.ts (no (class) @scope.class) → full file 8 fail / 1 pass; F86 alone passes.
F83 property_identifier narrowing (typescript/query.ts:972) NOT ADDRESSED Pattern still requires property: (property_identifier). [code-read] Pre-change matched any member_expression constructor; new obj[key]() is a subscript_expression, never matched either form — narrowing is intentional for shallow new ns.Foo(). No fallback arm or negative test added.
JS F83 untested (javascript/query.ts:448) NOT ADDRESSED JS query mirrors TS F83 change; all 9 tests still import emitTsScopeCaptures only. [code-read]
Baseline golden / CI BENCH (thread) ADDRESSED faf6180b updates TS fingerprint to 3f44a4a6…. [reproduced] Local measure.mjs --check PASS; CI GITNEXUS_BENCH PASS.

Summary: 1 of 4 prior action items resolved (baseline). Three inline threads remain open unchanged since 15bfb8c7.

What's solid

  • F44/F85/F87 query fixes structurally sound; enum bare vs assigned members do not double-capture [code-read] + prior AST probes.
  • 8/9 regressions are genuine red→green guards [reproduced].
  • F83 shallow qualified new ns.Foo() correctly emits @reference.name: Foo [reproduced].
  • CI blocker cleared: BENCH + ubuntu/coverage green on faf6180b.

Headline findings (still open from prior review)

1. P2 — F86 test is still a false guard

  • Risk: Class-expression scope ownership can regress without CI failure.
  • Evidence: js-parsing-coverage.test.ts:49–58 — comment claims Class parent; assertions only check method/name tags. Codex + risk + test-ci + correctness + adversarial + previous-comments lanes agree. [reproduced]
  • Recommended fix: Co-assert @scope.class === 1 in same fixture, or check scope-tree parent is Class via extractParsedFile.
  • Blocks merge: no (test hygiene; F44 tests cover the core capture)

2. P3 — JS F83 mirror still untested

  • Risk: TS-only future edits could desync javascript/query.ts:448–450.
  • Evidence: Zero emitJsScopeCaptures references in test file. Codex + test-ci + previous-comments agree. [code-read]
  • Recommended fix: One emitJsScopeCaptures('const x = new ns.Foo();', 'test.js') asserting @reference.name === 'Foo'.
  • Blocks merge: no

3. P2 — F83 narrowing tradeoff undocumented

  • Risk: Computed/subscript constructor forms emit no @reference.call.constructor tags (pre-existing gap for subscript; narrowing affects non-property_identifier member tails).
  • Evidence: typescript/query.ts:972–974 vs pre-change unconstrained member_expression. [code-read]
  • Recommended fix: Explicit negative test or comment documenting intentional exclusion.
  • Blocks merge: no

Lower priority (body only)

  • File header line 4: "Each fixture FAILS on main" — still false for F86 (8/9).
  • Enum module comment (query.ts:35–37) documents only enum_assignment, not bare enum_body members.
  • (class) @scope.class breadth mirrors existing JS query tradeoff (IIFE / inline heritage literals).

Refuted suspicions (unchanged)

  • Enum double-capture on Green = 1 — refuted.
  • (class) matching every class_declaration — refuted (distinct node types).
  • Mandatory baseline re-baseline — now addressed in faf6180b.

Open questions

  • Will scope-parity complete green? (only pending gate at review time)

Verdict

production-ready with minor follow-ups

Baseline/CI blocker from prior review is resolved. Query fixes are sound and 8/9 tests are real guards. Three prior inline comments remain open (F86 false guard, JS F83 test, F83 narrowing documentation). Recommend merge after scope-parity green; address F86/JS test as fast follow-ups.

Automated multi-tool delta digest — verify before acting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

JavaScript / TypeScript: parsing-layer coverage gaps (11 findings)

2 participants