fix(dataflow): Dart local variable declarations and calls never tracked - #2499
Merged
Conversation
dataflowDart left varDeclaratorNode unconfigured, and callNode pointed
at 'call_expression' -- a node type that doesn't exist at all in
tree-sitter-dart's grammar. Confirmed empirically that the grammar's
OWN documented postfix_expression wrapper (node-types.json) never
actually materializes in a parsed tree either: a call is a flat
sequence of siblings under whatever encloses it (a base identifier
followed by a chain of `selector` siblings, one of which wraps an
argument_part when it IS a call) -- not a single self-contained node
with fields, which the existing field-based callFunctionField/
callArgsField extraction fundamentally assumes.
Adds two new dataflow-visitor.ts mechanisms, both opt-in via new
config fields (null for every other language, zero behavior change
there):
- resolveCallParts: override for grammars with no field-based call
structure. Dart's resolveDartCallParts dispatches from the call
selector and resolves the callee by walking BACKWARD to the
preceding sibling (another selector's property, or a bare
identifier).
- callChainSiblingType: lets findCallSelector walk FORWARD from a
call-sourced value expression (e.g. a var declarator's resolved
`value` field, which lands on the callee's bare identifier, not
the call itself) to the trailing call-node sibling -- the
symmetric counterpart, needed so a call-sourced assignment
(`var x = helper(y);`) is recognized the same way it already is
for languages whose call node IS the value node directly.
Also sets varDeclaratorNode/varNameField/varValueField (the grammar
does have real name/value fields on initialized_variable_definition)
and argumentWrapperType: 'argument' (arguments' own children wrap each
argument, same wrapper name PHP's config already unwraps).
Rust's native engine has no Dart dataflow rules at all yet (tracked
separately as #2359), so this is legitimately TS/WASM-only.
Empirically verified against real parsed trees (bare calls, method
calls, non-call postfix expressions, call-sourced and plain variable
declarations) before writing the regression tests.
docs check acknowledged
Closes #2357
Contributor
Greptile SummaryThe PR enables Dart call and local-variable dataflow extraction in the TypeScript/WASM analysis path.
Confidence Score: 5/5The PR appears safe to merge, with no concrete blocking or independently actionable non-blocking issue established. The Dart-specific behavior is opt-in, existing languages retain the prior field-based resolution path, and the added tests exercise the primary call and assignment cases without revealing a reachable regression. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart LR
AST["Dart flat AST siblings"] --> Selector["Call selector"]
Selector --> Resolve["resolveDartCallParts"]
Resolve --> Callee["Callee name"]
Resolve --> Args["Arguments node"]
Args --> Flows["Argument flows"]
Value["Variable value node"] --> Find["findCallSelector"]
Find --> Selector
Callee --> Assignment["Call-sourced assignment"]
Reviews (1): Last reviewed commit: "fix(dataflow): dart local variable decla..." | Re-trigger Greptile |
Contributor
Codegraph Impact Analysis6 functions changed → 6 callers affected across 2 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
dataflowDartleftvarDeclaratorNodeentirely unconfigured, andcallNodepointed at'call_expression'— a node type that doesn't exist at all in tree-sitter-dart's grammar.postfix_expressionwrapper (per node-types.json) never actually materializes either: a call is a flat sequence of siblings under whatever encloses it —helper(x)parses as[identifier "helper", selector "(x)"]as direct siblings,obj.method(x)as[identifier "obj", selector ".method", selector "(x)"]— not a single self-contained node with fields, which the existing field-basedcallFunctionField/callArgsFieldextraction fundamentally assumes.DataflowRulesConfigfields (null for every other language, zero behavior change elsewhere):resolveCallParts— override for grammars with no field-based call structure. Dart'sresolveDartCallPartsdispatches from the callselectorand resolves the callee by walking backward to the preceding sibling (another selector's property, for method calls, or a bare identifier, for bare calls).callChainSiblingType— lets a newfindCallSelectorhelper walk forward from a call-sourced value expression (e.g. a var declarator's resolvedvaluefield, which lands on the callee's bare identifier, not the call itself) to the trailing call-node sibling — the symmetric counterpart, needed sovar x = helper(y);is recognized as call-sourced the same way it already is for languages whose call node IS the value node directly.varDeclaratorNode/varNameField/varValueField(the grammar does have realname/valuefields oninitialized_variable_definition) andargumentWrapperType: 'argument'(matching the same wrapper name PHP's config already unwraps).Test plan
x++), call-sourced and plain variable declarations, before writing any testtests/parsers/dataflow-dart.test.ts: bare call (as return expr and as statement), method call, non-call postfix rejection, call-sourced assignment, plain-assignment rejectionnpm run lintcleandiff-impact— contained (6 functions changed, 6 transitive callers)Closes #2357