fix(dataflow): Dart arrow-body functions never record an implicit return - #2498
Merged
Conversation
tree-sitter-dart represents an arrow-bodied function (int f() => x + 1;) as function_body containing the expression DIRECTLY — no return_statement node at all. dataflowDart's returnNode: 'return_statement' never matched, so arrow-bodied functions never recorded a returns entry, independent of #2182's sibling-body fix (this is a distinct semantic gap: an implicit return via => isn't modeled as a return at all). Adds a new implicitReturnBodyNode/blockBodyNode config pair to DataflowRulesConfig: when a configured node's only named child is not the block type, that child is recorded as an implicit return the same way handleReturn already does for a real return_statement (it only ever reads namedChildren[0], so it works unmodified regardless of the wrapper node's actual type). Enabled only for Dart (implicitReturnBodyNode: 'function_body') — no other language sets this, so this is purely additive. Rust's native engine has no Dart dataflow rules at all yet (tracked separately as #2359), so this is legitimately TS/WASM-only — no dual- engine parity gap for this specific fix. While verifying, found calls nested inside a return/other expression are never tracked at all for Dart (argFlows stays empty even for an ordinary block-bodied function) — a separate, pre-existing gap, unrelated to this fix. Filed as #2497. Closes #2356 Impact: 3 functions changed, 1 affected
Contributor
Greptile SummaryThe PR adds Dart expression-bodied function support to the TypeScript/WASM dataflow analyzer.
Confidence Score: 5/5The PR appears safe to merge with no concrete correctness or security issues identified. The Dart-only configuration recognizes expression-bodied functions without changing other language rules, while the visitor still traverses expression children and avoids treating block bodies as implicit returns. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Dart function_body] --> B{Exactly one named child?}
B -->|No| E[Continue normal child traversal]
B -->|Yes| C{Child type is block?}
C -->|Yes| E
C -->|No| D[Record child expression as implicit return]
D --> E
Reviews (1): Last reviewed commit: "fix(dataflow): dart arrow-body functions..." | Re-trigger Greptile |
Contributor
Codegraph Impact Analysis1 functions changed → 1 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
int f() => x + 1;) asfunction_bodycontaining the expression DIRECTLY — noreturn_statementnode at all.dataflowDart'sreturnNode: 'return_statement'never matched, so arrow-bodied functions never recorded areturnsentry — a distinct semantic gap from Dart: function_signature/method_signature never contains its own body — breaks per-function complexity/dataflow analysis #2182's sibling-body fix (an implicit return via=>isn't modeled as a return at all).implicitReturnBodyNode/blockBodyNodeconfig pair toDataflowRulesConfig: when a configured node's only named child is not the block type, that child is recorded as an implicit return the same wayhandleReturnalready does for a realreturn_statement(it only ever readsnamedChildren[0], so it works unmodified regardless of the wrapper node's actual type).implicitReturnBodyNode: 'function_body') — no other language sets this field, so this is purely additive with zero behavior change elsewhere.return/other expression are never tracked at all for Dart (argFlowsstays empty even for an ordinary block-bodied function) — a separate, pre-existing gap, unrelated to this fix. Filed as follow-up: Dart dataflow — calls nested inside a return/other expression are never tracked #2497.Test plan
tests/parsers/dataflow-dart.test.ts: implicit return from a top-level arrow-bodied function, from an arrow-bodied class method, and a check that a block-bodied function isn't double-countednpm run lintcleandiff-impact— contained (1 function changed, 1 transitive caller)Closes #2356