Skip to content

follow-up: Go's grouped a, b int parameter declarations share one paramIndex in both engines #2501

Description

@carlos-alm

Problem

Discovered while fixing #2358 (Dart's optional_formal_parameters sharing one paramIndex across multiple named-parameter-group children).

Go's grammar allows a single parameter_declaration node to declare multiple comma-separated names against one shared type: func f(a, b int, c string). Per node_modules/tree-sitter-go/src/node-types.json, parameter_declaration has a name field with multiple: true (both a and b are name-field children) plus a single type field.

Both engines extract all names from one such node in a single pass, and the outer per-child loop increments index only once per node (the exact bug pattern #2358 fixes for Dart) — so a and b above both get paramIndex: 0, and c gets paramIndex: 1, when the correct indices are 0, 1, 2 respectively (each is a genuinely independent, individually-positioned parameter, not a destructured binding of one argument slot):

  • TS: extractParamName hook in src/ast-analysis/rules/go.ts (parameter_declaration branch) returns names.length > 0 ? names : null — multiple names from one child in the generic extractParams loop (src/ast-analysis/visitor-utils.ts).
  • Rust: extract_params_go in crates/codegraph-core/src/ast_analysis/dataflow.rs has the identical shape — collects every identifier child into one Vec<String> returned for one parameter_declaration node, consumed by extract_params's per-child increment.

Why this isn't fixed by #2358's mechanism directly

#2358 introduces groupedParamTypes (TS-only, since Dart dataflow doesn't exist in the Rust engine yet — tracked separately by #2359): when a child's type is in this set, the outer loop iterates that child's OWN named children as separate slots instead of calling extractParamNames on the whole node.

Go's shape doesn't fit that directly — a and b are not separate child NODES, they're two identifiers under the SAME parameter_declaration's name field (multiple: true), sitting alongside a type field that must NOT be treated as its own slot. Naively marking parameter_declaration as a groupedParamTypes entry and iterating all of its namedChildren would incorrectly also try to extract a slot from the type node.

Fixing this needs either:

  • A field-aware variant (e.g. read childrenForFieldName('name') specifically, one slot per name, skip type), or
  • Restructuring go.ts's hook so each identifier is walked as an independent grandchild before extractParamName currently intercepts the whole parameter_declaration node.

Needs the equivalent fix mirrored in extract_params_go (Rust) for dual-engine parity, since — unlike Dart — Go already ships in both engines today.

Filed per this repo's scope-discipline convention — out of scope for #2358's Dart-specific groupedParamTypes fix.

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