Constant STACK_GRAPHS_TSG_SOURCE

Source
pub const STACK_GRAPHS_TSG_SOURCE: &str = ";; -*- coding: utf-8 -*-\n;; ------------------------------------------------------------------------------------------------\n;; Copyright \u{a9} 2023, stack-graphs authors.\n;; Licensed under either of Apache License, Version 2.0, or MIT license, at your option.\n;; Please see the LICENSE-APACHE or LICENSE-MIT files in this distribution for license details.\n;; ------------------------------------------------------------------------------------------------\n\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n;; Stack graphs definition for Python\n;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n;; Global Variables\n;; ^^^^^^^^^^^^^^^^\n\nglobal FILE_PATH\nglobal ROOT_PATH = \"\"\nglobal ROOT_NODE\nglobal JUMP_TO_SCOPE_NODE\n\n;; Attribute Shorthands\n;; ^^^^^^^^^^^^^^^^^^^^\n\nattribute node_definition = node        => type = \"pop_symbol\", node_symbol = node, is_definition\nattribute node_reference = node         => type = \"push_symbol\", node_symbol = node, is_reference\nattribute pop_node = node               => type = \"pop_symbol\", node_symbol = node\nattribute pop_scoped_node = node        => type = \"pop_scoped_symbol\", node_symbol = node\nattribute pop_scoped_symbol = symbol    => type = \"pop_scoped_symbol\", symbol = symbol\nattribute pop_symbol = symbol           => type = \"pop_symbol\", symbol = symbol\nattribute push_node = node              => type = \"push_symbol\", node_symbol = node\nattribute push_scoped_node = node       => type = \"push_scoped_symbol\", node_symbol = node\nattribute push_scoped_symbol = symbol   => type = \"push_scoped_symbol\", symbol = symbol\nattribute push_symbol = symbol          => type = \"push_symbol\", symbol = symbol\nattribute scoped_node_definition = node => type = \"pop_scoped_symbol\", node_symbol = node, is_definition\nattribute scoped_node_reference = node  => type = \"push_scoped_symbol\", node_symbol = node, is_reference\nattribute symbol_definition = symbol    => type = \"pop_symbol\", symbol = symbol, is_definition\nattribute symbol_reference = symbol     => type = \"push_symbol\", symbol = symbol, is_reference\n\nattribute node_symbol = node            => symbol = (source-text node), source_node = node\n\n;; Nodes\n;; ^^^^^\n\n(module) @node {\n  node @node.after_scope\n  node @node.before_scope\n}\n\n[\n  ; _statement\n  ; _simple_statement\n  (future_import_statement)\n  (import_statement)\n  (import_from_statement)\n  (print_statement)\n  (assert_statement)\n  (expression_statement)\n  (return_statement)\n  (delete_statement)\n  (raise_statement)\n  (pass_statement)\n  (break_statement)\n  (continue_statement)\n  (global_statement)\n  (nonlocal_statement)\n  (exec_statement)\n  (type_alias_statement)\n  ; _compound_statement\n  (if_statement)\n  (for_statement)\n  (while_statement)\n  (try_statement)\n  (with_statement)\n  (function_definition)\n  (class_definition)\n  (decorated_definition)\n  (match_statement)\n  ; block\n  (block)\n  ; statement clauses\n  (if_clause)\n  (elif_clause)\n  (else_clause)\n  (except_group_clause)\n  (except_clause)\n  (finally_clause)\n  (with_clause)\n  (case_clause)\n] @node {\n  node @node.after_scope\n  node @node.before_scope\n}\n\n[\n  (parameters)\n  (lambda_parameters)\n] @node {\n  node @node.after_scope\n  node @node.before_scope\n}\n\n[\n  (identifier)\n] @node {\n  node @node.def\n  node @node.def_dot\n  node @node.ref\n  node @node.ref_dot\n}\n\n[\n  (dotted_name)\n  (aliased_import)\n  (relative_import)\n  (wildcard_import)\n  (import_prefix)\n] @node {\n  node @node.after_scope\n  node @node.before_scope\n  node @node.def\n  node @node.ref\n}\n\n[\n  ; expressions\n  (comparison_operator)\n  (not_operator)\n  (boolean_operator)\n  (lambda)\n  ;(primary_expression) ; unfolded below\n  (conditional_expression)\n  (named_expression)\n  (as_pattern)\n  ; primary_expression\n  (await)\n  (binary_operator)\n  (identifier)\n  ;(keyword_identifier) ; invalid query pattern?\n  (string)\n  (concatenated_string)\n  (integer)\n  (float)\n  (true)\n  (false)\n  (none)\n  (unary_operator)\n  (attribute)\n  (subscript)\n  (call)\n  (list)\n  (list_comprehension)\n  (dictionary)\n  (dictionary_comprehension)\n  (set)\n  (set_comprehension)\n  (tuple)\n  (pair)\n  (parenthesized_expression)\n  (generator_expression)\n  (ellipsis)\n  (list_splat)\n\n  ; expression list\n  (expression_list)\n\n  ; pattern\n  (pattern/identifier)\n  ;(keyword_identifier) ; invalid query pattern?\n  ;(subscript)\n  ;(attribute)\n  (list_splat_pattern)\n  (tuple_pattern)\n  (list_pattern)\n  ; _simple_patterns\n  (class_pattern)\n  (splat_pattern)\n  (union_pattern)\n  ;(list_pattern) ; already in pattern\n  ;(tuple_pattern) ; already in pattern\n  (dict_pattern)\n  ;(string) ; already in primary_expression\n  ;(concatenated_string) ; already in primary_expression\n  ;(true) ; already in primary_expression\n  ;(false) ; already in primary_expression\n  ;(none) ; already in primary_expression\n  ;(integer) ; already in primary_expression\n  ;(float) ; already in primary_expression\n  (complex_pattern)\n  (dotted_name)\n  ; _as_attern\n  (as_pattern)\n  ; keyword pattern\n  (keyword_pattern)\n  ; case pattern\n  (case_pattern)\n  ; with item\n  (with_item)\n\n  ; pattern list\n  (pattern_list)\n\n  ; parameter\n  ;(identifier) ; already in expressions\n  (typed_parameter)\n  (default_parameter)\n  (typed_default_parameter)\n  ;(list_splat_pattern) ; already in patterns\n  ;(tuple_pattern) ; already in patterns\n  (keyword_separator)\n  (positional_separator)\n  (dictionary_splat_pattern)\n\n  ; parameters\n  (parameters)\n] @node {\n  node @node.input\n  node @node.new_bindings\n  node @node.output\n}\n\n(comment) @node {\n  node @node.after_scope\n  node @node.before_scope\n  node @node.def\n  node @node.def_dot\n  node @node.input\n  node @node.new_bindings\n  node @node.output\n  node @node.ref\n  node @node.ref_dot\n}\n\n;; Inherited Variables\n;; ^^^^^^^^^^^^^^^^^^^\n\ninherit .bottom\ninherit .class_member_attr_scope\ninherit .class_parent_scope\ninherit .class_self_scope\ninherit .class_super_scope\ninherit .function_returns\ninherit .global\ninherit .global_dot\ninherit .grandparent_module\ninherit .local_scope\ninherit .parent_module\n\n;;\n;; #     #\n;; ##   ##  ####  #####  #    # #      ######  ####\n;; # # # # #    # #    # #    # #      #      #\n;; #  #  # #    # #    # #    # #      #####   ####\n;; #     # #    # #    # #    # #      #           #\n;; #     # #    # #    # #    # #      #      #    #\n;; #     #  ####  #####   ####  ###### ######  ####\n;;\n;; Modules\n\n(module) @mod\n{\n  node mod_file_def\n  node mod_file_ref\n\n  var module_def = mod_file_def\n\n  node parent_module_def_node\n  var parent_module_def = parent_module_def_node\n\n  var module_ref = mod_file_ref\n\n  node parent_module_ref_node\n  var parent_module_ref = parent_module_ref_node\n\n  node grandparent_module_ref_node\n  var grandparent_module_ref = grandparent_module_ref_node\n\n  ; get the file path relative to the root path\n  let rel_path = (replace FILE_PATH ROOT_PATH \"\")\n  scan rel_path {\n    \"([^/]+)/\"\n    {\n      node def_dot\n      attr (def_dot) pop_symbol = \".\"\n      node next_def\n      ;\n      edge module_def -> def_dot\n      edge def_dot -> next_def\n      ;\n      attr (module_def) pop_symbol = $1\n      ;\n      set parent_module_def = module_def\n      set module_def = next_def\n\n      node ref_dot\n      attr (ref_dot) push_symbol = \".\"\n      node next_ref\n      ;\n      edge next_ref -> ref_dot\n      edge ref_dot -> module_ref\n      ;\n      attr (module_ref) push_symbol = $1\n      ;\n      set grandparent_module_ref = parent_module_ref\n      set parent_module_ref = module_ref\n      set module_ref = next_ref\n    }\n\n    \"__init__\\.py$\"\n    {\n      attr (parent_module_def) is_definition, source_node = @mod, empty_source_span\n    }\n\n    \"([^/]+)\\.py$\"\n    {\n      node def_dot\n      attr (def_dot) pop_symbol = \".\"\n      node next_def\n      ;\n      edge module_def -> def_dot\n      edge def_dot -> next_def\n      ;\n      attr (module_def) pop_symbol = $1, is_definition, source_node = @mod, empty_source_span\n      ;\n      set module_def = next_def\n    }\n  }\n\n  edge ROOT_NODE -> mod_file_def\n  edge mod_file_ref -> ROOT_NODE\n  edge module_def -> @mod.after_scope\n\n  node global\n  node global_dot\n\n  edge @mod.before_scope -> global_dot\n  edge global -> ROOT_NODE\n  attr (global) push_symbol = \"<builtins>\"\n\n  edge global_dot -> global\n  attr (global_dot) push_symbol = \".\"\n\n  let @mod.parent_module = parent_module_ref\n  let @mod.grandparent_module = grandparent_module_ref\n  let @mod.bottom = @mod.after_scope\n  let @mod.global = global\n  let @mod.global_dot = global_dot\n\n  ;; add a dummy nodes for inherited variables\n  node @mod.class_member_attr_scope\n  node @mod.class_parent_scope\n  node @mod.class_self_scope\n  node @mod.class_super_scope\n  node @mod.function_returns\n  node @mod.local_scope\n}\n\n;;\n;; ###\n;;  #  #    # #####   ####  #####  #####  ####\n;;  #  ##  ## #    # #    # #    #   #   #\n;;  #  # ## # #    # #    # #    #   #    ####\n;;  #  #    # #####  #    # #####    #        #\n;;  #  #    # #      #    # #   #    #   #    #\n;; ### #    # #       ####  #    #   #    ####\n;;\n;; Imports\n\n;; Import References\n;; ^^^^^^^^^^^^^^^^^\n\n;;;; Dotted Names\n;;\n;; (dotted_name).ref              node to connect to to use the reference\n;; (dotted_name).before_scope     node to connect from to ensure the reference resolves\n\n;; all names are references\n[\n  (import_statement        name:                       (dotted_name (identifier) @name))\n  (future_import_statement name:                       (dotted_name (identifier) @name))\n  (import_from_statement   name:                       (dotted_name (identifier) @name))\n  (import_statement        name: (aliased_import name: (dotted_name (identifier) @name)))\n  (future_import_statement name: (aliased_import name: (dotted_name (identifier) @name)))\n  (import_from_statement   name: (aliased_import name: (dotted_name (identifier) @name)))\n  (import_from_statement module_name:                  (dotted_name (identifier) @name))\n  (import_from_statement module_name: (relative_import (dotted_name (identifier) @name)))\n] {\n  attr (@name.ref) node_reference = @name\n}\n\n;; references are chained\n[\n  (import_statement        name:                       (dotted_name (identifier) @left . (identifier) @right))\n  (future_import_statement name:                       (dotted_name (identifier) @left . (identifier) @right))\n  (import_from_statement   name:                       (dotted_name (identifier) @left . (identifier) @right))\n  (import_statement        name: (aliased_import name: (dotted_name (identifier) @left . (identifier) @right)))\n  (future_import_statement name: (aliased_import name: (dotted_name (identifier) @left . (identifier) @right)))\n  (import_from_statement   name: (aliased_import name: (dotted_name (identifier) @left . (identifier) @right)))\n  (import_from_statement module_name:                  (dotted_name (identifier) @left . (identifier) @right))\n  (import_from_statement module_name: (relative_import (dotted_name (identifier) @left . (identifier) @right)))\n] {\n  node push_dot\n  attr (push_dot) push_symbol = \".\"\n\n  edge @right.ref -> push_dot\n  edge push_dot -> @left.ref\n}\n\n;; lookup first reference\n[\n  (import_statement        name:                       (dotted_name . (identifier) @first) @dotted)\n  (future_import_statement name:                       (dotted_name . (identifier) @first) @dotted)\n  (import_from_statement   name:                       (dotted_name . (identifier) @first) @dotted)\n  (import_statement        name: (aliased_import name: (dotted_name . (identifier) @first) @dotted))\n  (future_import_statement name: (aliased_import name: (dotted_name . (identifier) @first) @dotted))\n  (import_from_statement   name: (aliased_import name: (dotted_name . (identifier) @first) @dotted))\n  (import_from_statement module_name:                  (dotted_name . (identifier) @first) @dotted)\n  (import_from_statement module_name: (relative_import (dotted_name . (identifier) @first) @dotted))\n] {\n  edge @first.ref -> @dotted.before_scope\n}\n\n;; expose last reference\n[\n  (import_statement        name:                       (dotted_name (identifier) @last .) @dotted)\n  (future_import_statement name:                       (dotted_name (identifier) @last .) @dotted)\n  (import_from_statement   name:                       (dotted_name (identifier) @last .) @dotted)\n  (import_statement        name: (aliased_import name: (dotted_name (identifier) @last .) @dotted))\n  (future_import_statement name: (aliased_import name: (dotted_name (identifier) @last .) @dotted))\n  (import_from_statement   name: (aliased_import name: (dotted_name (identifier) @last .) @dotted))\n  (import_from_statement module_name:                  (dotted_name (identifier) @last .) @dotted)\n  (import_from_statement module_name: (relative_import (dotted_name (identifier) @last .) @dotted))\n] {\n  edge @dotted.ref -> @last.ref\n}\n\n;;;; Aliased Import\n;;\n;; An aliased import behaves like its wrapped dotted_name as a reference\n;;\n;; (aliased_import).ref              node to connect to, to use the reference\n;; (aliased_import).before_scope     node to connect from to ensure the reference resolves\n\n(aliased_import name: (dotted_name) @dotted) @aliased {\n  edge @aliased.ref -> @dotted.ref\n  edge @dotted.before_scope -> @aliased.before_scope\n}\n\n;;;; Relative Import\n;;\n;; A relative import behaves like its wrapped dotted_name as a reference\n;;\n;; (relative_import).ref              node to connect to, to use the reference\n;; (relative_import).before_scope     node to connect from to ensure the reference resolves\n\n(relative_import (import_prefix) . (dotted_name) @dotted) @relative {\n  edge @relative.ref -> @dotted.ref\n\n  node push_dot\n  attr (push_dot) push_symbol = \".\"\n\n  edge @dotted.before_scope -> push_dot\n  edge push_dot -> @relative.before_scope\n}\n\n(relative_import (import_prefix) .) @relative {\n  edge @relative.ref -> @relative.before_scope\n}\n\n;;;; Wildcard Import\n;;\n;; A wildcard import simply passes through\n;;\n;; (wildcard_import).ref              node to connect to, to use the reference\n;; (wildcard_import).before_scope     node to connect from to ensure the reference resolves\n\n(wildcard_import) @wildcard {\n  edge @wildcard.ref -> @wildcard.before_scope\n}\n\n;;;; Import from\n;;\n;; The imported references are resolved in the from module\n\n[\n  (import_from_statement module_name: (_) @left name: (_) @right)\n  (import_from_statement module_name: (_) @left (wildcard_import) @right)\n] {\n  node push_dot\n  attr (push_dot) push_symbol = \".\"\n\n  edge @right.before_scope -> push_dot\n  edge push_dot -> @left.ref\n}\n\n;;;; Non-relative Imports\n;;\n;; Non-relative imports are resolved in the root scope\n\n[\n  (import_statement      name:        (_) @name)\n  (import_from_statement module_name: (dotted_name) @name)\n] {\n  edge @name.before_scope -> ROOT_NODE\n}\n\n;;;; Relative Imports\n;;\n;; Relative imports are resolved in scopes related to the current module\n\n;; . imports resolve in parent module scope\n(import_from_statement module_name: (relative_import (import_prefix) @prefix (#eq? @prefix \".\")) @relative) {\n  edge @relative.before_scope -> @prefix.parent_module\n}\n\n;; .. imports resolve in grandparent module scope\n(import_from_statement module_name: (relative_import (import_prefix) @prefix (#eq? @prefix \"..\")) @relative) {\n  edge @relative.before_scope -> @prefix.grandparent_module\n}\n\n;;;; Future Imports\n;;\n;; We don\'t know the future, so we cannot connect references of future imports anywhere. Maybe one day?\n\n;; Import Definitions\n;; ^^^^^^^^^^^^^^^^^^\n\n;;;; Dotted Names & Aliased Imports\n;;\n;; (dotted_name).after_scope     node to connect to, to expose the definition\n;; (dotted_name).def             node to connect from, to give definition content\n\n;; unaliased names and aliases are definitions\n[\n  (import_statement        name:           (dotted_name (identifier) @name))\n  (future_import_statement name:           (dotted_name (identifier) @name))\n  (import_from_statement   name:           (dotted_name (identifier) @name))\n  (import_statement        name: (aliased_import alias: (identifier) @name))\n  (future_import_statement name: (aliased_import alias: (identifier) @name))\n  (import_from_statement   name: (aliased_import alias: (identifier) @name))\n] {\n  attr (@name.def) node_definition = @name\n}\n\n;; definitions are chained\n[\n  (import_statement        name: (dotted_name (identifier) @left . (identifier) @right))\n  (future_import_statement name: (dotted_name (identifier) @left . (identifier) @right))\n  (import_from_statement   name: (dotted_name (identifier) @left . (identifier) @right))\n] {\n  node pop_dot\n  attr (pop_dot) pop_symbol = \".\"\n\n  edge @left.def -> pop_dot\n  edge pop_dot -> @right.def\n}\n\n;; connect last definition\n[\n  (import_statement        name:           (dotted_name (identifier) @last .) @outer)\n  (future_import_statement name:           (dotted_name (identifier) @last .) @outer)\n  (import_from_statement   name:           (dotted_name (identifier) @last .) @outer)\n  (import_statement        name: (aliased_import alias: (identifier) @last  ) @outer)\n  (future_import_statement name: (aliased_import alias: (identifier) @last  ) @outer)\n  (import_from_statement   name: (aliased_import alias: (identifier) @last  ) @outer)\n] {\n  edge @last.def -> @outer.def\n}\n\n;; expose first definition\n[\n  (import_statement        name:           (dotted_name . (identifier) @first) @outer)\n  (future_import_statement name:           (dotted_name . (identifier) @first) @outer)\n  (import_from_statement   name:           (dotted_name . (identifier) @first) @outer)\n  (import_statement        name: (aliased_import alias:   (identifier) @first  ) @outer)\n  (future_import_statement name: (aliased_import alias:   (identifier) @first  ) @outer)\n  (import_from_statement   name: (aliased_import alias:   (identifier) @first  ) @outer)\n] {\n  edge @outer.after_scope -> @first.def\n}\n\n;;;; Wildcard Import\n;;\n;; Wildcard imports simply pass through\n\n(wildcard_import) @wildcard {\n  edge @wildcard.after_scope -> @wildcard.def\n}\n\n;;;; Import Definitions -> References\n;;\n;; The definitions introduced by imports are connected to the corresponding references\n\n[\n  (import_statement        name: (_) @name)\n  (future_import_statement name: (_) @name)\n  (import_from_statement   name: (_) @name)\n  (import_from_statement   (wildcard_import) @name)\n] {\n  edge @name.def -> @name.ref\n}\n\n;;;; Imports\n;;\n;; The definitions introduced by imports are visible after the import statement\n\n[\n  (import_statement        name: (_) @name)\n  (future_import_statement name: (_) @name)\n  (import_from_statement   name: (_) @name)\n  (import_from_statement   (wildcard_import) @name)\n] @stmt {\n  edge @stmt.after_scope -> @name.after_scope\n  attr (@stmt.after_scope -> @name.after_scope) precedence = 1\n}\n\n;;\n;; ######\n;; #     # #       ####   ####  #    #  ####\n;; #     # #      #    # #    # #   #  #\n;; ######  #      #    # #      ####    ####\n;; #     # #      #    # #      #  #        #\n;; #     # #      #    # #    # #   #  #    #\n;; ######  ######  ####   ####  #    #  ####\n;;\n;; Blocks\n\n[\n  (module (_) @last_stmt .)\n  (block (_) @last_stmt .)\n] @block\n{\n  edge @block.after_scope -> @last_stmt.after_scope\n}\n\n[\n  (module (_) @stmt1 . (_) @stmt2)\n  (block (_) @stmt1 . (_) @stmt2)\n]\n{\n  edge @stmt2.before_scope -> @stmt1.after_scope\n}\n\n[\n  (module (_) @stmt)\n  (block (_) @stmt)\n]\n{\n  edge @stmt.after_scope -> @stmt.before_scope\n  let @stmt.local_scope = @stmt.before_scope\n}\n\n[\n  (block . (_) @stmt)\n  (module . (_) @stmt)\n] @block\n{\n  edge @stmt.before_scope -> @block.before_scope\n}\n\n(function_definition (block) @block)\n{\n  edge @block.before_scope -> @block.local_scope\n}\n\n[\n  (while_statement (block) @block)\n  (if_statement (block) @block)\n  (with_statement (block) @block)\n  (try_statement (block) @block)\n  (for_statement (block) @block)\n  (_ [\n    (else_clause (block) @block)\n    (elif_clause (block) @block)\n    (except_clause (block) @block)\n    (finally_clause (block) @block)\n  ])\n] @stmt\n{\n  edge @block.before_scope -> @block.local_scope\n  edge @stmt.after_scope -> @block.after_scope\n}\n\n(match_statement body: (_) @block) @stmt\n{\n  let @block.local_scope = @block.before_scope\n  edge @block.before_scope -> @stmt.before_scope\n  edge @stmt.after_scope -> @block.after_scope\n}\n\n[\n  (for_statement)\n  (while_statement)\n] @stmt\n{\n  edge @stmt.before_scope -> @stmt.after_scope\n}\n\n;;\n;;  #####\n;; #     # #####   ##   ##### ###### #    # ###### #    # #####  ####\n;; #         #    #  #    #   #      ##  ## #      ##   #   #   #\n;;  #####    #   #    #   #   #####  # ## # #####  # #  #   #    ####\n;;       #   #   ######   #   #      #    # #      #  # #   #        #\n;; #     #   #   #    #   #   #      #    # #      #   ##   #   #    #\n;;  #####    #   #    #   #   ###### #    # ###### #    #   #    ####\n;;\n;; Statements\n\n;;;; Simple Statements\n\n(print_statement) {}\n\n(assert_statement) {}\n\n(expression_statement) {}\n\n(return_statement (_) @expr) @stmt\n{\n  edge @stmt.function_returns -> @expr.output\n}\n\n(delete_statement) {}\n\n(raise_statement) {}\n\n(pass_statement) {}\n\n(break_statement) {}\n\n(continue_statement) {}\n\n(global_statement) {}\n\n(nonlocal_statement) {}\n\n(exec_statement) {}\n\n(type_alias_statement) {}\n\n;;;; Compound Statements\n\n(if_statement) {}\n\n(if_clause) {}\n\n(elif_clause) {}\n\n(else_clause) {}\n\n(for_statement) {}\n\n(while_statement) {}\n\n(try_statement) {}\n\n(except_group_clause) {}\n\n(except_clause) {}\n\n(finally_clause) {}\n\n(with_statement) {}\n\n(with_clause) {}\n\n[\n  (function_definition\n    parameters: (_) @params\n    body: (_) @body\n  ) @func\n  (lambda\n    parameters: (_) @params\n    body: (_) @body\n  )@func\n] {\n  node @func.call\n  node return_value\n  node drop_scope\n\n  edge @func.call -> return_value\n  edge @body.before_scope -> @params.after_scope\n  edge @body.before_scope -> drop_scope\n  edge drop_scope -> @func.bottom\n  attr (drop_scope) type = \"drop_scopes\"\n  attr (@func.call) pop_scoped_symbol = \"()\"\n  edge @params.before_scope -> JUMP_TO_SCOPE_NODE\n  attr (return_value) is_exported\n  let @func.function_returns = return_value\n}\n\n(function_definition\n  name: (identifier) @name\n  body: (_) @body\n) @func {\n  attr (@name.def) node_definition = @name\n  attr (@name.def) definiens_node = @func\n  edge @func.after_scope -> @name.def\n  edge @name.def -> @func.call\n\n  ; Prevent functions defined inside of method bodies from being treated like methods\n  let @body.class_self_scope = #null\n  let @body.class_member_attr_scope = #null\n}\n\n; method definition\n(class_definition\n    body: (block\n            (function_definition\n                parameters: \n                    (parameters . (identifier) @first_param)\n                body: (block) @method_body\n            )\n         )\n) \n{\n  edge @first_param.def -> @first_param.class_self_scope\n  edge @first_param.class_member_attr_scope -> @first_param.output\n  edge @first_param.output -> @method_body.after_scope\n  attr (@first_param.output) push_node = @first_param\n}\n\n[\n  (parameters        (_) @param) @params\n  (lambda_parameters (_) @param) @params\n]\n{\n  node @param.param_index\n  node @param.param_name\n\n  attr (@param.param_index) push_symbol = (named-child-index @param)\n  edge @param.param_index -> @params.before_scope\n  edge @params.after_scope -> @param.input\n  edge @param.param_name -> @params.before_scope\n}\n\n\n(parameter/identifier) @param @name\n{\n  attr (@name.def) node_definition = @name\n  attr (@param.param_name) push_node = @param\n  edge @name.def -> @param.param_name\n  edge @name.def -> @param.param_index\n  edge @param.input -> @name.def\n}\n\n[\n  (parameter/default_parameter\n    name: (_) @name\n    value: (_) @value) @param\n  (parameter/typed_default_parameter\n    name: (_) @name\n    value: (_) @value) @param\n] {\n  attr (@name.def) node_definition = @name\n  attr (@param.param_name) push_node = @name\n  edge @name.def -> @param.param_name\n  edge @name.def -> @param.param_index\n  edge @param.input -> @name.def\n  edge @name.def -> @value.output\n}\n\n[\n  (parameter/typed_parameter\n    . (_) @name) @param\n  (parameter/list_splat_pattern\n    (_) @name) @param\n  (parameter/dictionary_splat_pattern\n    (_) @name) @param\n] {\n  attr (@name.def) node_definition = @name\n  attr (@param.param_name) push_node = @name\n  edge @name.def -> @param.param_name\n  edge @name.def -> @param.param_index\n  edge @param.input -> @name.def\n}\n\n(class_definition) @class {\n  node @class.call_drop\n  node @class.member_attrs\n  node @class.members\n  node @class.super_scope\n}\n\n(class_definition\n  name: (identifier) @name) {\n  attr (@name.def) node_definition = @name\n}\n\n(class_definition\n  name: (identifier) @name) @class\n{\n  node call\n  node self_dot\n  node self_scope\n  node members_dot\n\n  attr (@name.def) definiens_node = @class\n  attr (@name.def) syntax_type = \"class\"\n  edge @class.after_scope -> @name.def\n  edge @name.def -> call\n  edge @name.def -> members_dot\n  edge members_dot -> @class.members\n  edge call -> @class.call_drop\n  edge @class.call_drop -> self_scope\n  edge self_scope -> @class.super_scope\n  edge self_scope -> self_dot\n  edge self_dot -> @class.members\n  edge @class.members -> @class.member_attrs\n  attr (call) pop_scoped_symbol = \"()\"\n  attr (@class.call_drop) type = \"drop_scopes\"\n  attr (members_dot) pop_symbol = \".\"\n  attr (self_dot) pop_symbol = \".\"\n  attr (@class.member_attrs) push_symbol = \".\"\n  attr (self_scope) is_exported\n}\n\n(class_definition\n  body: (_) @body) @class\n{\n  let @body.class_member_attr_scope = @class.member_attrs\n  node @body.class_parent_scope\n  edge @body.class_parent_scope -> @class.class_parent_scope\n  edge @body.class_parent_scope -> @class.local_scope\n  let @body.class_self_scope = @class.call_drop\n  let @body.class_super_scope = @class.super_scope\n}\n\n(class_definition\n  body: (block\n    (_) @last_stmt .)) @class\n{\n  edge @class.members -> @last_stmt.after_scope\n}\n\n(class_definition\n  superclasses: (argument_list\n    (_) @superclass)) @class\n{\n  edge @class.super_scope -> @superclass.output\n}\n\n(decorated_definition\n  definition: (_) @def) @stmt\n{\n  edge @def.before_scope -> @stmt.before_scope\n  edge @stmt.after_scope -> @def.after_scope\n}\n\n(match_statement) {}\n\n(case_clause\n  (case_pattern) @pattern\n  consequence: (_) @consequence)\n{\n  edge @consequence.before_scope -> @pattern.new_bindings\n}\n\n(case_clause\n  consequence: (_) @consequence) @clause\n{\n  edge @consequence.before_scope -> @clause.before_scope\n  edge @clause.after_scope -> @consequence.after_scope\n}\n\n;;\n;; #######\n;; #       #    # #####  #####  ######  ####   ####  #  ####  #    #  ####\n;; #        #  #  #    # #    # #      #      #      # #    # ##   # #\n;; #####     ##   #    # #    # #####   ####   ####  # #    # # #  #  ####\n;; #         ##   #####  #####  #           #      # # #    # #  # #      #\n;; #        #  #  #      #   #  #      #    # #    # # #    # #   ## #    #\n;; ####### #    # #      #    # ######  ####   ####  #  ####  #    #  ####\n;;\n;; Expressions\n\n(lambda\n  body: (_) @body\n)@lam {\n  ;; TODO Unify .before_scope, .local_scope, and .input to simplify\n  ;;      uniform treatment of lambdas and function definitions.\n  node @body.before_scope\n  let @body.local_scope = @body.before_scope\n  edge @body.input -> @body.before_scope\n\n  edge @lam.output -> @lam.call\n}\n\n(conditional_expression) {}\n\n(named_expression) {}\n\n(as_pattern) {}\n\n(await) {}\n\n(binary_operator\n  (_) @left\n  (_) @right) @binop\n{\n  edge @binop.new_bindings -> @left.new_bindings\n  edge @binop.new_bindings -> @right.new_bindings\n}\n\n(primary_expression/identifier) @name {\n  attr (@name.ref) node_reference = @name\n}\n\n(primary_expression/identifier) @name\n{\n  edge @name.output -> @name.local_scope\n  edge @name.output -> @name.class_parent_scope\n  edge @name.local_scope -> @name.input\n  attr (@name.input) pop_node = @name\n  attr (@name.output) node_reference = @name\n\n  edge @name.new_bindings -> @name.def\n}\n\n(string) {}\n\n(concatenated_string) {}\n\n(integer) {}\n\n(float) {}\n\n(true) {}\n\n(false) {}\n\n(none) {}\n\n(unary_operator) {}\n\n(attribute\n  object: (_) @object\n  attribute: (identifier) @name) @expr\n{\n  node input_dot\n  node output_dot\n\n  edge @expr.output -> @name.output\n  edge @name.output -> output_dot\n  edge output_dot -> @object.output\n  edge @object.input -> input_dot\n  edge input_dot -> @name.input\n  edge @name.input -> @expr.input\n  attr (output_dot) push_symbol = \".\"\n  attr (input_dot) pop_symbol = \".\"\n  attr (@name.input) pop_node = @name\n  attr (@name.output) push_node = @name\n}\n\n(primary_expression/attribute\n  attribute: (identifier) @name)\n{\n  attr (@name.output) is_reference\n}\n\n(subscript) {}\n\n(call\n  function: (_) @fn\n  arguments: (argument_list) @args) @call\n{\n  node output_args\n\n  edge @call.output -> output_args\n  edge output_args -> @fn.output\n  attr (output_args) push_scoped_symbol = \"()\", scope = @args.args\n}\n\n(call\n  function: (attribute\n    object: (_) @receiver)\n  arguments: (argument_list\n    (expression) @arg) @args)\n{\n  node receiver_arg_index\n  attr (receiver_arg_index) pop_symbol = \"0\"\n  edge @args.args -> receiver_arg_index\n  edge receiver_arg_index -> @receiver.output\n\n  ;; FIXME the arguments will also exist with their unshifted indices because of the general\n  ;;       rule below!\n  node arg_index\n  attr (arg_index) pop_symbol = (plus 1 (named-child-index @arg))\n  edge arg_index -> @arg.output\n}\n\n(call\n  arguments: (argument_list\n    (keyword_argument\n      name: (identifier) @name\n      value: (_) @val)) @args)\n{\n  node arg_name\n  edge @args.args -> arg_name\n  attr (arg_name) pop_node = @name\n  edge arg_name -> @val.output\n}\n\n(argument_list) @args {\n  node @args.args\n  attr (@args.args) is_exported\n}\n\n(argument_list\n  (expression) @arg) @args\n{\n  node arg_index\n  edge @args.args -> arg_index\n  attr (arg_index) pop_symbol = (named-child-index @arg)\n  edge arg_index -> @arg.output\n}\n\n(\n  (call\n    function: (identifier) @_fn_name) @call\n  (#eq? @_fn_name \"super\")\n)\n{\n  edge @call.output -> @call.class_super_scope\n}\n\n(list) @list\n{\n  node called\n\n  edge @list.output -> called\n  edge called -> @list.global_dot\n  attr (called) push_symbol = \"list\"\n}\n\n(list (_) @el) @list\n{\n  edge @list.new_bindings -> @el.new_bindings\n}\n\n(list_comprehension) {}\n\n(dictionary (pair) @pair) @dict\n{\n  edge @dict.new_bindings -> @pair.new_bindings\n}\n\n(pair\n  value: (_) @value) @pair\n{\n  edge @pair.new_bindings -> @value.new_bindings\n}\n\n(dictionary_comprehension) {}\n\n(set (_) @el) @set\n{\n  edge @set.new_bindings -> @el.new_bindings\n}\n\n(set_comprehension) {}\n\n[\n  (tuple (_) @element)\n  (expression_list (_) @element)\n] @tuple\n{\n  node el_index\n\n  edge @tuple.output -> el_index\n  attr (el_index) pop_symbol = (named-child-index @element)\n  edge el_index -> @element.output\n\n  edge @tuple.new_bindings -> @element.new_bindings\n}\n\n(parenthesized_expression) {}\n\n(generator_expression) {}\n\n(ellipsis) {}\n\n(list_splat (_) @splatted) @splat\n{\n  edge @splat.new_bindings -> @splatted.new_bindings\n}\n\n;;\n;; ######\n;; #     #   ##   ##### ##### ###### #####  #    #  ####\n;; #     #  #  #    #     #   #      #    # ##   # #\n;; ######  #    #   #     #   #####  #    # # #  #  ####\n;; #       ######   #     #   #      #####  #  # #      #\n;; #       #    #   #     #   #      #   #  #   ## #    #\n;; #       #    #   #     #   ###### #    # #    #  ####\n;;\n;; Patterns\n\n\n[\n  (pattern/identifier) @name @pattern\n  ; identifiers in patterns\n  (as_pattern (identifier) @name .) @pattern\n  (keyword_pattern (identifier) @name) @pattern\n  (splat_pattern (identifier) @name) @pattern\n  ; every context where _simple_pattern is used, because matching\n  ; pattern/dotted_name does not work\n  (case_pattern (dotted_name . (_) @name .) @pattern)\n  (keyword_pattern (dotted_name . (_) @name .) @pattern)\n  (union_pattern (dotted_name . (_) @name .) @pattern)\n] {\n  attr (@name.def) node_definition = @name\n  edge @pattern.output -> @pattern.local_scope\n  edge @pattern.output -> @pattern.class_parent_scope\n  edge @pattern.local_scope -> @pattern.input\n  attr (@pattern.local_scope -> @pattern.input) precedence = 1\n  attr (@pattern.input) node_definition = @name\n  attr (@pattern.output) push_node = @name\n\n  edge @pattern.new_bindings -> @name.def\n}\n\n(pattern/subscript) {}\n\n(pattern/attribute\n  attribute: (identifier) @name)\n{\n  attr (@name.input) is_definition\n}\n\n\n(list_splat_pattern (_) @pattern) @list {\n  edge @list.new_bindings -> @pattern.new_bindings\n}\n\n[\n  (pattern_list (_) @pattern)\n  (tuple_pattern (_) @pattern)\n  (list_pattern (_) @pattern)\n] @list\n{\n  node pattern_index\n\n  let statement_scope = @list.local_scope\n  node @pattern.local_scope\n  edge statement_scope -> @pattern.local_scope\n  attr (statement_scope -> @pattern.local_scope) precedence = (plus 1 (named-child-index @pattern))\n\n  edge pattern_index -> @list.input\n  edge @pattern.input -> pattern_index\n  attr (pattern_index) push_symbol = (named-child-index @pattern)\n}\n\n(class_pattern (case_pattern) @pattern) @class {\n  edge @class.new_bindings -> @pattern.new_bindings\n}\n\n(splat_pattern (_) @pattern) @splat {\n  edge @splat.new_bindings -> @pattern.new_bindings\n}\n\n(union_pattern (_) @pattern) @union {\n  edge @union.new_bindings -> @pattern.new_bindings\n}\n\n(dict_pattern (_) @pattern) @dict {\n  edge @dict.new_bindings -> @pattern.new_bindings\n}\n\n(complex_pattern) {}\n\n(as_pattern\n  (expression) @value\n  alias: (as_pattern_target (identifier) @name)) @as_pattern\n{\n  attr (@name.local_scope -> @name.input) precedence = 1\n  attr (@name.input) is_definition\n\n  edge @as_pattern.new_bindings -> @value.new_bindings\n  edge @as_pattern.new_bindings -> @name.new_bindings\n}\n\n(keyword_pattern) {}\n\n(case_pattern (_) @pattern) @case\n{\n  edge @case.new_bindings -> @pattern.new_bindings\n}\n\n[\n  (assignment\n    left: (_) @pattern\n    right: (_) @value)\n  (with_item\n    value:\n      (as_pattern\n        (_) @value\n        alias: (as_pattern_target (_) @pattern)))\n]\n{\n  edge @pattern.input -> @value.output\n}\n\n;;\n;;  #####                                      #######\n;; #     # #   # #    # #####   ##   #    #       #    #   # #####  ######  ####\n;; #        # #  ##   #   #    #  #   #  #        #     # #  #    # #      #\n;;  #####    #   # #  #   #   #    #   ##         #      #   #    # #####   ####\n;;       #   #   #  # #   #   ######   ##         #      #   #####  #           #\n;; #     #   #   #   ##   #   #    #  #  #        #      #   #      #      #    #\n;;  #####    #   #    #   #   #    # #    #       #      #   #      ######  ####\n;;\n;; Syntax Types\n\n;;\n;; BEGIN BIG GNARLY DISJUNCTION\n;;\n;; The following pair of rules is intended to capture the following behavior:\n;;\n;; If a function definition is used to define a method, by being inside a class\n;; definition, then we make its syntax type `method`. Otherwise, we make it\'s\n;; syntax type `function`. Unfortunately, because of the limitations on negation\n;; and binding in tree sitter queries, we cannot negate `class_definition` or\n;; similar things directly. Instead, we have to manually push the negation down\n;; to form the finite disjunction it corresponds to.\n;;\n\n[\n  (class_definition (block (decorated_definition (function_definition name: (_)@name))))\n  (class_definition (block (function_definition name: (_)@name)))\n]\n{\n  attr (@name.def) syntax_type = \"method\"\n}\n\n[\n  (module (decorated_definition (function_definition name: (_)@name)))\n  (module (function_definition name: (_)@name))\n\n  (if_statement (block (decorated_definition (function_definition name: (_)@name))))\n  (if_statement (block (function_definition name: (_)@name)))\n\n  (elif_clause (block (decorated_definition (function_definition name: (_)@name))))\n  (elif_clause (block (function_definition name: (_)@name)))\n\n  (else_clause (block (decorated_definition (function_definition name: (_)@name))))\n  (else_clause (block (function_definition name: (_)@name)))\n\n  (case_clause (block (decorated_definition (function_definition name: (_)@name))))\n  (case_clause (block (function_definition name: (_)@name)))\n\n  (for_statement (block (decorated_definition (function_definition name: (_)@name))))\n  (for_statement (block (function_definition name: (_)@name)))\n\n  (while_statement (block (decorated_definition (function_definition name: (_)@name))))\n  (while_statement (block (function_definition name: (_)@name)))\n\n  (try_statement (block (decorated_definition (function_definition name: (_)@name))))\n  (try_statement (block (function_definition name: (_)@name)))\n\n  (except_clause (block (decorated_definition (function_definition name: (_)@name))))\n  (except_clause (block (function_definition name: (_)@name)))\n\n  (finally_clause (block (decorated_definition (function_definition name: (_)@name))))\n  (finally_clause (block (function_definition name: (_)@name)))\n\n  (with_statement (block (decorated_definition (function_definition name: (_)@name))))\n  (with_statement (block (function_definition name: (_)@name)))\n\n  (function_definition (block (decorated_definition (function_definition name: (_)@name))))\n  (function_definition (block (function_definition name: (_)@name)))\n]\n{\n  attr (@name.def) syntax_type = \"function\"\n}\n\n;;\n;; END BIG GNARLY DISJUNCTION\n;;\n";
Expand description

The stack graphs tsg source for this language.