Skip to content

bug(indexer): parameter extraction is broken in 5 languages (Ruby, PHP ×2, JavaScript, C++) — functions get no Parameter nodes #1527

Closed

Description

@Shashankss1205

Collected from a parser audit; these all break parameter extraction, so the affected functions get no Parameter nodes and no HAS_PARAMETER edges. Filing together because they share one root theme and one test surface. All reproduced.

(The Python case is separate and larger — see the annotated-parameter issue filed alongside this.)

1. Ruby — args is always [] for every method

tools/languages/ruby.py:183-191. _parse_method_parameters scans method_node.children for identifier, but parameters live inside a method_parameters child; the only direct identifier child is the method name, which the code explicitly skips.

def add(a, b)  ->  args: []

No Ruby function anywhere gets parameter edges.

2. PHP — emits parameters, but the indexer reads args

tools/languages/php.py:245. Extraction works; the key is wrong.

public function add(int $x, string $y)
  ->  {"parameters": ["$x", "$y"]}     # no "args" key

graph_builder.py:296 and writer.py:339 both read item.get("args", []), so params_batch stays empty. java.py:360, scala.py:197 and solidity.py:373 all emit both keys — PHP is the outlier.

3. PHP — promoted-constructor and variadic parameters dropped

tools/languages/php.py:225. The guard if "variable_name" in child.type or "simple_parameter" in child.type does not substring-match property_promotion_parameter or variadic_parameter.

__construct(private string $dsn)  ->  parameters: []
all(...$filters)                  ->  parameters: []

Promoted constructors are the standard PHP 8 idiom. Their types also never enter var_type_map, degrading $this->x receiver inference.

4. JavaScript — destructured and rest parameters dropped

tools/languages/javascript.py:351-368. _extract_parameters handles only identifier, assignment_pattern and rest_pattern, and the rest_pattern branch reads a field (argument) that node type does not have. object_pattern and array_pattern are unhandled.

function f(a, {b, c}, [d], ...rest)  ->  args: ["a"]      # 3 of 4 lost
const g = ({x}) => x                 ->  args: []

Destructured props are the dominant React idiom, so function Button({label}) yields no parameters at all.

5. C++ — lambda parameters always empty

tools/languages/cpp.py:452. Lines 448-450 correctly walk lambda_expression → lambda_declarator → parameters, then 452 unconditionally overwrites params_node with lambda_node.child_by_field_name('parameters'), which is None. Even restored, line 461 filters for p.type == 'identifier' over a parameter_list of parameter_declaration nodes.

auto f = [](int a, int b){...}  ->  args: []

Suggested fix

Each is independent and local. A shared regression test asserting "declared parameter count == extracted args count" across one fixture per language would catch all five and prevent recurrence — the current fixtures do not assert on parameter counts.


Environment
Commit c0e0bed (main)
Python 3.12.3, Linux

From a parser audit of tools/languages/. All five reproduced by running the parsers directly.

Activity

  1. added
    bugSomething isn't working
    severity: mediumIncorrect results, misleading output, or a broken contract
    area: indexerParsing, discovery, resolution, persistence
    on Aug 1, 2026
  2. github-actions commented on Aug 1, 2026

    @github-actions
    Contributor

    Hi! 👋 Join our CodeGraphContext Discord channel to collaborate: https://discord.gg/dR4QY32uYQ

  3. Shashankss1205 commented on Aug 5, 2026

    @Shashankss1205
    CollaboratorAuthor

    Ruby is fixed in #1581 (merged) — _parse_method_parameters now reads the method_parameters child and handles every form:

    def complex(a, b = 1, *rest, key:, **opts, &blk)
    # -> ['a', 'b', '*rest', 'key', '**opts', '&blk']

    PHP's parameters-vs-args key mismatch was fixed earlier in #1563 as part of the imports work.

    Still open in this issue:

    • PHP promoted-constructor / variadic parameters — php.py:225, the substring guard doesn't match property_promotion_parameter or variadic_parameter, so __construct(private string $dsn) yields [].
    • JavaScript destructured and rest parameters — javascript.py:351-368; function Button({label}) yields no parameters, which is the dominant React idiom.
    • C++ lambda parameters — cpp.py:452 overwrites the correctly-walked params_node with a None field lookup.

    Keeping this open for those three. The shared regression test suggested in the issue — asserting declared parameter count equals extracted args count, one fixture per language — is still the right way to close it and prevent recurrence.

  4. AloysJehwin commented on Aug 8, 2026

    @AloysJehwin
    Contributor

    Opened PR #1591 for the JavaScript case (#4). Covers object_pattern, array_pattern, and fixes rest_pattern which was looking for a named field that doesn't exist in this grammar — the identifier is a direct child.

  5. moved this from Backlog tasks to In progress in CGC Progress Boardon Aug 18, 2026
  6. moved this from In progress to Done in CGC Progress Boardon Aug 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: indexerParsing, discovery, resolution, persistencebugSomething isn't workingseverity: mediumIncorrect results, misleading output, or a broken contract

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions