Skip to content

fix(dataflow): port dart dataflow rules to the native rust engine - #2503

Merged
carlos-alm merged 1 commit into
mainfrom
fix/issue-2359-rust-dart-dataflow-rules
Aug 14, 2026
Merged

fix(dataflow): port dart dataflow rules to the native rust engine#2503
carlos-alm merged 1 commit into
mainfrom
fix/issue-2359-rust-dart-dataflow-rules

Conversation

@carlos-alm

Copy link
Copy Markdown
Contributor

Summary

get_dataflow_rules() in crates/codegraph-core/src/ast_analysis/dataflow.rs had no "dart" arm, so codegraph build --engine native --dataflow silently produced zero dataflow edges for Dart, while the TS/WASM engine (fixed across #2182, #2356, #2357, #2358) already produces correct ones. This violated the repo's dual-engine parity mandate.

This PR ports dataflowDart (src/ast-analysis/rules/b2.ts) to Rust, including everything those four issues fixed:

Grammar divergence from TS's WASM grammar (important for reviewers)

The Rust-native tree_sitter_dart crate (v0.2.0) has real structural differences from the WASM tree-sitter-dart npm package TS uses — confirmed empirically by writing disposable #[test] functions that dump real parsed trees, not by trusting either side's grammar docs (this feature was previously mis-designed once on the TS side by trusting docs instead of empirical dumps — issue #2357's history):

  • function_signature/method_signature expose real name/parameters fields directly via child_by_field_name. WASM's grammar has no such fields for these node types (needing TS's getParamListNode override). Rust needs no equivalent override — the generic param_list_field: "parameters" lookup just works.
  • call_expression is a real, standard node with function/arguments fields. WASM has no call_expression node type at all — a call is a flat sibling chain of selector nodes, needing TS's resolveCallParts/callChainSiblingType hooks. Rust needs none of that: plain call_node/member_node config works unmodified with the existing generic call-handling code.
  • arguments' own children are bare expressions ((x)[ ( , identifier "x", ) ]). WASM wraps each argument in an argument node. So argument_wrapper_type stays None for Rust.
  • initialized_variable_definition exposes name/value fields directly, with value resolving straight to the call_expression node. WASM's value field resolves to the bare callee identifier, needing TS's callChainSiblingType forward-sibling walk. Rust needs no var-declarator override either.
  • method_signature's sole named child can be function_signature, getter_signature, setter_signature, or constructor_signature — all four confirmed via dump, each carrying its own name field (and, for all but getter, parameters too). Mirrors TS's DART_NESTED_SIGNATURE_TYPES.

