Skip to content

codegraph ast --kind string misclassifies PHP scalar type-hints as string literals #1821

Description

@carlos-alm

Summary

While fixing #1729 (TypeScript predefined_type keyword misclassified as kind: string), I found the identical bug class in PHP: tree-sitter-php's primitive_type production lexes its string scalar type-hint keyword as an anonymous (unnamed) grammar token whose type string collides with the named string literal node type — exactly mirroring TypeScript's predefined_type construct. PHP_AST_TYPES in src/ast-analysis/rules/php.ts maps the bare key string: 'string', so codegraph ast --kind string spuriously matches PHP scalar type declarations, not just genuine string literals.

Repro (verified via direct grammar dump)

function f(string $x): string {
  return $x;
}

Dumping the parsed AST (web-tree-sitter + tree-sitter-php.wasm) shows:

simple_parameter
  primitive_type              (named)
    string                    (UNNAMED — the `string` keyword token)
  variable_name  $x
...
primitive_type                (named, return type)
  string                      (UNNAMED)

versus a genuine string literal:

encapsed_string                (named)
  "
  string_content  foo
  "

Both the WASM path (src/ast-analysis/rules/php.ts::astTypes → shared resolveAstKind in src/ast-analysis/visitors/ast-store-visitor.ts) and the native path (crates/codegraph-core/src/extractors/helpers.rs::PHP_AST_CONFIG + generic classify_ast_node/walk_ast_nodes_with_config_depth) match by node.type/node.kind() string alone, without checking named-vs-anonymous — so string $name parameter and : ReturnType scalar type-hints are misclassified as kind: "string" string-literal rows, distinguishable from genuine literals by an unquoted text value equal to the bare word string (same signature as #1729).

Expected

codegraph ast --kind string should only match genuine PHP string literals (encapsed_string, and whichever named node covers single-quoted strings), never the string scalar type-hint keyword.

Scope note

#1729's fix (an isNamed/is_named() guard) is scoped to the JS/TS/TSX family only (astRequiresNamedNode() in src/ast-analysis/rules/index.ts on the WASM side; the JS-specific bespoke walker in crates/codegraph-core/src/extractors/javascript.rs on the native side) to keep that PR narrowly scoped and avoid touching the generic Rust helpers.rs walker shared by ~20 other languages without dedicated verification. This issue tracks applying the equivalent named-node guard to PHP specifically (and re-auditing whether any other language sharing the generic native walker has the same grammar ambiguity — none currently do based on a node-types.json sweep of all bundled grammars, but that sweep should be re-verified at fix time).

Context

Found via a systematic node-types.json sweep across all bundled tree-sitter grammars while root-causing #1729, then confirmed with a direct parser dump against tree-sitter-php.wasm.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions