fix: extract Dart null-aware (?.) method calls, in both engines - #2570
Merged
Conversation
a?.b() was silently extracted as zero calls in both engines, since Dart's null-aware member access uses a distinct grammar node instead of the one ordinary `.` access uses: - WASM: conditional_assignable_selector instead of unconditional_assignable_selector. resolveDartSelectorCall's Layout A/B checks only looked for the unconditional wrapper. - Native: null_aware_member_expression instead of member_expression (confirmed via a parse dump of tree-sitter-dart 0.2). handle_dart_call_expression's match only had an arm for the unconditional shape. Both wrappers carry the identical identifier for call-resolution purposes, so this is a pure extend-the-match fix on both sides -- no new resolution logic needed. docs check acknowledged. Closes #2476 Impact: 2 functions changed, 4 affected
Contributor
Greptile SummaryThe PR extends Dart call extraction to recognize null-aware member calls in both native and WASM engines.
Confidence Score: 5/5The PR appears safe to merge, with no actionable defects identified in the changed null-aware call extraction paths. Both extraction engines extend their existing member-call handling to the corresponding null-aware grammar node while preserving the established receiver and call-emission behavior. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart LR
Source["Dart source: a?.b()"] --> Parse{"Selected engine"}
Parse -->|WASM| Selector["conditional_assignable_selector"]
Parse -->|Native| Member["null_aware_member_expression"]
Selector --> Resolve["Extract method b and receiver a"]
Member --> Resolve
Resolve --> Call["Emit call fact"]
Reviews (1): Last reviewed commit: "fix: extract Dart null-aware (?.) method..." | Re-trigger Greptile |
Contributor
Codegraph Impact Analysis2 functions changed → 4 callers affected across 1 files
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
a?.b()was silently extracted as zero calls in both engines, since Dart's null-aware member access uses a distinct grammar node instead of the one ordinary.access uses:src/extractors/dart.ts): null-aware access parses asconditional_assignable_selectorinstead ofunconditional_assignable_selector.resolveDartSelectorCall's Layout A/B checks only looked for the unconditional wrapper (confirmed via a parse dump ofa?.b();, which produces the same Layout B shape ordinary.calls use, just with the different wrapper node).crates/codegraph-core/src/extractors/dart.rs): null-aware access parses asnull_aware_member_expressioninstead ofmember_expression(confirmed via a parse dump of tree-sitter-dart 0.2).handle_dart_call_expression'smatch func.kind()had no arm for the null-aware shape.Both wrappers carry the identical
identifier/object+propertyfields for call-resolution purposes, so this is a pure extend-the-match fix on both sides — no new resolution logic needed. Also extended the (currently dead, but still mirrored for consistency per this file's own convention) legacyresolve_dart_selector_call/find_dart_assignable_selectorpath in Rust, matching the WASM-side fix.Pure extraction gap — no false edges, no benchmark regression (per the issue's own framing): before this fix, no call was ever recorded at all for this shape.
Test plan
dart.rs(null_aware_callsmodule) — basic call, receiver prefixing, chained null-aware callstests/parsers/dart.test.ts(#2476describe block) — same coverage, WASM engine[](no calls extracted) for the exact new tests addednpx tsc --noEmit -p .,npm run lint, fullnpm test(5475 passed)cargo fmt -- --check,cargo clippy --lib -- -D warnings,cargo test --lib(1116 passed)Closes #2476