Changes

  • DataflowRules struct gains 5 new fields (body_sibling_types, name_extractor, grouped_param_types, implicit_return_body_node, block_body_node), all defaulted to no-op values on the 8 existing language configs (JS/TS, Python, Go, Rust, Java, C#, PHP, Ruby) — no behavior change for any of them.
  • New DART_DATAFLOW static config + extract_dart_function_name helper + get_dataflow_rules("dart") arm.
  • visit() now threads a consumed: &mut HashSet<usize> (mirrors TS's consumedSiblingIds) to guard against double-walking a body-sibling node, and dispatches implicit_return_body_node nodes to handle_return_stmt.
  • extract_params() now special-cases grouped_param_types, giving each name inside a group its own index while an empty-name slot inside the group does not consume one (ordinary non-grouped children still always consume an index, preserving unnamed-C-parameter behavior).
  • 10 new Rust unit tests in dataflow.rs (top-level + method params, no-double-count regression, named/optional param group indices, arrow implicit return, no-double-count-as-return regression, var-from-call assignment, bare-call and method-call argFlows, sibling-scope isolation).
  • New describe('Dart', ...) block in tests/engines/dataflow-parity.test.ts (8 tests) confirming byte-identical native vs. WASM output for parameters, returns, assignments, and argFlows.

Out of scope (matches TS's current scope exactly)

Plain non-var assignment, mutations, and await are not configured for Dart (assignment_node: None, mutating_methods: &[], await_node: None) — TS's dataflowDart doesn't support these either, so this is parity, not a new gap.

Test plan

  • cargo test — 1022 tests pass (crates/codegraph-core), including 10 new Dart unit tests
  • cargo clippy --all-targets --release -- -D warnings — clean
  • cargo fmt --check — clean
  • Native addon built + installed locally; npx vitest run — 328 files / 5281 tests pass, including tests/engines/dataflow-parity.test.ts (Go/Rust/Ruby/Dart) and tests/parsers/dataflow-dart.test.ts (unmodified, still green)
  • npm run lint — clean
  • Confirmed via git diff origin/main that nothing under src/ changed, and the 8 existing Rust language configs only gained no-op default field values

Closes #2359

get_dataflow_rules() in crates/codegraph-core had no "dart" arm, so
`codegraph build --engine native --dataflow` silently produced zero
dataflow edges for Dart while the TS/WASM engine (fixed across #2182,
#2356, #2357, #2358) already produced correct ones. Ports dataflowDart
(src/ast-analysis/rules/b2.ts) to Rust, including everything those four
issues fixed: body-sibling function bodies, nested method_signature name
resolution, grouped named/optional parameter indices, and arrow-body
implicit returns.

Adds body_sibling_types, name_extractor, grouped_param_types,
implicit_return_body_node, and block_body_node to DataflowRules with
no-op defaults for the 8 existing language configs (no behavior change
for them), plus a DART_DATAFLOW config and get_dataflow_rules("dart")
arm. Adds Rust unit tests in dataflow.rs and a Dart describe block to
tests/engines/dataflow-parity.test.ts confirming both engines now
produce identical output.

Confirmed empirically (temporary #[test] tree dumps against the real
tree_sitter_dart crate, removed before this commit) that Rust's native
grammar differs structurally from the WASM grammar TS uses: real
call_expression/function_signature "parameters" fields and a real
initialized_variable_definition "value" field exist in Rust where WASM
has none, so none of TS's resolveCallParts/callChainSiblingType/
getParamListNode workarounds are needed on the Rust side.

Closes #2359

docs check acknowledged
@greptile-apps

greptile-apps Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds native-engine Dart dataflow extraction to restore parity with the TypeScript/WASM engine.

  • Adds Dart-specific function scope, name, grouped-parameter, implicit-return, variable, and call rules.
  • Extends traversal to process sibling function bodies exactly once.
  • Adds Rust unit tests and cross-engine parity coverage for parameters, returns, assignments, and argument flows.

Confidence Score: 5/5

The PR appears safe to merge because no concrete changed-code defect remains after reviewing the new Dart extraction paths and parity coverage.

The implementation confines new behavior to Dart-specific configuration while existing languages receive no-op defaults, and the new tests exercise the principal scope, parameter, return, assignment, and call-flow paths.

Important Files Changed

Filename Overview
crates/codegraph-core/src/ast_analysis/dataflow.rs Adds Dart dataflow configuration and generalized sibling-body, name-extraction, grouped-parameter, and implicit-return support with focused unit coverage.
tests/engines/dataflow-parity.test.ts Adds native-versus-WASM Dart parity tests covering the principal newly supported dataflow outputs.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  Dart["Dart source"] --> NativeParse["Native tree-sitter Dart parser"]
  NativeParse --> Rules["DART_DATAFLOW rules"]
  Rules --> Scope["Function scope and parameters"]
  Rules --> Returns["Explicit and implicit returns"]
  Rules --> Calls["Assignments and argument flows"]
  Scope --> Result["Dataflow result"]
  Returns --> Result
  Calls --> Result
  Dart --> Wasm["TypeScript/WASM dataflow"]
  Wasm --> Parity["Cross-engine parity tests"]
  Result --> Parity
Loading

Reviews (1): Last reviewed commit: "fix(dataflow): port dart dataflow rules ..." | Re-trigger Greptile

@carlos-alm
carlos-alm merged commit 8c32643 into main Aug 14, 2026
34 checks passed
@carlos-alm
carlos-alm deleted the fix/issue-2359-rust-dart-dataflow-rules branch August 14, 2026 14:18
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 14, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

follow-up: Rust engine needs DartDataflowRules to match TS's now-fixed dataflowDart

1 participant