fix(dataflow): port dart dataflow rules to the native rust engine - #2503
Merged
Conversation
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
Contributor
Greptile SummaryThis PR adds native-engine Dart dataflow extraction to restore parity with the TypeScript/WASM engine.
Confidence Score: 5/5The 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
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
Reviews (1): Last reviewed commit: "fix(dataflow): port dart dataflow rules ..." | Re-trigger Greptile |
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
get_dataflow_rules()incrates/codegraph-core/src/ast_analysis/dataflow.rshad no"dart"arm, socodegraph build --engine native --dataflowsilently 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:function_signature/method_signature, not a child. Handled via a newbody_sibling_typesfield wired intovisit(), reusing the existingfind_body_sibling_nodehelper (already had passing unit tests for this exact Dart shape).method_signaturehas noname/parametersfields of its own; its nestedfunction_signature/getter_signature/setter_signature/constructor_signaturechild carries them. Handled via a newname_extractorfield +extract_dart_function_name.{int times, bool loud}/[int x, int y]groups wrap multiple separate parameter slots in oneoptional_formal_parametersnode; each must get its ownparamIndex. Handled via a newgrouped_param_typesfield wired intoextract_params().int f() => x + 1;) have noreturn_statementat all. Handled via newimplicit_return_body_node/block_body_nodefields wired intovisit()'s dispatch.Grammar divergence from TS's WASM grammar (important for reviewers)
The Rust-native
tree_sitter_dartcrate (v0.2.0) has real structural differences from the WASMtree-sitter-dartnpm 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_signatureexpose realname/parametersfields directly viachild_by_field_name. WASM's grammar has no such fields for these node types (needing TS'sgetParamListNodeoverride). Rust needs no equivalent override — the genericparam_list_field: "parameters"lookup just works.call_expressionis a real, standard node withfunction/argumentsfields. WASM has nocall_expressionnode type at all — a call is a flat sibling chain ofselectornodes, needing TS'sresolveCallParts/callChainSiblingTypehooks. Rust needs none of that: plaincall_node/member_nodeconfig works unmodified with the existing generic call-handling code.arguments' own children are bare expressions ((x)→[ ( , identifier "x", ) ]). WASM wraps each argument in anargumentnode. Soargument_wrapper_typestaysNonefor Rust.initialized_variable_definitionexposesname/valuefields directly, withvalueresolving straight to thecall_expressionnode. WASM'svaluefield resolves to the bare callee identifier, needing TS'scallChainSiblingTypeforward-sibling walk. Rust needs no var-declarator override either.method_signature's sole named child can befunction_signature,getter_signature,setter_signature, orconstructor_signature— all four confirmed via dump, each carrying its ownnamefield (and, for all but getter,parameterstoo). Mirrors TS'sDART_NESTED_SIGNATURE_TYPES.Changes
DataflowRulesstruct 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.DART_DATAFLOWstatic config +extract_dart_function_namehelper +get_dataflow_rules("dart")arm.visit()now threads aconsumed: &mut HashSet<usize>(mirrors TS'sconsumedSiblingIds) to guard against double-walking a body-sibling node, and dispatchesimplicit_return_body_nodenodes tohandle_return_stmt.extract_params()now special-casesgrouped_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).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).describe('Dart', ...)block intests/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-
varassignment, mutations, andawaitare not configured for Dart (assignment_node: None,mutating_methods: &[],await_node: None) — TS'sdataflowDartdoesn'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 testscargo clippy --all-targets --release -- -D warnings— cleancargo fmt --check— cleannpx vitest run— 328 files / 5281 tests pass, includingtests/engines/dataflow-parity.test.ts(Go/Rust/Ruby/Dart) andtests/parsers/dataflow-dart.test.ts(unmodified, still green)npm run lint— cleangit diff origin/mainthat nothing undersrc/changed, and the 8 existing Rust language configs only gained no-op default field valuesCloses #2359