github / stack-graphs

Rust implementation of stack graphs
https://docs.rs/stack-graphs/*/stack_graphs/
Apache License 2.0
717 stars 122 forks source link

Python TSG: Error when typed function parameters with splat operator #408

Open augmented-fog opened 4 months ago

augmented-fog commented 4 months ago

The following input causes the Python TSG to fail.

Input

def f(**kwargs: Any):
  pass

CST

(module [0, 0] - [3, 0]
  (function_definition [0, 0] - [1, 11]
    name: (identifier [0, 4] - [0, 5])
    parameters: (parameters [0, 5] - [0, 20]
      (typed_parameter [0, 6] - [0, 19]
        (dictionary_splat_pattern [0, 6] - [0, 14]
          (identifier [0, 8] - [0, 14]))
        type: (type [0, 16] - [0, 19]
          (identifier [0, 16] - [0, 19]))))
    body: (block [1, 7] - [1, 11]
      (pass_statement [1, 7] - [1, 11]))))

Error

ExecutionError(
  InContext(
    Statement(
    [StatementContext {
      statement: "edge @name.def -> @param.param_name at (853, 3)",
      statement_location: Location { row: 852, column: 2 },
      stanza_location: Location { row: 842, column: 0 },
      source_location: Location { row: 1630, column: 59 },
      node_kind: "typed_parameter" }
    ]),
    InContext(
      Other("Evaluating edge source"),
      UndefinedScopedVariable("[syntax node dictionary_splat_pattern].def"))))

Suggested mitigation

[
  (parameter/typed_parameter
--    . (_) @name) @param
++    . (identifier) @name) @param
  (parameter/list_splat_pattern
--    (_) @name) @param
++    (identifier) @name) @param
  (parameter/dictionary_splat_pattern
--    (_) @name) @param
++    (identifier) @name) @param
] {
  attr (@name.def) node_definition = @name
  attr (@param.param_name) push_node = @name
  edge @name.def -> @param.param_name
  edge @name.def -> @param.param_index
  edge @param.input -> @name.def
}
augmented-fog commented 4 months ago

This one is weird. This expression:

(parameter/dictionary_splat_pattern (_) @name) @param)

applied to the CST above, matches as follows:

But @name should be matching the identifier node instead. Making the syntax node type explicit corrects the problem.