Skip to content

Dart: local-variable constructor-call typing not seeded (svc.method() unresolved) #2474

Description

@carlos-alm

Context

Follow-up to #2319, discovered while verifying that fix's resolution-benchmark improvement.

#2319 added typeMap population for Dart's explicitly-typed field declarations and this.field constructor-shorthand params, moving the resolution benchmark's receiver-typed category from 0/8 to 4/8 (50% recall; overall dart recall 61.9% → 81.0%). The remaining 4/8 false negatives are all local-variable method calls in tests/benchmarks/resolution/fixtures/dart/main.dart:

var repo = UserRepository();
var svc = UserService(repo);   // <-- svc's type is never seeded

svc.createUser('1', 'Alice', 'alice@example.com');  // unresolved
svc.getUser('1');                                    // unresolved
svc.removeUser('2');                                 // unresolved
svc.summary();                                        // unresolved

svc's type (UserService) is knowable with full certainty from its constructor-call initializer (UserService(repo)) — the same "assign a constructor call to a local variable" pattern every other language extractor in this codebase already treats as a distinct, high-confidence (1.0), always-implemented category (e.g. JS/TS's handleVarDeclaratorTypeMap for const p = new Ctor(), and its Rust mirror handle_var_declarator_type_map). Dart's src/extractors/dart.ts and crates/codegraph-core/src/extractors/dart.rs have no equivalent for local_variable_declaration (WASM grammar) / initialized_variable_definition (native grammar) nodes.

This was deliberately left out of #2319's scope — that issue's own scope explicitly excluded "type inference from initializers without an explicit type annotation (var x = Foo();)" as a blanket exclusion (not limited to fields), to keep the change narrowly scoped to fields/constructor-shorthand params.

Suggested fix direction

Add a Dart-specific local_variable_declaration / initialized_variable_definition handler (mirroring JS's handleVarDeclaratorTypeMap's constructor-call branch, confidence 1.0) in both src/extractors/dart.ts and crates/codegraph-core/src/extractors/dart.rs, seeding typeMap[varName] = ctorType when the initializer is a bare/keyword-less constructor call (var svc = UserService(repo);). Verify the exact grammar shapes for both engines before implementing — confirmed via tree-sitter-dart parsing during #2319's investigation:

  • WASM (npm tree-sitter-dart 1.x): local_variable_declaration -> initialized_variable_definition -> inferred_type(var) identifier("svc") = identifier("UserService") selector("(repo)").
  • Native (crates.io tree-sitter-dart 0.2): local_variable_declaration (initialized_variable_definition name: (identifier) value: (call_expression function: (identifier) arguments: (...))).

After this lands, Dart's resolution-benchmark receiver-typed category should move from 4/8 to 8/8 (100% recall), and overall Dart recall from 81.0% to 100%.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions