STACK_GRAPHS_TSG_TS_SOURCE

Constant STACK_GRAPHS_TSG_TS_SOURCE 

Source
pub const STACK_GRAPHS_TSG_TS_SOURCE: &str = "; -*- coding: utf-8 -*-\n; ------------------------------------------------------------------------------------------------\n; Copyright \u{a9} 2022, 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;\n; ######## ##    ## ########  ########  ######   ######  ########  #### ########  ########\n;    ##     ##  ##  ##     ## ##       ##    ## ##    ## ##     ##  ##  ##     ##    ##\n;    ##      ####   ##     ## ##       ##       ##       ##     ##  ##  ##     ##    ##\n;    ##       ##    ########  ######    ######  ##       ########   ##  ########     ##\n;    ##       ##    ##        ##             ## ##       ##   ##    ##  ##           ##\n;    ##       ##    ##        ##       ##    ## ##    ## ##    ##   ##  ##           ##\n;    ##       ##    ##        ########  ######   ######  ##     ## #### ##           ##\n;\n; ########################################################################################\n\n; Global Variables\n; ^^^^^^^^^^^^^^^^\n\nglobal FILE_PATH           ; project relative path of this file\nglobal PROJECT_NAME = \"\"   ; project name, used to isolate different projects in the same stack graph\n\nglobal JUMP_TO_SCOPE_NODE\nglobal ROOT_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; Node Name & Symbol Conventions\n; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n;\n; @node.{expr,type,mod}_def = STRING\n;     A definition node, pop node with a name value.\n;\n; @node.{expr,type,mod}_ref = STRING\n;     A reference node, a push node with a name value.\n;\n; @node.{expr,type,mod}_{def,ref}.ns = \"%T\" | \"%E\" | \"%M\"\n;     Internal symbol indicating the namespace of an identifier.\n;\n; @node.{expr,type,ns}_{def,ref}.typeof = \":\"\n;     Internal symbol indicating the type of an identifier.\n;\n; @node.callable = \"->\"\n;     Internal symbol indicating a callable.\n;\n; @node.member = \".\"\n;     Internal symbol indicating a named member (e.g., a field or method).\n;\n; @node.ctor = \"<new>\"\n;     Internal symbol indicating a constructor.\n;\n; @node.type_{abs,app} = \"<>\"\n;     Internal scoped symbol indicating type parameters & arguments.\n;\n; @node.indexable = \"[]\"\n;     Internal symbol indicating an indexable (i.e., array access).\n;\n; @node.{type,expr}_export = \"%T\" | \"%E\"\n;     Internal node for namespace guards for default and = exports.\n\n; comments can appear almost everywhere, so we simply make sure all\n; possible nodes are defined on comments\n(comment)@comment {\n  node @comment.alias_type\n  node @comment.aliased_type\n  node @comment.applied_type\n  node @comment.arg\n  node @comment.args\n  node @comment.async_type\n  node @comment.await_type\n  node @comment.callable\n  node @comment.coargs\n  node @comment.cocallable\n  node @comment.coparam\n  node @comment.coparams\n  node @comment.cotype\n  node @comment.default_export\n  node @comment.defs\n  node @comment.exports\n  node @comment.expr_def\n  node @comment.expr_def__ns\n  node @comment.expr_ref\n  node @comment.expr_ref__ns\n  node @comment.global_defs\n  node @comment.lexical_defs\n  node @comment.lexical_scope\n  node @comment.member\n  node @comment.mod_def\n  node @comment.mod_def__ns\n  node @comment.mod_ref\n  node @comment.param\n  node @comment.params\n  node @comment.return_type\n  node @comment.static_members\n  node @comment.static_type\n  node @comment.type\n  node @comment.type_def\n  node @comment.type_def__ns\n  node @comment.type_members\n  node @comment.type_ref\n  node @comment.type_ref__ns\n  node @comment.var_defs\n}\n\n; #     #\n; ##   ##  ####  #####  #    # #      ######  ####\n; # # # # #    # #    # #    # #      #      #\n; #  #  # #    # #    # #    # #      #####   ####\n; #     # #    # #    # #    # #      #           #\n; #     # #    # #    # #    # #      #      #    #\n; #     #  ####  #####   ####  ###### ######  ####\n;\n; #################################################\n\n; Projects are defined using a \"%Proj\" PROJECT_NAME definition in the root scope. Each module defines\n; its own project scope, which is joined with all other project scopes by both exposing a project\n; definition and importing a project reference. The module itself is defined with a \"%M\" NAME* definition,\n; based in its FILE_PATH.\n;\n; For example, a module `src/core/MyModule.ts` in a project `MyProject` is defined as follows:\n;\n;     ROOT_NODE -> \u{2191}\"%Proj\" -> \u{2191}\"MyProject\" -> proj_scope\n;     proj_scope -> \u{2191}\"%M\" -> \u{2191}\"src\" -> \u{2191}\"core\" -> \u{2191}\"MyModule\" -> @prog.defs\n;\n; For any module in the project `MyProject` ensures the composition with other modules in the same project:\n;\n;     proj_scope -> \u{2193}\"MyProject\" -> -> \u{2193}\"%Proj\" -> ROOT_NODE\n;     @prog.lexical_scope -> proj_scope\n;\n; Module imports are either relative or non-relative. Relative imports are relative either to the current file,\n; or to the `rootDirs` in `tsconfig.json`. Relative imports use a NAME* \"%RelM\" reference (which may include `..`\n; components!). Each module defines a \"%RelM\" definition, which is linked to a NAME* references based on its own\n; path, as well as \"..\" definitions that can skip components. (References are normalized to ensure `..` components\n; only appear at the beginning of the path.)\n;\n; For example, an import of `../OtherModule`:\n;\n;     importing_scope -> \u{2193}\"OtherModule\" -> \u{2193}\"%RelM\" -> @node.lexical_scope\n;\n; And, the module `src/core/MyModule.ts` would have the following definition to convert it to a proper module reference:\n;\n;     @prog.lexical_scope -> \u{2191}\"%RelM\" -> \u{2193}\"core\" -> \u{2193}\"src\" -> \u{2193}\"%M\" -> proj_scope\n;                               \\            \\        /          /\n;                                 --- \u{2191}\"..\" --\\----->           /\n;                                               --- \u{2191}\"..\" ---->\n;\n; The root dirs defined in `tsconfig.json` introduce definitions to convert relative imports to proper module paths.\n;\n; For example, `rootDirs: [\"./src/util\"]` would give:\n;\n;     proj_scope -> \u{2191}\"%RelM\" -> \u{2193}\"util\" -> \u{2193}\"src\" -> \u{2193}\"%M\" -> proj_scope\n;\n; Non-relative imports appear as \"%NonRelM\" NAME* definitions in either a project scope, or the global scope.\n;\n; Non-relative definitions in a project scope are the result of path mappings in `tsconfig.json`.\n;\n; For example, given `paths: { \"util\": [\"./my_util\"] }` with base URL `./src`, we get:\n;\n;     proj_scope -> \u{2191}\"%NonRelM\" -> \u{2191}\"%util\" -> \u{2193}\"my_util\" -> \u{2193}\"src\" -> \u{2193}\"%M\"\n;\n; The global definition rewrites the package name to a projects root dir, via a \"%PkgM\" node.\n; The \"%PkgM\" node maps to source files in the root directory. A \"%NonRelM\" NAME* definition in\n; the global scope maps non-relative module paths starting with the package name to the \"%PkgM\" node.\n;\n; For example, a package `@my/pkg` defined in project `MyProject` with source directory `src` would appear as:\n;\n;     ROOT_NODE -> \u{2191}\"%NonRelM\" -> \u{2191}\"@my\" -> \u{2191}\"pkg\" -> \u{2193}\"%PkgM\" -> proj_scope\n;     proj_scope -> \u{2191}\"%PkgM\" -> \u{2193}\"src\" -> \u{2193}\"%M\"\n;\n; The various references and definitions for `tsconfig.json` are not created by this TSG file, but\n; by the `TsConfigAnalyzer` defined in `rust/tsconfig.rs`. The global package definition is created\n; by the `NpmPackageAnalyzer` in `rust/npm_package.rs`.\n\n\n\n; ######\n; #     # #####   ####   ####  #####    ##   #    #  ####\n; #     # #    # #    # #    # #    #  #  #  ##  ## #\n; ######  #    # #    # #      #    # #    # # ## #  ####\n; #       #####  #    # #  ### #####  ###### #    #      #\n; #       #   #  #    # #    # #   #  #    # #    # #    #\n; #       #    #  ####   ####  #    # #    # #    #  ####\n;\n; ########################################################\n\n;; Attributes defined on programs\n;\n; out .lexical_scope\n;     Lexical scope.\n;\n; in .defs\n;     Lexical and variable definitions.\n;\n; in .exports\n;     Exported definitions.\n;\n; out .mod_def\n;     Module definition\n\n;; Nodes\n(program)@prog {\n  node @prog.defs\n  node @prog.exports\n  node @prog.globals\n  node @prog.lexical_scope\n}\n\n(program)@prog {\n  ; expose definitions\n  edge @prog.lexical_scope -> @prog.defs\n\n  ; import builtins\n  node builtins_ref__ns\n  attr (builtins_ref__ns) push_symbol = \"%Proj\"\n  edge builtins_ref__ns -> ROOT_NODE\n  ;\n  node builtins_ref\n  attr (builtins_ref) push_symbol = \"<builtins>\"\n  edge builtins_ref -> builtins_ref__ns\n  ;\n  edge @prog.lexical_scope -> builtins_ref\n}\n\n;; Project and module definitions\n(program [(import_statement) (export_statement)]* @imexs)@prog {\n  var proj_scope = ROOT_NODE\n  if (not (eq PROJECT_NAME \"\")) {\n    ; project definition\n    node proj_def__ns\n    attr (proj_def__ns) pop_symbol = \"%Proj\"\n    edge proj_scope -> proj_def__ns\n    ;\n    node proj_def\n    attr (proj_def) pop_symbol = PROJECT_NAME\n    edge proj_def__ns -> proj_def\n    ;\n    set proj_scope = proj_def\n  }\n\n  ; expose globals\n  edge proj_scope -> @prog.globals\n\n  var mod_scope = proj_scope\n  if (not (is-empty @imexs)) {\n    ; module definition\n    let mod_name = (path-filestem FILE_PATH)\n    let mod_path = (path-normalize (path-join (path-dir FILE_PATH) mod_name))\n    ;\n    node mod_def__ns\n    attr (mod_def__ns) pop_symbol = \"%M\"\n    edge mod_scope -> mod_def__ns\n    set mod_scope = mod_def__ns\n    ;\n    scan mod_path {\n      \"index$\" {\n        ; skip last component for index files\n      }\n      \"([^/]+)/?\" {\n        node mod_def\n        attr (mod_def) pop_symbol = $1\n        edge mod_scope -> mod_def\n        set mod_scope = mod_def\n      }\n    }\n    ; make the last one a definition\n    attr (mod_scope) is_definition, source_node = @prog, empty_source_span\n    ; expose exports via module definition\n    edge mod_scope -> @prog.exports\n  } else {\n    ; expose definitions via project scope\n    edge mod_scope -> @prog.defs\n  }\n}\n\n;; Project and module reference\n(program [(import_statement) (export_statement)]* @imexs)@prog {\n  var proj_scope = ROOT_NODE\n  if (not (eq PROJECT_NAME \"\")) {\n    ; project reference\n    node proj_ref__ns\n    attr (proj_ref__ns) push_symbol = \"%Proj\"\n    edge proj_ref__ns -> proj_scope\n    ;\n    node proj_ref\n    attr (proj_ref) push_symbol = PROJECT_NAME\n    edge proj_ref -> proj_ref__ns\n    ;\n    set proj_scope = proj_ref\n  }\n\n  ; compose all project files by adding edge to the project reference\n  edge @prog.lexical_scope -> proj_scope\n\n  var mod_scope = proj_scope\n  if (not (is-empty @imexs)) {\n    ; module reference\n    node mod_ref__ns\n    attr (mod_ref__ns) push_symbol = \"%M\"\n    edge mod_ref__ns -> mod_scope\n    set mod_scope = mod_ref__ns\n    ;\n    let mod_dir = (path-normalize (path-dir FILE_PATH))\n    scan mod_dir {\n      \"([^/]+)/?\" {\n        node mod_ref\n        attr (mod_ref) push_symbol = $1\n        edge mod_ref -> mod_scope\n\n        node mod_node\n        edge mod_node -> mod_ref\n\n        node parent_def\n        attr (parent_def) pop_symbol = \"..\"\n        edge parent_def -> mod_scope\n        edge mod_node -> parent_def\n        attr (mod_node -> parent_def) precedence = 1 ; consume dots eagerly\n\n        set mod_scope = mod_node\n      }\n    }\n\n    ; relative import definition\n    node rel_def\n    attr (rel_def) pop_symbol = \"%RelM\"\n    edge rel_def -> mod_scope\n\n    ; expose reference in lexical scope\n    edge @prog.lexical_scope -> rel_def\n  }\n}\n\n(program\n  (_)@stmt\n)@prog {\n  ; propagate lexical scope\n  edge @stmt.lexical_scope -> @prog.lexical_scope\n\n  ; expose lexical and variable declarations\n  edge @prog.defs -> @stmt.lexical_defs\n  edge @prog.defs -> @stmt.var_defs\n\n  ; exports are visible via module definition\n  edge @prog.exports -> @stmt.exports\n\n  ; globals are visible in the project scope\n  edge @prog.globals -> @stmt.global_defs\n}\n\n\n;; hashbang\n\n(hash_bang_line) {\n}\n\n\n;; Comments\n\n(comment) {\n}\n\n\n\n;  #####\n; #     # #####   ##   ##### ###### #    # ###### #    # #####  ####\n; #         #    #  #    #   #      ##  ## #      ##   #   #   #\n;  #####    #   #    #   #   #####  # ## # #####  # #  #   #    ####\n;       #   #   ######   #   #      #    # #      #  # #   #        #\n; #     #   #   #    #   #   #      #    # #      #   ##   #   #    #\n;  #####    #   #    #   #   ###### #    # ###### #    #   #    ####\n;\n; ###################################################################\n\n;; Attributes defined on statements\n;\n; in .lexical_scope\n;     Lexical scope.\n;\n; out .lexical_defs\n;     Lexical definitions, that are block scoped\n;\n; out .var_defs\n;     Variable definitions, that are function scoped\n;\n; out .exports\n;     Exported definitions.\n;\n; out .default_export\n;    Nameless (but namespaced) exports for use in default and = exports.\n;\n; out .return_type\n;    Type of contained return statement.\n\n[\n    (abstract_class_declaration)\n    (ambient_declaration)\n    (break_statement)\n    (catch_clause)\n    (class_declaration)\n    (continue_statement)\n    (debugger_statement)\n    (do_statement)\n    (else_clause)\n    (empty_statement)\n    (enum_declaration)\n    (export_statement)\n    (expression_statement)\n    (finally_clause)\n    (for_in_statement)\n    (for_statement)\n    (function_declaration)\n    (function_signature)\n    (generator_function_declaration)\n    (hash_bang_line)\n    (if_statement)\n    (import_alias)\n    (import_statement)\n    (interface_declaration)\n    (internal_module)\n    (labeled_statement)\n    (lexical_declaration)\n    (module)\n    (return_statement)\n    (statement_block)\n    (switch_body)\n    (switch_case)\n    (switch_default)\n    (switch_statement)\n    (throw_statement)\n    (try_statement)\n    (type_alias_declaration)\n    (variable_declaration)\n    (while_statement)\n    (with_statement)\n]@stmt {\n  node @stmt.default_export\n  node @stmt.exports\n  node @stmt.global_defs\n  node @stmt.lexical_defs\n  node @stmt.lexical_scope\n  node @stmt.return_type\n  node @stmt.var_defs\n}\n\n\n;; Imports & Exports (The Many Faced God)\n;\n; TypeScript has many import / export forms. Below is a condensed presentation that can be used as a reference\n; for the sections below where the actual rules are defined. One has to be careful with the queries to ensure\n; that cases do not overlap, even if their syntactic forms (partially) do. This must be done by adding negative\n; matches to some queries. This overview should make it easier to spot where negative are required.\n;\n;;;; Exports\n;\n; export_statement :=\n;    (export_statement \"*\"                                source:(_)@from) ; export * from MODULE              ; re-export everything from MODULE\n;  | (export_statement (namespace_export (identifier)@ns) source:(_)@from) ; export * as NAMESPACE from MODULE ; re-export MODULE as NAMESPACE\n;  | (export_statement  \"default\" value:(_)@value)                         ; export default EXPRESSION         ; export EXPRESSION as default\n;  | (export_statement  \"default\" declaration:(_)@decl)                    ; export default DECLARATION        ; export DECLARATION as default\n;  | (export_statement ^\"default\" declaration:(_)@decl)                    ; export DECL                       ; export DECLARATION\n;  | (export_statement \"type\"? (export_clause)@clause  source:(_)@from)    ; export (type) CLAUSE from MODULE  ; re-export (type) identifiers from MODULE\n;  | (export_statement \"type\"? (export_clause)@clause !source         )    ; export (type) CLAUSE              ; export (type) identifiers\n;  | (export_statement \"=\" . (expression)@value)                           ; export = EXPRESSION               ; export EXPRESSION as exports object\n;  | (export_statement \"as\" \"namespace\" . (_)@ns)                          ; export as namespace NAMESPACE     ; export this module as global NAMESPACE\n;\n; export_clause :=\n;    (export_clause (export_specifier)*)                                   ; { EXPORT_SPECIFIER* }\n;\n; export_specifier :=\n;    (export_specifier name:(_)  alias:(_))                                ; NAME\n;  | (export_specifier name:(_) !alias    )                                ; NAME as ALIAS\n;\n;;;; Imports\n;\n; import_statement :=\n;    ; note that the first case overlaps with the two after it, but the behaviour is orthogonal\n;    (import_statement \"type\"?  (import_clause (identifier)@name                                   ) source:(_)@from)  ; import (type) NAME from MODULE           ; import default (type) from MODULE as NAME\n;  | (import_statement \"type\"?  (import_clause                   (namespace_import (identifier)@ns)) source:(_)@from)  ; import (type) * as NAMESPACE from MODULE ; import all (type) identifiers from MODULE in NAMESPACE\n;  | (import_statement \"type\"?  (import_clause                   (named_imports)@named_imports     ) source:(_)@from)  ; import (type) NAMED_IMPORTS from MODULE  ; import named (type) identifiers from MODULE\n;  | (import_statement \"type\"? ^(import_clause)                                                      source:(_)@from)  ; import (type) MODULE                     ; do not import any identifiers from MODULE\n;  | (import_statement \"type\"?  (import_require_clause (identifier)@name                             source:(_)@from)) ; import (type) NAME = require(MODULE)     ; import exports object (type) as NAME from MODULE\n;\n; named_imports :=\n;    (named_imports (import_specifier)*)                                                              ; { IMPORT_SPECIFIER* }\n;\n; import_specifier :=\n;    (import_specifier name:(_)  alias:(_))                                                           ; NAME\n;    (import_specifier name:(_) !alias    )                                                           ; NAME as ALIAS\n;\n; Note that the grammar productions for imports and exports are factored slightly\n; different. The statements above are inlined such that corresponding import and\n; export statements all live in the top-level list. Be mindful that (export_clause)\n; corresponds to (import_clause (named_imports)) and not to (import_cluase)!\n;\n; The presence of a \"type\" modifier does not fundamentally change the way a certain\n; export/import variant works, only which identifiers are included in the import/export.\n; Therefore, we do not handle that as different export/export variants, but deal with that\n; in the rules for the various clauses, which already determine the identifiers involved.\n\n;; Module References\n\n[\n  (export_statement                        source:(_)@from )\n  (import_statement                        source:(_)@from )\n  (import_statement (import_require_clause source:(_)@from))\n]@import_stmt {\n  let mod_path = (replace (source-text @from) \"[\\\"\\\']\" \"\")\n\n  ; relative or non-relative import specific\n  node mod_ref__ns\n  edge mod_ref__ns -> @import_stmt.lexical_scope\n  scan mod_path {\n    \"^\\\\..*$\" { ; relative imports\n      attr (mod_ref__ns) push_symbol = \"%RelM\"\n    }\n    \"^.+$\" { ; non-relative imports\n      attr (mod_ref__ns) push_symbol = \"%NonRelM\"\n    }\n  }\n\n  ; module reference\n  var mod_scope = mod_ref__ns\n  ; normalize path and remove the extension as we want to match \'foo\', \'foo.js\', \'foo.ts\', etc.\n  scan (path-normalize (replace mod_path \"\\.(js|ts|jsx|tsx)$\" \"\")) {\n    \"([^/]+)/?\" {\n      node mod_ref\n      attr (mod_ref) push_symbol = $1\n      edge mod_ref -> mod_scope\n      ;\n      set mod_scope = mod_ref\n    }\n  }\n  ; make the last one a reference\n  attr (mod_scope) is_reference, source_node = @from\n  ; expose mod_ref\n  let @from.mod_ref = mod_scope\n}\n\n;; Named Clauses\n\n[\n  (export_statement \"type\"? (export_clause               )@clause)\n  (import_statement \"type\"? (import_clause (named_imports)@clause))\n] {\n  node @clause.defs\n  node @clause.exports\n  node @clause.lexical_defs\n  node @clause.lexical_scope\n}\n\n;;;; Types\n\n[\n  (export_statement \"type\"? (export_clause                (export_specifier name:(_)@name))@clause)\n  (import_statement \"type\"? (import_clause (named_imports (import_specifier name:(_)@name))@clause))\n] {\n  node @name.type_def\n  node @name.type_def__ns\n  node @name.type_ref\n  node @name.type_ref__ns\n\n  ; type reference\n  attr (@name.type_ref) node_reference = @name\n  edge @name.type_ref -> @name.type_ref__ns\n  ;\n  attr (@name.type_ref__ns) push_symbol = \"%T\"\n  edge @name.type_ref__ns -> @clause.lexical_scope\n}\n\n[\n  (export_statement \"type\"? (export_clause                (export_specifier name:(_)@name !alias))@clause)\n  (import_statement \"type\"? (import_clause (named_imports (import_specifier name:(_)@name !alias))@clause))\n] {\n  ; type definition\n  edge @clause.defs -> @name.type_def__ns ; FIXME defs, lexical_defs?\n  ;\n  attr (@name.type_def__ns) pop_symbol = \"%T\"\n  edge @name.type_def__ns -> @name.type_def\n  ;\n  attr (@name.type_def) node_definition = @name\n  edge @name.type_def -> @name.type_ref\n}\n\n[\n  (export_statement \"type\"? (export_clause                (export_specifier name:(_)@name alias:(_)@alias))@clause)\n  (import_statement \"type\"? (import_clause (named_imports (import_specifier name:(_)@name alias:(_)@alias))@clause))\n] {\n  node @alias.type_def\n  node @alias.type_def__ns\n  node @alias.type_ref\n\n  ; type definition\n  edge @clause.defs -> @alias.type_def__ns\n  ;\n  attr (@alias.type_def__ns) pop_symbol = \"%T\"\n  edge @alias.type_def__ns -> @alias.type_def\n  ;\n  attr (@alias.type_def) node_definition = @alias\n  edge @alias.type_def -> @name.type_ref\n}\n\n\n;;;; Expressions\n\n[\n  (export_statement \"type\"?@is_type (export_clause                (export_specifier name:(_)@name))@clause)\n  (import_statement \"type\"?@is_type (import_clause (named_imports (import_specifier name:(_)@name))@clause))\n] {\nif none @is_type {\n  edge @name.expr_ref__ns -> @clause.lexical_scope\n}\n}\n\n[\n  (export_statement \"type\"?@is_type (export_clause                (export_specifier name:(_)@name !alias))@clause)\n  (import_statement \"type\"?@is_type (import_clause (named_imports (import_specifier name:(_)@name !alias))@clause))\n] {\nif none @is_type {\n  node @name.expr_def\n  node @name.expr_def__ns\n\n  ; expr definition\n  edge @clause.defs -> @name.expr_def__ns ; FIXME defs, lexical_defs?\n  ;\n  attr (@name.expr_def__ns) pop_symbol = \"%E\"\n  edge @name.expr_def__ns -> @name.expr_def\n  ;\n  attr (@name.expr_def) node_definition = @name\n  edge @name.expr_def -> @name.expr_ref\n}\n}\n\n[\n  (export_statement \"type\"?@is_type (export_clause                (export_specifier name:(_)@name alias:(_)@alias))@clause)\n  (import_statement \"type\"?@is_type (import_clause (named_imports (import_specifier name:(_)@name alias:(_)@alias))@clause))\n] {\nif none @is_type {\n  node @alias.expr_def\n  node @alias.expr_def__ns\n\n  ; expr definition\n  edge @clause.defs -> @alias.expr_def__ns\n  ;\n  attr (@alias.expr_def__ns) pop_symbol = \"%E\"\n  edge @alias.expr_def__ns -> @alias.expr_def\n  ;\n  attr (@alias.expr_def) node_definition = @alias\n  edge @alias.expr_def -> @name.expr_ref\n}\n}\n\n;; Exports\n\n; export * from from MODULE\n;\n; (export_statement\n;   \"*\" source:(string)@name\n; )@export_stmt\n\n(export_statement\n  \"*\" source:(_)@name\n)@export_stmt {\n  node expr_pop\n  node expr_push\n  attr (expr_pop) pop_symbol = \"%E\"\n  attr (expr_push) push_symbol = \"%E\"\n  edge expr_pop -> expr_push\n\n  node type_pop\n  node type_push\n  attr (type_pop) pop_symbol = \"%E\"\n  attr (type_push) push_symbol = \"%E\"\n  edge type_pop -> type_push\n\n  ; export all expressions from source module\n  edge @export_stmt.exports -> expr_pop\n  edge expr_push -> @name.mod_ref\n\n  ; export all types from source module\n  edge @export_stmt.exports -> type_pop\n  edge type_push -> @name.mod_ref\n}\n\n; export CLAUSE from MODULE\n; export type CLAUSE from MODULE\n;\n; (export_statement\n;   \"type\"? (export_clause)@clause source:(_)@name\n; )@export_stmt\n\n(export_statement\n  \"type\"? (export_clause)@clause source:(_)@name\n)@export_stmt {\n  ; propagate lexical scope\n  edge @clause.lexical_scope -> @name.mod_ref\n\n  ; propagate exports\n  edge @export_stmt.exports -> @clause.defs\n}\n\n; export CLAUSE\n; export type CLAUSE\n;\n; (export_statement\n;   \"type\"?\n;   (export_clause)@clause\n; )@export_stmt\n\n(export_statement\n  \"type\"?\n  (export_clause)@clause\n  !source\n)@export_stmt {\n  ; propagate lexical scope\n  edge @clause.lexical_scope -> @export_stmt.lexical_scope\n\n  ; propagate exports\n  edge @export_stmt.exports -> @clause.defs\n}\n\n; export DECL\n;\n; (export_statement\n;   ^\"default\"\n;   declaration:(_)@decl\n; )@export_stmt\n\n(export_statement\n  \"default\"?@is_default\n  declaration:(_)@decl\n)@export_stmt {\nif none @is_default {\n  ; propagate lexical scope\n  edge @decl.lexical_scope -> @export_stmt.lexical_scope\n\n  ; expose lexical definitions\n  edge @export_stmt.lexical_defs -> @decl.lexical_defs\n\n  ; expose variable definitions\n  edge @export_stmt.var_defs -> @decl.var_defs\n\n  ; export the definitions\n  edge @export_stmt.exports -> @decl.lexical_defs\n  edge @export_stmt.exports -> @decl.var_defs\n}\n}\n\n; export default DECL\n;\n; (export_statement\n;   \"default\"\n;   declaration:(_)@decl\n; )@export_stmt\n\n; export default EXPR\n;\n; (export_statement\n;   \"default\"\n;   value:(_)@expr\n; )@export_stmt\n\n; export = NAME\n;\n; (export_statement\n;   \"=\"\n;   (expression)@expr\n; )@export_stmt\n\n; NOTE Default exports are modeled as variables named \"default\", because the grammar\n;      treats \"default\" as a regular identifier instead of a keyword. This approach\n;      ensures renaming imports such as `import { default as X } from ...` work correctly.\n;\n;      Default exports are generally expressions. However, if the export is specified as\n;      an identifier, the type with that name is also exported.\n\n(export_statement\n  [\"default\" \"=\"]\n)@export_stmt {\n  node @export_stmt.default_def\n  node @export_stmt.default_expr_def\n  node @export_stmt.default_expr_def__ns_pop\n  node @export_stmt.default_expr_def__ns_push\n  node @export_stmt.default_type_def\n  node @export_stmt.default_type_def__ns_pop\n  node @export_stmt.default_type_def__ns_push\n\n  ; export as default expr\n  edge @export_stmt.exports -> @export_stmt.default_expr_def__ns_pop\n  ;\n  attr (@export_stmt.default_expr_def__ns_pop) pop_symbol = \"%E\"\n  edge @export_stmt.default_expr_def__ns_pop -> @export_stmt.default_expr_def\n  ;\n  ;; @export_stmt.default_expr_def pop_symbol set below for \"default\" and \"=\"\n  edge @export_stmt.default_expr_def -> @export_stmt.default_expr_def__ns_push\n  ;\n  attr (@export_stmt.default_expr_def__ns_push) push_symbol = \"%E\"\n  edge @export_stmt.default_expr_def__ns_push -> @export_stmt.default_def\n\n  ; export as default type\n  edge @export_stmt.exports -> @export_stmt.default_type_def__ns_pop\n  ;\n  attr (@export_stmt.default_type_def__ns_pop) pop_symbol = \"%T\"\n  edge @export_stmt.default_type_def__ns_pop -> @export_stmt.default_type_def\n  ;\n  ;; @export_stmt.default_expr_def pop_symbol set below for \"default\" and \"=\"\n  edge @export_stmt.default_type_def -> @export_stmt.default_type_def__ns_push\n  ;\n  attr (@export_stmt.default_type_def__ns_push) push_symbol = \"%T\"\n  edge @export_stmt.default_type_def__ns_push -> @export_stmt.default_def\n}\n\n(export_statement\n  \"default\"\n)@export_stmt {\n  attr (@export_stmt.default_expr_def) symbol_definition = \"default\", source_node = @export_stmt\n  attr (@export_stmt.default_type_def) symbol_definition = \"default\", source_node = @export_stmt\n}\n\n(export_statement\n  \"=\"\n)@export_stmt {\n  attr (@export_stmt.default_expr_def) symbol_definition = \"<exports>\", source_node = @export_stmt\n  attr (@export_stmt.default_type_def) symbol_definition = \"<exports>\", source_node = @export_stmt\n}\n\n(export_statement\n  \"default\"\n  declaration:(_)@decl\n)@export_stmt {\n  ; propagate lexical scope\n  edge @decl.lexical_scope -> @export_stmt.lexical_scope\n\n  ; expose lexical definitions\n  edge @export_stmt.lexical_defs -> @decl.lexical_defs\n\n  ; expose variable definitions\n  edge @export_stmt.var_defs -> @decl.var_defs\n\n  ; export as default\n  edge @export_stmt.default_def -> @decl.default_export\n}\n\n[\n  (export_statement \"default\" value:(_)@expr)@export_stmt\n  (export_statement \"=\" . (_)@expr)@export_stmt\n] {\n  node @export_stmt.default_expr__ns\n  node @export_stmt.default_expr__typeof\n\n  ; propagate lexical scope\n  edge @expr.lexical_scope -> @export_stmt.lexical_scope\n\n  ; expose lexical definitions\n  edge @export_stmt.lexical_defs -> @expr.lexical_defs\n\n  ; expose variable definitions\n  edge @export_stmt.var_defs -> @expr.var_defs\n\n  ; export expression as default\n  edge @export_stmt.default_def -> @export_stmt.default_expr__ns\n  ;\n  attr (@export_stmt.default_expr__ns) pop_symbol = \"%E\"\n  edge @export_stmt.default_expr__ns -> @export_stmt.default_expr__typeof\n  ;\n  attr (@export_stmt.default_expr__typeof) pop_symbol = \":\"\n  edge @export_stmt.default_expr__typeof -> @expr.type\n}\n\n; NOTE an identifier in a default export can also be a type reference\n[\n  (export_statement \"default\" value:(identifier)@name)@export_stmt\n  (export_statement \"=\" . (identifier)@name)@export_stmt\n] {\n  node @export_stmt.default_type__ns\n  node @name.type_ref\n  node @name.type_ref__ns\n\n  ; export type as default\n  edge @export_stmt.default_def -> @export_stmt.default_type__ns\n  ;\n  attr (@export_stmt.default_type__ns) pop_symbol = \"%T\"\n  edge @export_stmt.default_type__ns -> @name.type_ref\n  ;\n  attr (@name.type_ref) node_reference = @name\n  edge @name.type_ref -> @name.type_ref__ns\n  ;\n  attr (@name.type_ref__ns) push_symbol = \"%T\"\n  edge @name.type_ref__ns -> @export_stmt.lexical_scope\n}\n\n; export * as namespace NAME\n\n; (export_statement\n;   (namespace_export (identifier)@ns)\n;   source:(_)@from\n; )\n\n(export_statement\n  (namespace_export (identifier)@name)\n  source:(_)@from\n)@export_stmt {\n  ; namespace definitions are specified together with (module) and (internal_module)\n\n  ; export expression definition\n  node expr_ns_pop\n  attr (expr_ns_pop) pop_symbol = \"%E\"\n  ;\n  edge @export_stmt.exports -> expr_ns_pop\n  edge expr_ns_pop -> @name.expr_def\n\n  ; export type definition\n  node type_ns_pop\n  attr (type_ns_pop) pop_symbol = \"%T\"\n  ;\n  edge @export_stmt.exports -> type_ns_pop\n  edge type_ns_pop -> @name.type_def\n\n  ; connect expression definition to exports\n  node expr_ns_push\n  attr (expr_ns_push) push_symbol = \"%E\"\n  ;\n  edge @name.expr_def_member -> expr_ns_push\n  edge expr_ns_push -> @from.mod_ref\n\n  ; connect type definition to exports\n  node type_ns_push\n  attr (type_ns_push) push_symbol = \"%T\"\n  ;\n  edge @name.type_def_member -> type_ns_push\n  edge type_ns_push -> @from.mod_ref\n}\n\n; export as namespace NAME\n;\n; (export_statement\n;   \"as\"\n;   \"namespace\"\n;   (identifier)@name\n; )@export_stmt\n\n(program (export_statement\n  \"as\" \"namespace\" . (_)@name\n))@prog {\n  ; namespace definitions are specified together with (module) and (internal_module)\n\n  ; make expression definition global\n  node expr_ns_pop\n  attr (expr_ns_pop) pop_symbol = \"%E\"\n  ;\n  edge @prog.globals -> expr_ns_pop\n  edge expr_ns_pop -> @name.expr_def\n\n  ; make type definition global\n  node type_ns_pop\n  attr (type_ns_pop) pop_symbol = \"%T\"\n  ;\n  edge @prog.globals -> type_ns_pop\n  edge type_ns_pop -> @name.type_def\n\n  ; connect expression definition to exports\n  node expr_ns_push\n  attr (expr_ns_push) push_symbol = \"%E\"\n  ;\n  edge @name.expr_def_member -> expr_ns_push\n  edge expr_ns_push -> @prog.exports\n\n  ; connect type definition to exports\n  node type_ns_push\n  attr (type_ns_push) push_symbol = \"%T\"\n  ;\n  edge @name.type_def_member -> type_ns_push\n  edge type_ns_push -> @prog.exports\n}\n\n;; Imports\n\n; import MODULE\n;\n; (import_statement\n;   ^(import_clause)\n;   source:(_)@from\n; )@import_stmt\n\n(import_statement\n  \"type\"?\n  (import_clause)?@has_clause\n  source:(_)\n) {\nif none @has_clause {\n  ; do nothing, imported for side-effect only\n}\n}\n\n; import (type) NAMED_IMPORTS from MODULE\n\n(import_statement\n  \"type\"?\n  (import_clause (named_imports)@clause)\n  source:(_)@from\n)@import_stmt {\n  ; use module for lexical scope of import clause\n  edge @clause.lexical_scope -> @from.mod_ref\n\n  ; expose imported definitions\n  edge @import_stmt.lexical_defs -> @clause.defs\n}\n\n; import (type) NAME from MODULE\n; import (type) NAME = require(MODULE)\n\n[\n  (import_statement \"type\"? (import_clause         (identifier)) source:(_)@from)@import_stmt\n  (import_statement \"type\"? (import_require_clause (identifier)  source:(_)@from))@import_stmt\n] {\n  node @import_stmt.default_ref\n\n  ; connect default refererence to module\n  edge @import_stmt.default_ref -> @from.mod_ref\n}\n\n;;;; Types\n\n[\n  (import_statement \"type\"? (import_clause         (identifier)@name))@import_stmt\n  (import_statement \"type\"? (import_require_clause (identifier)@name))@import_stmt\n] {\n  node @import_stmt.type_def\n  node @import_stmt.type_def__ns\n  node @import_stmt.default_type_ref\n  node @import_stmt.default_type_ref__ns\n\n  ; type definition\n  edge @import_stmt.lexical_defs -> @import_stmt.type_def__ns\n  ;\n  attr (@import_stmt.type_def__ns) pop_symbol = \"%T\"\n  edge @import_stmt.type_def__ns -> @import_stmt.type_def\n  ;\n  attr (@import_stmt.type_def) node_definition = @name\n  edge @import_stmt.type_def -> @import_stmt.default_type_ref\n  ;\n  ;; @import_stmt.default_type_ref pop_symbol set below for \"default\" and \"=\"\n  edge @import_stmt.default_type_ref -> @import_stmt.default_type_ref__ns\n  ;\n  attr (@import_stmt.default_type_ref__ns) push_symbol = \"%T\"\n  edge @import_stmt.default_type_ref__ns -> @import_stmt.default_ref\n}\n\n(import_statement \"type\"? (import_clause (identifier)))@import_stmt {\n  attr (@import_stmt.default_type_ref) symbol_reference = \"default\", source_node = @import_stmt\n}\n\n(import_statement \"type\"? (import_require_clause (identifier)))@import_stmt {\n  attr (@import_stmt.default_type_ref) symbol_reference = \"<exports>\", source_node = @import_stmt\n}\n\n;;;; Expressions\n\n[\n  (import_statement \"type\"?@is_type (import_clause         (identifier)@name))@import_stmt\n  (import_statement \"type\"?@is_type (import_require_clause (identifier)@name))@import_stmt\n] {\nif none @is_type {\n  node @import_stmt.expr_def\n  node @import_stmt.expr_def__ns\n  node @import_stmt.default_expr_ref\n  node @import_stmt.default_expr_ref__ns\n\n  ; expr definition\n  edge @import_stmt.lexical_defs -> @import_stmt.expr_def__ns\n  ;\n  attr (@import_stmt.expr_def__ns) pop_symbol = \"%E\"\n  edge @import_stmt.expr_def__ns -> @import_stmt.expr_def\n  ;\n  attr (@import_stmt.expr_def) node_definition = @name\n  edge @import_stmt.expr_def -> @import_stmt.default_expr_ref\n  ;\n  ;; @import_stmt.default_expr_ref pop_symbol set below for \"default\" and \"=\"\n  edge @import_stmt.default_expr_ref -> @import_stmt.default_expr_ref__ns\n  ;\n  attr (@import_stmt.default_expr_ref__ns) push_symbol = \"%E\"\n  edge @import_stmt.default_expr_ref__ns -> @import_stmt.default_ref\n}\n}\n\n(import_statement \"type\"?@is_type (import_clause (identifier)))@import_stmt {\nif none @is_type {\n  attr (@import_stmt.default_expr_ref) symbol_reference = \"default\", source_node = @import_stmt\n}\n}\n\n(import_statement \"type\"?@is_type (import_require_clause (identifier)))@import_stmt {\nif none @is_type {\n  attr (@import_stmt.default_expr_ref) symbol_reference = \"<exports>\", source_node = @import_stmt\n}\n}\n\n; import (type) * as NAMESPACE from MODULE\n\n(import_statement\n  \"type\"?\n  (import_clause (namespace_import (identifier)@name))\n  source:(_)@from\n)@import_stmt {\n  ; namespace definitions are specified together with (module) and (internal_module)\n\n  ; expose expression definition\n  node expr_ns_pop\n  attr (expr_ns_pop) pop_symbol = \"%E\"\n  ;\n  edge @import_stmt.lexical_defs -> expr_ns_pop\n  edge expr_ns_pop -> @name.expr_def\n\n  ; expose type definition\n  node type_ns_pop\n  attr (type_ns_pop) pop_symbol = \"%T\"\n  ;\n  edge @import_stmt.lexical_defs -> type_ns_pop\n  edge type_ns_pop -> @name.type_def\n\n  ; connect expression definition to import\n  node expr_ns_push\n  attr (expr_ns_push) push_symbol = \"%E\"\n  ;\n  edge @name.expr_def_member -> expr_ns_push\n  edge expr_ns_push -> @from.mod_ref\n\n  ; connect type definition to import\n  node type_ns_push\n  attr (type_ns_push) push_symbol = \"%T\"\n  ;\n  edge @name.type_def_member -> type_ns_push\n  edge type_ns_push -> @from.mod_ref\n}\n\n;; Import Alias\n\n; import ID = ID | NESTED_ID\n\n; (import_alias\n;   (identifier)\n;   [(identifier) (nested_identifier)]\n; ) {}\n\n\n\n;; Debugger\n\n; debugger;\n; debugger\n\n(debugger_statement) {\n}\n\n\n\n;; Expression\n\n; 1;\n\n(expression_statement (_)@expr)@expr_stmt {\n  ; propagate lexical scope\n  edge @expr.lexical_scope -> @expr_stmt.lexical_scope\n}\n\n\n\n;; Declaration\n\n;; Variable Declarations\n\n; var foo;\n; var x = 1;\n; var x, y = {}, z;\n; let baz = bar;\n; const quux = baz;\n\n(variable_declaration (variable_declarator)@declor)@decl {\n  ; propagate lexical scope\n  edge @declor.lexical_scope -> @decl.lexical_scope\n\n  ; local definitions\n  edge @decl.var_defs -> @declor.defs\n\n  ; default export\n  edge @decl.default_export -> @declor.default_export\n}\n\n(lexical_declaration  (variable_declarator)@declor)@decl {\n  ; propagate lexical scope\n  edge @declor.lexical_scope -> @decl.lexical_scope\n\n  ; local definitions\n  edge @decl.lexical_defs -> @declor.defs\n\n  ; default export\n  edge @decl.default_export -> @declor.default_export\n}\n\n\n;; Variable Declarator\n\n(variable_declarator)@decl {\n  node @decl.default_export\n  node @decl.defs\n  node @decl.lexical_scope\n}\n\n(variable_declarator\n  name:(_)@pat\n)@decl {\n  node @decl.expr_export\n  node @decl.type_export\n\n  ; propagate lexical scope\n  edge @pat.lexical_scope -> @decl.lexical_scope\n\n  ; local definitions from pattern\n  edge @decl.defs -> @pat.defs\n\n  ; default export\n  edge @decl.default_export -> @decl.expr_export\n  ;\n  attr (@decl.expr_export) pop_symbol = \"%E\"\n}\n\n(variable_declarator\n  name:(_)@pat\n  type:(_)@type\n)@decl {\n  ; propagate lexical scope\n  edge @type.lexical_scope -> @decl.lexical_scope\n\n  ; match pattern cotype to type annotation\n  edge @pat.cotype -> @type.type\n\n  ; default export\n  edge @decl.expr_export -> @type.type\n}\n\n(variable_declarator\n  name:(_)@pat\n  !type\n  value:(_)@value\n)@decl {\n  ; match pattern cotype to value type\n  edge @pat.cotype -> @value.type\n\n  ; default export\n  edge @decl.expr_export -> @value.type\n}\n\n(variable_declarator\n  value:(_)@value\n)@decl {\n  ; propagate lexical scope\n  edge @value.lexical_scope -> @decl.lexical_scope\n}\n\n(variable_declarator\n  type:(_)@type\n  value:(_)@value\n) {\n  ; match value cotype to type annotation\n  edge @value.cotype -> @type.type\n}\n\n\n\n;; Function Declarations\n\n; function foo(x) {\n;   return x;\n; }\n\n; (function_declaration\n;   name:(_)@name\n;   type_parameters:(_)@type_params ; opt\n;   parameters:(_)@call_sig\n;   body:(_)@body\n;   return_type:(_)@return_type ; opt\n; )@fun_decl\n\n; (generator_function_declaration\n;   name:(_)@name\n;   type_parameters:(_)@type_params ; opt\n;   parameters:(_)@call_sig\n;   body:(_)@body\n; )@fun_decl\n\n; (function_signature\n;   name:(_)@name\n;   type_parameters:(_)@type_params ; opt\n;   parameters:(_)@params\n;   return_type:(_)@return_type ; opt\n; )@fun_decl\n\n[\n  (function_declaration           name:(_)@name)\n  (generator_function_declaration name:(_)@name)\n  (function_signature             name:(_)@name)\n]@fun_decl {\n  node @fun_decl.callable\n  node @fun_decl.callable__params\n  node @fun_decl.callable__return\n  node @fun_decl.expr_export\n  node @name.expr_def\n  node @name.expr_def__ns\n  node @name.expr_def__typeof\n\n  ; function definition\n  edge @fun_decl.var_defs -> @name.expr_def__ns\n  ;\n  attr (@name.expr_def__ns) pop_symbol = \"%E\"\n  edge @name.expr_def__ns -> @name.expr_def\n  ;\n  attr (@name.expr_def) node_definition = @name, syntax_type = \"function\"\n\n  ; function type\n  edge @name.expr_def -> @name.expr_def__typeof\n  ;\n  attr (@name.expr_def__typeof) pop_symbol = \":\"\n  edge @name.expr_def__typeof -> @fun_decl.callable\n  ;\n  attr (@fun_decl.callable) pop_symbol = \"->\"\n  edge @fun_decl.callable -> @fun_decl.generic_type\n  ;\n  edge @fun_decl.generic_inner_type -> @fun_decl.callable__params\n  edge @fun_decl.generic_inner_type -> @fun_decl.callable__return\n  ;\n  attr (@fun_decl.callable__return) pop_symbol = \"<return>\"\n\n  ; default export\n  edge @fun_decl.default_export -> @fun_decl.expr_export\n  ;\n  attr (@fun_decl.expr_export) pop_symbol = \"%E\"\n  edge @fun_decl.expr_export -> @fun_decl.callable\n}\n\n; type parameters are handled in generics rules\n\n[\n  (function_declaration           parameters:(_)@params)\n  (generator_function_declaration parameters:(_)@params)\n  (function_signature             parameters:(_)@params)\n]@fun_decl {\n  ; propagate lexical scope\n  edge @params.lexical_scope -> @fun_decl.generic_inner_lexical_scope\n\n  ; expose parameter definitions\n  edge @fun_decl.generic_inner_lexical_scope -> @params.defs\n  attr (@fun_decl.generic_inner_lexical_scope -> @params.defs) precedence = 1\n\n  ; expose parameters to type\n  edge @fun_decl.callable__params -> @params.params\n}\n\n[\n  (function_declaration           return_type:(_)@return_type)\n  (generator_function_declaration return_type:(_)@return_type)\n  (function_signature             return_type:(_)@return_type)\n]@fun_decl {\n  ; propagate lexical scope\n  edge @return_type.lexical_scope -> @fun_decl.generic_inner_lexical_scope\n\n  ; function type returns return type\n  edge @fun_decl.callable__return -> @return_type.type\n}\n\n[\n  (function_declaration           \"async\"?@is_async !return_type body:(_)@body)\n  (generator_function_declaration \"async\"?@is_async !return_type body:(_)@body)\n]@fun_decl {\nif none @is_async {\n  ; function returns body return type\n  edge @fun_decl.callable__return -> @body.return_type\n}\n}\n\n[\n  (function_declaration           body:(_)@body)\n  (generator_function_declaration body:(_)@body)\n]@fun_decl {\n  ; propagate lexical scope\n  edge @body.lexical_scope -> @fun_decl.generic_inner_lexical_scope\n\n  ; function scopes lexical and variable definitions\n  edge @fun_decl.generic_inner_lexical_scope -> @body.lexical_defs\n  attr (@fun_decl.generic_inner_lexical_scope -> @body.lexical_defs) precedence = 1\n  edge @fun_decl.generic_inner_lexical_scope -> @body.var_defs\n  attr (@fun_decl.generic_inner_lexical_scope -> @body.var_defs) precedence = 1\n}\n\n[\n  (function_declaration           \"async\" !return_type body:(_)@body)\n  (generator_function_declaration \"async\" !return_type body:(_)@body)\n]@fun_decl {\n  ; function returns body return type\n  edge @fun_decl.callable__return -> @fun_decl.async_type\n  ;\n  edge @fun_decl.await_type -> @body.return_type\n}\n\n\n\n;; (Abstract) Class & Interface Declaration\n\n; class Foo { }\n; class Bar extends Foo {\n;   baz() {}\n; }\n\n; (abstract_class_declaration\n;   decorator:(_) ; rep\n;   name:(_) ; opt\n;   type_parameters:(_) ; opt\n;   (class_heritage) ; opt\n;   body:(_)\n; ) {}\n\n; (class_declaration\n;   decorator:(_) ; rep\n;   name:(_) ; opt\n;   type_parameters:(_) ; opt\n;   (class_heritage) ; opt\n;   body:(_)\n; ) {}\n\n; (interface_declaration\n;   name:(_)@name\n;   type_parameters:(_) ; opt\n;   (extends_clause) ; opt\n;   body:(_)@body\n; )@decl\n\n; decorators\n[\n  (abstract_class_declaration decorator:(_)@dec)\n  (class_declaration          decorator:(_)@dec)\n]@class_decl {\n  ; connect lexical scope\n  edge @dec.lexical_scope -> @class_decl.lexical_scope\n}\n\n\n\n; definitions\n[\n  (abstract_class_declaration name:(_)@name)\n  (class_declaration          name:(_)@name)\n  (interface_declaration      name:(_)@name)\n]@class_decl {\n  node @class_decl.type_export\n  node @name.type_def\n  node @name.type_def__ns\n\n  ; type definition\n  edge @class_decl.lexical_defs -> @name.type_def__ns\n  ;\n  attr (@name.type_def__ns) pop_symbol = \"%T\"\n  edge @name.type_def__ns -> @name.type_def\n  ;\n  attr (@name.type_def) node_definition = @name\n  edge @name.type_def -> @class_decl.generic_type\n\n  ; default type export\n  edge @class_decl.default_export -> @class_decl.type_export\n  ;\n  attr (@class_decl.type_export) pop_symbol = \"%T\"\n  edge @class_decl.type_export -> @class_decl.generic_type\n}\n[\n  (interface_declaration name:(_)@name)\n] {\n  attr (@name.type_def) syntax_type = \"interface\"\n}\n[\n  (abstract_class_declaration name:(_)@name)\n  (class_declaration          name:(_)@name)\n; NOTE not for interface_declaration as body is already a type with an endpoint of needed\n]@class_decl {\n  attr (@name.type_def) syntax_type = \"class\"\n\n  ; mark type scope as endpoint\n  attr (@class_decl.generic_inner_type) is_endpoint\n}\n[\n  (abstract_class_declaration name:(_)@name)\n  (class_declaration          name:(_)@name)\n]@class_decl {\n  node @class_decl.expr_export\n\n  ; class expr definition\n  edge @class_decl.lexical_defs -> @name.expr_def__ns\n  ;\n  attr (@name.expr_def__ns) pop_symbol = \"%E\"\n  edge @name.expr_def__ns -> @name.expr_def\n  ;\n  attr (@name.expr_def) node_definition = @name, syntax_type = \"class\"\n\n  ; type of expression is .static_type\n  edge @name.expr_def -> @name.expr_def__typeof\n  ;\n  attr (@name.expr_def__typeof) pop_symbol = \":\"\n  edge @name.expr_def__typeof -> @class_decl.static_type\n\n  ; default expression export\n  edge @class_decl.default_export -> @class_decl.expr_export\n  ;\n  attr (@class_decl.expr_export) pop_symbol = \"%E\"\n  edge @class_decl.expr_export -> @class_decl.static_type\n\n  ; mark type scope as endpoint\n  attr (@class_decl.static_type) is_endpoint\n}\n\n; type parameters are handled in generics rules below\n\n; inheritance\n[\n  (abstract_class_declaration (class_heritage)@heritage)\n  (class_declaration          (class_heritage)@heritage)\n]@class_decl {\n  ; propagate lexical scope\n  edge @heritage.lexical_scope -> @class_decl.generic_inner_lexical_scope\n\n  ; class type inherits from heritage type\n  edge @class_decl.generic_inner_type -> @heritage.type_members\n  attr (@class_decl.generic_inner_type -> @heritage.type_members) precedence = 1\n\n  ; class object inherits from super class object\n  edge @class_decl.static_type -> @heritage.static_members\n  attr (@class_decl.static_type -> @heritage.static_members) precedence = 1\n\n  ; expose super definition\n  edge @class_decl.generic_inner_lexical_scope -> @heritage.lexical_defs\n}\n[\n  (interface_declaration (extends_type_clause)@extends)\n]@class_decl {\n  ; propagate lexical scope\n  edge @extends.lexical_scope -> @class_decl.generic_inner_lexical_scope\n\n  ; interface type inherits from extends type\n  edge @class_decl.generic_inner_type -> @extends.type_members\n}\n\n; this\n[\n  (abstract_class_declaration)\n  (class_declaration         )\n  (interface_declaration     )\n]@class_decl {\n  node @class_decl.this__expr_def\n  node @class_decl.this__expr_def__ns\n  node @class_decl.this__expr_def__typeof\n  node @class_decl.this__type_def\n  node @class_decl.this__type_def__ns\n  node @class_decl.static_type\n\n  ; this expr definition\n  edge @class_decl.generic_inner_lexical_scope -> @class_decl.this__expr_def__ns\n  ;\n  attr (@class_decl.this__expr_def__ns) pop_symbol = \"%E\"\n  edge @class_decl.this__expr_def__ns -> @class_decl.this__expr_def\n  ;\n  attr (@class_decl.this__expr_def) pop_symbol = \"this\", source_node = @class_decl, empty_source_span\n  edge @class_decl.this__expr_def -> @class_decl.this__expr_def__typeof\n  ;\n  attr (@class_decl.this__expr_def__typeof) pop_symbol = \":\"\n  edge @class_decl.this__expr_def__typeof -> @class_decl.generic_inner_type\n\n  ; this type definition\n  ; FIXME this is more dynamic in reality\n  edge @class_decl.generic_inner_lexical_scope -> @class_decl.this__type_def__ns\n  ;\n  attr (@class_decl.this__type_def__ns) pop_symbol = \"%T\"\n  edge @class_decl.this__type_def__ns -> @class_decl.this__type_def\n  ;\n  attr (@class_decl.this__type_def) pop_symbol = \"this\"\n  edge @class_decl.this__type_def -> @class_decl.generic_inner_type\n}\n\n; default constructor\n; FIXME only if no other constructor is defined\n[\n  (abstract_class_declaration)\n  (class_declaration         )\n]@class_decl {\n  node @class_decl.ctor_def\n\n  ; default nullary constructor\n  edge @class_decl.static_type -> @class_decl.ctor_def\n  ;\n  attr (@class_decl.ctor_def) pop_symbol = \"<new>\"\n  ; FIXME constructor inherits type parameters of surrounding class\n  edge @class_decl.ctor_def -> @class_decl.generic_type\n}\n\n; body\n[\n  (abstract_class_declaration body:(_)@body)\n  (class_declaration          body:(_)@body)\n  (interface_declaration      body:(_)@body)\n]@class_decl {\n  ; propagate lexical scope\n  ; FIXME the static members have access to type variables like this\n  edge @body.lexical_scope -> @class_decl.generic_inner_lexical_scope\n\n  ; class type consists of body members\n  edge @class_decl.generic_inner_type -> @body.type_members\n  attr (@class_decl.generic_inner_type -> @body.type_members) precedence = 2\n\n  ; class object consists of static members\n  edge @class_decl.static_type -> @body.static_members\n  attr (@class_decl.static_type -> @body.static_members) precedence = 2\n}\n\n\n;; Class Body\n\n; (class_body\n;   [(decorator)\n;    (method_definition)\n;    (abstract_method_signature)\n;    (index_signature)\n;    (method_signature)\n;    (public_field_definition)]\n; )\n\n[\n  (class_body)\n  (interface_body)\n]@body {\n  node @body.lexical_scope\n  node @body.type_members\n  node @body.static_members\n}\n\n; decorators\n[\n  (class_body     decorator:(_)@dec)\n]@class_body {\n  ; connect lexical scope\n  edge @dec.lexical_scope -> @class_body.lexical_scope\n}\n\n[\n  (class_body     (_)@mem)\n  (interface_body (_)@mem)\n]@body {\n  ; propagate lexical scope\n  edge @mem.lexical_scope -> @body.lexical_scope\n\n  ; body members are member definitions\n  edge @body.type_members -> @mem.type_members\n\n  ; body static members are static member definitions\n  edge @body.static_members -> @mem.static_members\n}\n\n\n\n;; Statement Block\n\n(statement_block\n  (_)@stmt\n)@block {\n  ; propagate lexical scope\n  edge @stmt.lexical_scope -> @block.lexical_scope\n\n  ; lexical definitions are scoped by the block\n  edge @block.lexical_scope -> @stmt.lexical_defs\n  attr (@block.lexical_scope -> @stmt.lexical_defs) precedence = 1\n\n  ; variable definitions escape the block\n  edge @block.var_defs -> @stmt.var_defs\n\n  ; exports escape the block (for use in namespaces and ambient modules)\n  edge @block.exports -> @stmt.exports\n\n  ; expose return type\n  edge @block.return_type -> @stmt.return_type\n}\n\n\n\n;; If\n\n; if (x)\n;   log(y);\n\n; if (a.b) {\n;   log(c);\n;   d;\n; }\n\n; if (x)\n;   y;\n; else if (a)\n;   b;\n\n; if (a) {\n;   c;\n; } else {\n;   e;\n; }\n\n(if_statement\n  condition:(_)@condition\n)@if_stmt {\n  ; propagate lexical scope\n  edge @condition.lexical_scope -> @if_stmt.lexical_scope\n\n  ; lexical definitions\n  edge @if_stmt.lexical_defs -> @condition.lexical_defs\n\n  ; variable definitions\n  edge @if_stmt.var_defs -> @condition.var_defs\n\n  ; expose return type\n  edge @if_stmt.return_type -> @condition.return_type\n}\n(if_statement\n  consequence:(_)@consequence\n)@if_stmt {\n  ; propagate lexical scope\n  edge @consequence.lexical_scope -> @if_stmt.lexical_scope\n\n  ; lexical definitions\n  edge @if_stmt.lexical_defs -> @consequence.lexical_defs\n\n  ; variable definitions\n  edge @if_stmt.var_defs -> @consequence.var_defs\n\n  ; expose return type\n  edge @if_stmt.return_type -> @consequence.return_type\n}\n(if_statement\n  alternative:(_)@alternative\n)@if_stmt {\n  ; propagate lexical scope\n  edge @alternative.lexical_scope -> @if_stmt.lexical_scope\n\n  ; lexical definitions\n  edge @if_stmt.lexical_defs -> @alternative.lexical_defs\n\n  ; variable definitions\n  edge @if_stmt.var_defs -> @alternative.var_defs\n\n  ; expose return type\n  edge @if_stmt.return_type -> @alternative.return_type\n}\n\n(else_clause (_)@inner)@else_clause {\n  ; propagate lexical scope\n  edge @inner.lexical_scope -> @else_clause.lexical_scope\n\n  ; lexical definitions\n  edge @else_clause.lexical_defs -> @inner.lexical_defs\n\n  ; variable definitions\n  edge @else_clause.var_defs -> @inner.var_defs\n\n  ; expose return type\n  edge @else_clause.return_type -> @inner.return_type\n}\n\n\n\n;; Switch\n\n; switch (x) {\n;   case 1:\n;   case 2:\n;     something();\n;     break;\n;   case \"three\":\n;     somethingElse();\n;     break;\n;   default:\n;     return 4;\n; }\n\n(switch_statement\n  value:(_)\n  body:(_)@body\n)@switch_stmt {\n  ; propagate lexical scope\n  edge @body.lexical_scope -> @switch_stmt.lexical_scope\n\n  ; variable definitions\n  edge @switch_stmt.var_defs -> @body.var_defs\n\n  ; expose return type\n  edge @switch_stmt.return_type -> @body.return_type\n}\n\n(switch_body\n  (_)@choice\n)@switch_body {\n  ; propagate lexical scope\n  edge @choice.lexical_scope -> @switch_body.lexical_scope\n\n  ; lexical definitions are scoped in the body\n  edge @switch_body.lexical_scope -> @choice.lexical_defs\n  attr (@switch_body.lexical_scope -> @choice.lexical_defs) precedence = 1\n\n  ; variable definitions escape\n  edge @switch_body.var_defs -> @choice.var_defs\n\n  ; expose return type\n  edge @switch_body.return_type -> @choice.return_type\n}\n\n(switch_case\n  value:(_)\n  body: (_)@stmt\n)@switch_case {\n  ; propagate lexical scope\n  edge @stmt.lexical_scope -> @switch_case.lexical_scope\n\n  ; lexical definitions\n  edge @switch_case.lexical_defs -> @stmt.lexical_defs\n\n  ; variable definitions\n  edge @switch_case.var_defs -> @stmt.var_defs\n\n  ; expose return type\n  edge @switch_case.return_type -> @stmt.return_type\n}\n\n(switch_default\n  body: (_)@stmt\n)@switch_default {\n  ; propagate lexical scope\n  edge @stmt.lexical_scope -> @switch_default.lexical_scope\n\n  ; lexical definitions\n  edge @switch_default.lexical_defs -> @stmt.lexical_defs\n\n  ; variable definitions\n  edge @switch_default.var_defs -> @stmt.var_defs\n\n  ; expose return type\n  edge @switch_default.return_type -> @stmt.return_type\n}\n\n\n\n;; For\n\n; for (var a, b; c; d)\n;   e;\n\n; for (i = 0, init(); i < 10; i++)\n;   log(y);\n\n; for (;;) {\n;   z;\n;   continue;\n; }\n\n; (for_statement\n;   initializer:(_)@initializer\n;   condition:(_)@condition\n;   increment:(_)@increment ; opt\n;   body:(_)@body\n; )@for_stmt\n\n(for_statement\n  initializer:(_)@initializer\n  condition:(_)@condition\n  body:(_)@body\n)@for_stmt {\n  ; propagate lexical scope\n  edge @initializer.lexical_scope -> @for_stmt.lexical_scope\n  edge @condition.lexical_scope -> @for_stmt.lexical_scope\n  edge @body.lexical_scope -> @for_stmt.lexical_scope\n\n  ; initializer lexical definition is scoped in loop\n  edge @for_stmt.lexical_scope -> @initializer.lexical_defs\n  attr (@for_stmt.lexical_scope -> @initializer.lexical_defs) precedence = 1\n\n  ; initializer variable definition escapes the loop\n  edge @for_stmt.var_defs -> @initializer.var_defs\n\n  ; body lexical definitions are scoped in loop\n  edge @for_stmt.lexical_scope -> @body.lexical_defs\n  attr (@for_stmt.lexical_scope -> @body.lexical_defs) precedence = 1\n\n  ; body variable definitions escape the loop\n  edge @for_stmt.var_defs -> @body.var_defs\n\n  ; expose return type\n  edge @for_stmt.return_type -> @body.return_type\n}\n\n(for_statement\n  increment:(_)@increment\n)@for_stmt {\n  ; propagate lexical scope\n  edge @increment.lexical_scope -> @for_stmt.lexical_scope\n}\n\n\n\n;; For In / For Of\n\n; for (item in items)\n;   item();\n; for (var item in items || {})\n;   item();\n; for (const {thing} in things)\n;   thing();\n; for (x in a, b, c)\n;   foo();\n; for (x[i] in a) {}\n; for (x.y in a) {}\n; for ([a, b] in c) {}\n; for ((a) in b) {}\n\n; for (a of b) {}\n\n(for_in_statement\n  left:(_)@left\n  right:(_)@right\n  body:(_)@body\n)@for_in_stmt {\n  ; propagate lexical scope\n  edge @left.lexical_scope -> @for_in_stmt.lexical_scope\n  edge @right.lexical_scope -> @for_in_stmt.lexical_scope\n  edge @body.lexical_scope -> @for_in_stmt.lexical_scope\n\n  ; expose return type\n  edge @for_in_stmt.return_type -> @body.return_type\n}\n\n(for_in_statement\n  \"var\"\n  left:(_)@pat\n)@for_in_stmt {\n  ; variable definition escapes\n  edge @for_in_stmt.var_defs -> @pat.defs\n}\n\n(for_in_statement\n  [\"let\" \"const\"]\n  left:(_)@pat\n)@for_in_stmt {\n  ; lexical declaration are locally scoped\n  edge @for_in_stmt.lexical_scope -> @pat.defs\n}\n\n(for_in_statement\n  left:(_)@pat\n  \"of\"\n  right:(_)@expr\n)@for_in_stmt {\n  node @for_in_stmt.indexable\n\n  ; connect pattern cotype to index of expression\n  edge @pat.cotype -> @for_in_stmt.indexable\n  ;\n  attr (@for_in_stmt.indexable) push_symbol = \"[]\"\n  edge @for_in_stmt.indexable -> @expr.type\n}\n\n\n\n;; While\n\n; while (a)\n;   b();\n\n; while (a) {\n\n; }\n\n(while_statement\n  condition:(_)@condition\n  body:(_)@body\n)@while_stmt {\n  ; propagate lexical scope\n  edge @condition.lexical_scope -> @while_stmt.lexical_scope\n  edge @body.lexical_scope -> @while_stmt.lexical_scope\n\n  ; lexical definitions escape\n  edge @while_stmt.lexical_defs -> @body.lexical_defs\n\n  ; variable definitions escape\n  edge @while_stmt.var_defs -> @body.var_defs\n\n  ; expose return type\n  edge @while_stmt.return_type -> @body.return_type\n}\n\n\n\n;; Do\n\n; do {\n;   a;\n; } while (b)\n\n; do a; while (b)\n\n; do {} while (b)\n\n(do_statement\n  body:(_)@body\n  condition:(_)@condition\n)@do_stmt {\n  ; propagate lexical scope\n  edge @condition.lexical_scope -> @do_stmt.lexical_scope\n  edge @body.lexical_scope -> @do_stmt.lexical_scope\n\n  ; lexical definitions escape\n  edge @do_stmt.lexical_defs -> @body.lexical_defs\n\n  ; variable definitions escape\n  edge @do_stmt.var_defs -> @body.var_defs\n\n  ; expose return type\n  edge @do_stmt.return_type -> @body.return_type\n}\n\n\n\n;; Try\n\n; try { a; } catch (b) { c; }\n; try { d; } finally { e; }\n; try { f; } catch { g; } finally { h; }\n; try { throw [a, b] } catch ([c, d]) { }\n\n(try_statement\n  body:(_)@body\n)@try_stmt {\n  ; propagate lexical scope\n  edge @body.lexical_scope -> @try_stmt.lexical_scope\n\n  ; lexical definitions escape\n  edge @try_stmt.lexical_defs -> @body.lexical_defs\n\n  ; variable definitions escape\n  edge @try_stmt.var_defs -> @body.var_defs\n\n  ; expose return type\n  edge @try_stmt.return_type -> @body.return_type\n}\n\n(try_statement\n  handler:(_)@handler\n)@try_stmt {\n  ; propagate lexical scope\n  edge @handler.lexical_scope -> @try_stmt.lexical_scope\n\n  ; lexical definitions escape\n  edge @try_stmt.lexical_defs -> @handler.lexical_defs\n\n  ; variable definitions escape\n  edge @try_stmt.var_defs -> @handler.var_defs\n\n  ; expose return type\n  edge @try_stmt.return_type -> @handler.return_type\n}\n\n(try_statement\n  finalizer:(_)@finalizer\n)@try_stmt {\n  ; propagate lexical scope\n  edge @finalizer.lexical_scope -> @try_stmt.lexical_scope\n\n  ; lexical definitions escape\n  edge @try_stmt.lexical_defs -> @finalizer.lexical_defs\n\n  ; variable definitions escape\n  edge @try_stmt.var_defs -> @finalizer.var_defs\n\n  ; expose return type\n  edge @try_stmt.return_type -> @finalizer.return_type\n}\n\n; (catch_clause\n;   parameter:(_)@param ; opt\n;   type:(_)@type       ; opt, and only if parameter is present\n;   body:(_)@body\n; )@catch_clause\n\n(catch_clause type:(_)@type)@catch_clause {\n  ; propagate lexical scope\n  edge @type.lexical_scope -> @catch_clause.lexical_scope\n}\n\n(catch_clause body:(_)@body)@catch_clause {\n  ; propagate lexical scope\n  edge @body.lexical_scope -> @catch_clause.lexical_scope\n\n  ; lexical definitions escape\n  edge @catch_clause.lexical_defs -> @body.lexical_defs\n\n  ; variable definitions escape\n  edge @catch_clause.var_defs -> @body.var_defs\n\n  ; expose return type\n  edge @catch_clause.return_type -> @body.return_type\n}\n\n(finally_clause body:(_)@body)@finally_clause {\n  ; propagate lexical scope\n  edge @body.lexical_scope -> @finally_clause.lexical_scope\n\n  ; lexical definitions escape\n  edge @finally_clause.lexical_defs -> @body.lexical_defs\n\n  ; variable definitions escape\n  edge @finally_clause.var_defs -> @body.var_defs\n\n  ; expose return type\n  edge @finally_clause.return_type -> @body.return_type\n}\n\n\n\n;; With\n\n; with (x) { i; }\n; with (x) { }\n\n(with_statement\n  object:(_)@object\n  body:(_)@body\n)@with_stmt {\n  node @with_stmt.member\n  node @with_stmt.expr_ref__ns\n\n  ; propagate lexical scope\n  edge @object.lexical_scope -> @with_stmt.lexical_scope\n  edge @body.lexical_scope -> @with_stmt.lexical_scope\n\n  ; lexical definitions escape\n  edge @with_stmt.lexical_defs -> @body.lexical_defs\n\n  ; variable definitions escape\n  edge @with_stmt.var_defs -> @body.var_defs\n\n  ; expose return type\n  edge @with_stmt.return_type -> @body.return_type\n\n  ; expression references as member references in object\n  edge @body.lexical_scope -> @with_stmt.expr_ref__ns\n  ;\n  attr (@with_stmt.expr_ref__ns) pop_symbol = \"%E\"\n  edge @with_stmt.expr_ref__ns -> @with_stmt.member\n  ;\n  attr (@with_stmt.member) push_symbol = \".\"\n  edge @with_stmt.member -> @object.type\n}\n\n\n\n;; Break\n\n; break;\n\n(break_statement) {\n}\n\n\n\n;; Continue\n\n; continue;\n\n(continue_statement) {\n}\n\n\n\n;; Return\n\n; return;\n\n(return_statement\n  (_)@returned_expr\n)@return_stmt {\n  ; propagate lexical scope\n  edge @returned_expr.lexical_scope -> @return_stmt.lexical_scope\n\n  ; expose return type\n  edge @return_stmt.return_type -> @returned_expr.type\n}\n\n\n\n;; Throw\n\n; throw new Error(\"error\");\n; throw x = 1, x;\n\n(throw_statement (_)@thrown_expr)@throw_stmt {\n  ; propagate lexical scope\n  edge @thrown_expr.lexical_scope -> @throw_stmt.lexical_scope\n}\n\n\n\n;; Empty\n\n; if (true) { ; };;;\n; if (true) {} else {}\n\n(empty_statement) {\n}\n\n\n\n;; Labeled\n\n; label:\n; while (true) { }\n\n(statement_identifier)@stmt_identifier {\n  ; FIXME remove when we bump tree-sitter-typescript version\n  node @stmt_identifier.global_defs\n  node @stmt_identifier.lexical_defs\n  node @stmt_identifier.lexical_scope\n  node @stmt_identifier.return_type\n  node @stmt_identifier.var_defs\n}\n\n; FIXME match body: when we bump tree-sitter-typescript version\n(labeled_statement (_)@inner)@labeled_stmt {\n  ; propagate lexical scope\n  edge @inner.lexical_scope -> @labeled_stmt.lexical_scope\n\n  ; lexical definitions escape\n  edge @labeled_stmt.lexical_defs -> @inner.lexical_defs\n\n  ; variable definitions escape\n  edge @labeled_stmt.var_defs -> @inner.var_defs\n\n  ; expose return type\n  edge @labeled_stmt.return_type -> @inner.return_type\n}\n\n\n\n;; Ambient Declaration\n\n(ambient_declaration\n  (declaration)@decl\n)@amb_decl {\n  ; propagate lexical scope\n  edge @decl.lexical_scope -> @amb_decl.lexical_scope\n\n  ; expose lexical definitions\n  edge @amb_decl.global_defs -> @decl.lexical_defs\n\n  ; expose variable definitions\n  edge @amb_decl.global_defs -> @decl.var_defs\n}\n\n(ambient_declaration\n  \"global\"\n  (statement_block)@stmt_blk\n)@amb_decl {\n  ; propagate lexical scope\n  edge @stmt_blk.lexical_scope -> @amb_decl.lexical_scope\n\n  ; expose lexical definitions\n  edge @amb_decl.global_defs -> @stmt_blk.lexical_defs\n\n  ; expose variable definitions\n  edge @amb_decl.global_defs -> @stmt_blk.var_defs\n}\n\n; FIXME what is this? tsc doesn\'t recognize this syntax\n(ambient_declaration\n  \"module\"\n  (property_identifier)\n  (_)@type\n)@amb_decl {\n  ; propagate lexical scope\n  edge @type.lexical_scope -> @amb_decl.lexical_scope\n}\n\n\n\n;; (Internal) Module\n\n; (module\n;   name:[(string) (identifier) (nested_identifier)]\n;   body:(_) ; opt\n; ) {}\n\n; (internal_module\n;   name:[(string) (identifier) (nested_identifier)]\n;   body:(_) ; opt\n; ) {}\n\n; NOTE namespaces are modeled as a type and an expression definition, exposing\n;      type and expression members\n\n[\n  ; X\n  (module                                       name:(identifier)@name)\n  (internal_module                              name:(identifier)@name)\n  (export_statement \"as\" \"namespace\" .               (identifier)@name)\n  (export_statement (namespace_export                (identifier)@name))\n  (import_statement (import_clause (namespace_import (identifier)@name)))\n  (ambient_declaration (module                  name:(string)    @name))\n  ; X._\n  (nested_identifier                          object:(identifier)@name)\n  ; _.X._\n  (member_expression                          object:(identifier)@name)\n  ; _.X\n  (nested_identifier                        property:(_)@name)\n  ; _._.X\n  (member_expression                        property:(_)@name)\n] {\n  node @name.expr_def\n  node expr_def_typeof\n  node @name.expr_def_member\n  node @name.type_def\n  node @name.type_def_member\n\n  ; expression definition\n  attr (@name.expr_def) node_definition = @name, syntax_type = \"module\"\n  attr (expr_def_typeof) pop_symbol = \":\"\n  attr (@name.expr_def_member) pop_symbol = \".\"\n  ;\n  edge @name.expr_def -> expr_def_typeof\n  edge expr_def_typeof -> @name.expr_def_member\n\n  ; type definition\n  attr (@name.type_def) node_definition = @name, syntax_type = \"module\"\n  attr (@name.type_def_member) pop_symbol = \".\"\n  ;\n  edge @name.type_def -> @name.type_def_member\n}\n\n[\n  (nested_identifier object:(_)@mod)\n  (member_expression object:[(member_expression) (identifier)]@mod)\n]@nested {\n  node @nested.expr_def\n  node @nested.type_def\n\n  edge @nested.expr_def -> @mod.expr_def\n  edge @nested.type_def -> @mod.type_def\n}\n\n[\n  (nested_identifier object:(_)@mod                                property:(_)@name)\n  (member_expression object:[(member_expression) (identifier)]@mod property:(_)@name)\n] {\n  edge @mod.expr_def_member -> @name.expr_def\n  edge @mod.type_def_member -> @name.type_def\n}\n\n[\n  (nested_identifier property:(_)@name)\n  (member_expression property:(_)@name)\n]@nested {\n  node @nested.expr_def_member\n  node @nested.type_def_member\n\n  edge @name.expr_def_member -> @nested.expr_def_member\n  edge @name.type_def_member -> @nested.type_def_member\n}\n\n[\n  (module          name:(_)@mod body:(_)@body)\n  (internal_module name:(_)@mod body:(_)@body)\n]@mod_decl {\n  ; propagate lexical scope\n  edge @body.lexical_scope -> @mod_decl.lexical_scope\n\n  ; expose expression definition\n  node expr_ns_pop\n  attr (expr_ns_pop) pop_symbol = \"%E\"\n  ;\n  edge @mod_decl.lexical_defs -> expr_ns_pop\n  edge expr_ns_pop -> @mod.expr_def\n\n  ; expose type definition\n  node type_ns_pop\n  attr (type_ns_pop) pop_symbol = \"%T\"\n  ;\n  edge @mod_decl.lexical_defs -> type_ns_pop\n  edge type_ns_pop -> @mod.type_def\n\n  ; connect expression definition to exports\n  node expr_ns_push\n  attr (expr_ns_push) push_symbol = \"%E\"\n  edge @mod.expr_def_member -> expr_ns_push\n  edge expr_ns_push -> @body.exports\n\n  ; connect type definition to exports\n  node type_ns_push\n  attr (type_ns_push) push_symbol = \"%T\"\n  edge @mod.type_def_member -> type_ns_push\n  edge type_ns_push -> @body.exports\n}\n\n; NOTE internal_module is also an expression in the grammar, not only a statement.\n;      Not entirely sure why... tsc doesn\'t seem to accept namespaces in arbitrary\n;      expression positions. Therefore we forward relevant nodes here.\n\n(expression_statement (internal_module)@mod_decl)@stmt {\n  ; connect lexical definitions\n  edge @stmt.lexical_defs -> @mod_decl.lexical_defs\n}\n\n\n\n;; Ambient Module\n\n(ambient_declaration\n  (module name:(string)@name body:(_)@body)\n)@amb_decl {\n  ; propagate lexical scope\n  edge @body.lexical_scope -> @amb_decl.lexical_scope\n\n  ; module definition\n  let mod_path = (replace (source-text @name) \"[\\\"\\\']\" \"\")\n  ;\n  node mod_def__ns\n  attr (mod_def__ns) pop_symbol = \"%NonRelM\"\n  edge @amb_decl.lexical_defs -> mod_def__ns\n  ;\n  var mod_scope = mod_def__ns\n  scan mod_path {\n    \"([^/]+)/?\" {\n      node mod_def\n      attr (mod_def) pop_symbol = $1\n      edge mod_scope -> mod_def\n      ;\n      set mod_scope = mod_def\n    }\n  }\n  ; make the last one a definition\n  attr (mod_scope) is_definition, source_node = @name\n  ; expose exports via module definition\n  edge mod_scope -> @body.exports\n}\n\n\n\n;; Enum Declaration\n\n; (enum_declaration\n;   name:(_)\n;   body:(_)\n; ) {}\n\n(enum_declaration\n  name:(_)@name\n  body:(_)@body\n)@enum_decl {\n  node @enum_decl.static_type\n  node @enum_decl.expr_export\n  node @enum_decl.expr_export__ns\n  node @enum_decl.type\n  node @name.expr_def\n  node @name.expr_def__ns\n  node @name.expr_def__typeof\n  node @name.type_def\n  node @name.type_def__ns\n\n  ; propagate lexical scope\n  edge @body.lexical_scope -> @enum_decl.lexical_scope\n\n  ; enum expression declaration\n  edge @enum_decl.lexical_defs -> @name.expr_def__ns\n  ;\n  attr (@name.expr_def__ns) pop_symbol = \"%E\"\n  edge @name.expr_def__ns -> @name.expr_def\n  ;\n  attr (@name.expr_def) node_definition = @name, syntax_type = \"type\"\n\n  ; type of enum expression is members\n  edge @name.expr_def -> @name.expr_def__typeof\n  ;\n  attr (@name.expr_def__typeof) pop_symbol = \":\"\n  edge @name.expr_def__typeof -> @enum_decl.static_type\n  ;\n  edge @enum_decl.static_type -> @body.static_members\n\n  ; default expression export\n  edge @enum_decl.default_export -> @enum_decl.expr_export\n  ;\n  attr (@enum_decl.expr_export) pop_symbol = \"%E\"\n  edge @enum_decl.expr_export -> @body.static_members\n\n  ; enum type declaration\n  edge @enum_decl.lexical_defs -> @name.type_def__ns\n  ;\n  attr (@name.type_def__ns) pop_symbol = \"%T\"\n  edge @name.type_def__ns -> @name.type_def\n  ;\n  attr (@name.type_def) node_definition = @name, syntax_type = \"type\"\n  edge @name.type_def -> @enum_decl.type\n  ;\n  edge @enum_decl.type -> @body.type_members\n\n  ; NOTE enum_declaration cannot appear directly in `export default\'\n  ;      statements, so we do not set .default_export\n\n  ; this is the enum type\n  edge @body.this -> @enum_decl.type\n\n  ; mark type scope as endpoint\n  attr (@enum_decl.type) is_endpoint\n  attr (@enum_decl.static_type) is_endpoint\n}\n\n; (enum_body\n;   (_) ; _property_name | enum_assignment ; opt, sepBy1\n; ) {}\n\n(enum_body)@body {\n  node @body.lexical_scope\n  node @body.static_members\n  node @body.this\n  node @body.type_members\n}\n\n(enum_body\n  [\n    name:(_)@name\n    (enum_assignment name:(_)@name)\n  ]@constant\n)@body {\n  node @constant.member\n  node @name.expr_def\n  node @name.expr_def__typeof\n\n  ; property definition\n  edge @body.static_members -> @constant.member\n  ;\n  attr (@constant.member) pop_symbol = \".\"\n  edge @constant.member -> @name.expr_def\n  ;\n  attr (@name.expr_def) symbol_definition = (replace (source-text @name) \"[\\\"\\\']\" \"\"), source_node = @name\n\n  ; type of the constant\n  edge @name.expr_def -> @name.expr_def__typeof\n  ;\n  attr (@name.expr_def__typeof) pop_symbol = \":\"\n  edge @name.expr_def__typeof -> @body.this\n}\n\n; (enum_assignment\n;   (_)@property_name\n;   value:(_)\n; ) {}\n\n(enum_body\n  (enum_assignment value:(_)@value)\n)@body {\n  ; propagate lexical scope\n  edge @value.lexical_scope -> @body.lexical_scope\n}\n\n\n\n;; Type Alias Declaration\n\n; (type_alias_declaration\n;   name:(_)@name\n;   type_parameters:(_)@type_params ; opt\n;   value:(_)@value\n; )@decl\n\n(type_alias_declaration\n  name:(_)@name\n  value:(_)@value\n)@decl {\n  node @name.type_def\n  node @name.type_def__ns\n\n  ; propagate lexical scope\n  edge @value.lexical_scope -> @decl.generic_inner_lexical_scope\n\n  ; type definition\n  edge @decl.lexical_defs -> @name.type_def__ns\n  ;\n  attr (@name.type_def__ns) pop_symbol = \"%T\"\n  edge @name.type_def__ns -> @name.type_def\n  ;\n  attr (@name.type_def) node_definition = @name, syntax_type = \"type\"\n  edge @name.type_def -> @decl.generic_type\n  ;\n  ; type parameters are handled by generics rules below\n  ;\n  edge @decl.generic_inner_type -> @decl.alias_type\n  ;\n  ; alias guards are handled by alias rules below\n  ;\n  edge @decl.aliased_type -> @value.type\n\n  ; NOTE type_alias_declaration cannot appear directly in `export default\'\n  ;      statements, so we do not set .default_export\n}\n\n\n\n; #######\n; #       #    # #####  #####  ######  ####   ####  #  ####  #    #  ####\n; #        #  #  #    # #    # #      #      #      # #    # ##   # #\n; #####     ##   #    # #    # #####   ####   ####  # #    # # #  #  ####\n; #         ##   #####  #####  #           #      # # #    # #  # #      #\n; #        #  #  #      #   #  #      #    # #    # # #    # #   ## #    #\n; ####### #    # #      #    # ######  ####   ####  #  ####  #    #  ####\n;\n; ########################################################################\n\n;; Attributes defined on expressions\n;\n; in .lexical_scope\n;     Scope to resolve type names.\n;\n; out .type\n;     Scope representing the type of the expression.\n\n[\n  (array)\n  (arrow_function)\n  (as_expression)\n  (assignment_expression)\n  (augmented_assignment_expression)\n  (await_expression)\n  (binary_expression)\n  (call_expression)\n  (class)\n  (false)\n  (function_expression)\n  (generator_function)\n  (import)\n  (member_expression)\n  (meta_property)\n  (new_expression)\n  (non_null_expression)\n  (null)\n  (number)\n  (object)\n  (parenthesized_expression)\n  (regex)\n  (satisfies_expression)\n  (sequence_expression)\n  (spread_element)\n  (string)\n  (subscript_expression)\n  (super)\n  (template_string)\n  (ternary_expression)\n  (this)\n  (true)\n\n  (type_assertion)\n\n\n\n\n\n\n\n\n  (unary_expression)\n  (undefined)\n  (update_expression)\n  (yield_expression)\n]@expr {\n  node @expr.cotype\n  node @expr.lexical_defs\n  node @expr.lexical_scope\n  node @expr.return_type\n  node @expr.type\n  node @expr.var_defs\n}\n\n[\n  (abstract_class_declaration name:(_)@name)\n  (class_declaration          name:(_)@name)\n  (property_signature         name:(_)@name)\n  (public_field_definition    name:(_)@name)\n  (method_signature           name:(_)@name)\n  (abstract_method_signature  name:(_)@name)\n  (method_definition          name:(_)@name)\n] {\n  node @name.expr_def\n  node @name.expr_def__ns\n  node @name.expr_def__typeof\n}\n\n;; Parenthesized\n\n; (parenthesized_expression\n;   (expression)@expr\n;   (type_annotation)@type ; opt\n; )@parens_expr\n; (parenthesized_expression\n;   (sequence_expression)@seq_expr\n; )@parens_expr\n\n(parenthesized_expression\n  [(expression) (sequence_expression)]@expr\n)@parens_expr {\n  ; propagate lexical scope\n  edge @expr.lexical_scope -> @parens_expr.lexical_scope\n}\n\n(parenthesized_expression\n  [(expression) (sequence_expression)]@expr\n  !type\n)@parens_expr {\n  ; type is type of the inner expression\n  edge @parens_expr.type -> @expr.type\n}\n\n(parenthesized_expression\n  type:(_)@type ; opt\n)@parens_expr {\n  ; propagate lexical scope\n  edge @type.lexical_scope -> @parens_expr.lexical_scope\n\n  ; type is type of the annotation\n  edge @parens_expr.type -> @type.type\n}\n\n\n\n;; Strings\n\n; \"A double quoted string.\";\n; \'A single quoted string.\';\n\n(string) {\n}\n\n\n;; Template Strings\n\n; `A template string ${ \"with another string\" } inside of it.`;\n\n; (template_string)@template_string\n; (template_string (template_substitution (_)@inner_expr))@template_string\n\n(template_string\n  (template_substitution (_)@inner_expr)\n)@template_string {\n  ; propagate lexical scope\n  edge @inner_expr.lexical_scope -> @template_string.lexical_scope\n}\n\n\n\n;; Numbers\n\n; 12345;\n\n(number) {\n}\n\n\n;; Variables / Identifiers\n\n; x;\n\n(identifier)@name {\n  node @name.cotype\n  node @name.lexical_defs\n  node @name.lexical_scope\n  node @name.type\n  node @name.var_defs\n\n  node @name.expr_ref\n  node @name.expr_ref__ns\n  node @name.expr_ref__typeof\n\n  ; expression reference\n  attr (@name.expr_ref) node_reference = @name\n  edge @name.expr_ref -> @name.expr_ref__ns\n  ;\n  attr (@name.expr_ref__ns) push_symbol = \"%E\"\n  edge @name.expr_ref__ns -> @name.lexical_scope\n\n  ; type is type of the reference\n  edge @name.type -> @name.expr_ref__typeof\n  ;\n  attr (@name.expr_ref__typeof) push_symbol = \":\"\n  edge @name.expr_ref__typeof -> @name.expr_ref\n}\n\n; [\n;   (primary_expression/identifier)@name\n;   ; FIXME expansion of _lhs_expression/identifier and _augmented_assignment_lhs\n;   ;       we need to do this for every (identifier) inside a type query\n;   ;       this cannot be expressed, so we manually unroll three levels here\n;   (for_in_statement [\"var\" \"let\" \"const\"]?@is_def left:(identifier)@name)\n;   (assignment_expression left:(identifier)@name)\n;   (augmented_assignment_expression left:(identifier)@name)\n;   (asserts (identifier)@name)\n;   (type_predicate name:(identifier)@name)\n;   ; FIXME type_query has its own restricted expression production\n;   ;       we need to do this for every (identifier) inside a type query\n;   ;       this cannot be expressed, so we manually unroll three levels here\n;   (type_query (identifier)@name)\n;   (type_query (member_expression object:(identifier)@name))\n;   (type_query (member_expression object:(member_expression object:(identifier)@name)))\n;   (type_query (member_expression object:(member_expression object:(member_expression object:(identifier)@name))))\n;   (type_query (subscript_expression object:(identifier)@name))\n;   (type_query (subscript_expression object:(member_expression object:(identifier)@name)))\n;   (type_query (subscript_expression object:(member_expression object:(member_expression object:(identifier)@name))))\n;   (type_query (call_expression function:(identifier)@name))\n;   (type_query (call_expression function:(member_expression object:(identifier)@name)))\n;   (type_query (call_expression function:(member_expression object:(member_expression object:(identifier)@name))))\n;   (type_query (call_expression function:(member_expression object:(member_expression object:(member_expression object:(identifier)@name)))))\n;   (type_query (call_expression function:(subscript_expression object:(identifier)@name)))\n;   (type_query (call_expression function:(subscript_expression object:(member_expression object:(identifier)@name))))\n;   (type_query (call_expression function:(subscript_expression object:(member_expression object:(member_expression object:(identifier)@name)))))\n;   ; FIXME decorator has its own restricted expression production\n;   ;       we need to do this for every (identifier) inside a decorator\n;   ;       this cannot be expressed, so we manually unroll three levels here\n;   (decorator (identifier)@name)\n;   (decorator (member_expression object:(identifier)@name))\n;   (decorator (member_expression object:(member_expression object:(identifier)@name)))\n;   (decorator (member_expression object:(member_expression object:(member_expression object:(identifier)@name))))\n;   (decorator (call_expression function:(identifier)@name))\n;   (decorator (call_expression function:(member_expression object:(identifier)@name)))\n;   (decorator (call_expression function:(member_expression object:(member_expression object:(identifier)@name))))\n;   (decorator (call_expression function:(member_expression object:(member_expression object:(member_expression object:(identifier)@name)))))\n;   ; FIXME nested_identifier has its own restricted expression production\n;   ;       we need to do this for every (identifier) inside a decorator\n;   ;       this cannot be expressed, so we manually unroll three levels here\n;   (nested_identifier object:(identifier)@name)\n;   (nested_identifier object:(member_expression object:(identifier)@name))\n;   (nested_identifier object:(member_expression object:(member_expression object:(identifier)@name)))\n;   (nested_identifier object:(member_expression object:(member_expression object:(member_expression object:(identifier)@name))))\n\n\n\n\n\n; ] {\n; if none @is_def {\n; ; node @name.cotype\n; ; node @name.lexical_defs\n; ; node @name.lexical_scope\n; ; node @name.type\n; ; node @name.var_defs\n\n; }\n; }\n\n\n\n;; Meta property\n\n; new.target\n\n(meta_property) {\n}\n\n\n\n;; Booleans and other special values\n\n;; true;\n\n(true) {\n}\n\n;; false;\n\n(false) {\n}\n\n\n\n;; this;\n\n(this)@this {\n  node @this.expr_ref\n  node @this.expr_ref__ns\n  node @this.expr_ref__typeof\n\n  ; expression reference\n  attr (@this.expr_ref) node_reference = @this\n  edge @this.expr_ref -> @this.expr_ref__ns\n  ;\n  attr (@this.expr_ref__ns) push_symbol = \"%E\"\n  edge @this.expr_ref__ns -> @this.lexical_scope\n\n  ; type is type of the reference\n  edge @this.type -> @this.expr_ref__typeof\n  ;\n  attr (@this.expr_ref__typeof) push_symbol = \":\"\n  edge @this.expr_ref__typeof -> @this.expr_ref\n}\n\n\n\n;; super\n\n(super)@super {\n  node @super.expr_ref\n  node @super.expr_ref__ns\n  node @super.expr_ref__typeof\n\n  ; expression reference\n  attr (@super.expr_ref) node_reference = @super\n  edge @super.expr_ref -> @super.expr_ref__ns\n  ;\n  attr (@super.expr_ref__ns) push_symbol = \"%E\"\n  edge @super.expr_ref__ns -> @super.lexical_scope\n\n  ; type is type of the reference\n  edge @super.type -> @super.expr_ref__typeof\n  ;\n  attr (@super.expr_ref__typeof) push_symbol = \":\"\n  edge @super.expr_ref__typeof -> @super.expr_ref\n}\n\n\n\n; null;\n(null) {\n}\n\n\n\n; undefined;\n(undefined) {\n}\n\n\n\n;; Regular Expressions\n\n; /foo/;\n; /bar/g;\n\n; i dont think the specifics of the patterns or flags matter\n; (regex (regex_pattern))\n; (regex (regex_pattern) (regex_flags))\n\n(regex) {\n}\n\n\n\n;; Satisfies Expressions\n\n; { foo: 42 } satisfies { foo: number }\n\n(satisfies_expression (_)@expr . (_)@type)@satisfies {\n  ; propagate lexical scope\n  edge @expr.lexical_scope -> @satisfies.lexical_scope\n  edge @type.lexical_scope -> @satisfies.lexical_scope\n\n  ; type is union of both\n  edge @satisfies.type -> @expr.type\n  edge @satisfies.type -> @type.type\n}\n\n\n;; Spread Element\n\n(spread_element (_)@expr)@spread_elem {\n  ; propagate lexical scope\n  edge @expr.lexical_scope -> @spread_elem.lexical_scope\n}\n\n\n\n;; Objects\n\n; {\n;   foo: \"bar\",\n;   \"baz\": 1,\n;   quux(x) { x; }\n; };\n;\n; { foo, bar };\n\n; (object\n;   (pair (property_identifier) (string))\n;   (pair (string) (number))\n;   (method_definition\n;     (property_identifier)\n;     (formal_parameters)\n;     (statement_block)))\n;\n; (object\n;   (shorthand_property_identifier)\n;   (shorthand_property_identifier))\n\n; (object (pair (_) (_)@rhs))@object\n; (object (spread_element)@element)@object\n\n(object)@object_expr {\n  attr (@object_expr.type) is_endpoint\n}\n\n(object (_)@entry)@object_expr {\n  ; propagate lexical scope\n  edge @entry.lexical_scope -> @object_expr.lexical_scope\n\n  ; type of object are its members\n  edge @object_expr.type -> @entry.type_members\n}\n\n(object (shorthand_property_identifier)@name) {\n  node @name.lexical_scope\n  node @name.member\n  node @name.type_members\n  node @name.expr_def\n  node @name.expr_def__typeof\n  node @name.expr_ref\n  node @name.expr_ref__ns\n  node @name.expr_ref__typeof\n\n  ; property definition\n  edge @name.type_members -> @name.member\n  ;\n  attr (@name.member) pop_symbol = \".\"\n  edge @name.member -> @name.expr_def\n  ;\n  attr (@name.expr_def) symbol_definition = (replace (source-text @name) \"[\\\"\\\']\" \"\"), source_node = @name\n\n  ; type of the property is type of the reference\n  edge @name.expr_def -> @name.expr_def__typeof\n  ;\n  attr (@name.expr_def__typeof) pop_symbol = \":\"\n  edge @name.expr_def__typeof -> @name.expr_ref__typeof\n\n  ; expression reference\n  attr (@name.expr_ref) node_reference = @name\n  edge @name.expr_ref -> @name.expr_ref__ns\n  ;\n  attr (@name.expr_ref__ns) push_symbol = \"%E\"\n  edge @name.expr_ref__ns -> @name.lexical_scope\n\n  ; type of the reference is type of the declaration\n  attr (@name.expr_ref__typeof) push_symbol = \":\"\n  edge @name.expr_ref__typeof -> @name.expr_ref\n}\n\n(pair\n  key:(_)@name\n  value:(_)@expr\n)@pair {\n  node @pair.lexical_scope\n  node @pair.member\n  node @pair.type_members\n  node @name.expr_def\n  node @name.expr_def__ns\n  node @name.expr_def__typeof\n\n  ; propagate lexical scope\n  edge @expr.lexical_scope -> @pair.lexical_scope\n\n  ; property definition\n  edge @pair.type_members -> @pair.member\n  ;\n  attr (@pair.member) pop_symbol = \".\"\n  edge @pair.member -> @name.expr_def\n  ;\n  attr (@name.expr_def) symbol_definition = (replace (source-text @name) \"[\\\"\\\']\" \"\"), source_node = @name\n\n  ; type of the property is type of the expression\n  edge @name.expr_def -> @name.expr_def__typeof\n  ;\n  attr (@name.expr_def__typeof) pop_symbol = \":\"\n  edge @name.expr_def__typeof -> @expr.type\n}\n\n(spread_element)@spread_elem {\n  node @spread_elem.member\n  node @spread_elem.type_members\n}\n\n\n;; Arrays\n\n; [1,2,3];\n\n; (array (number) (number) (number))\n; (array (_expression)@element)@array\n\n(array)@array_expr {\n  node @array_expr.indexable\n\n  ; array is indexable\n  edge @array_expr.type -> @array_expr.indexable\n  ;\n  attr (@array_expr.indexable) pop_symbol = \"[]\"\n}\n\n(array (_)@element)@array_expr {\n  ; propagate lexical scope\n  edge @element.lexical_scope -> @array_expr.lexical_scope\n\n  ; type is the union of element types\n  edge @array_expr.indexable -> @element.type\n}\n\n\n\n;; Formal Parameters\n\n(formal_parameters)@formal_params {\n  node @formal_params.coparams\n  node @formal_params.defs\n  node @formal_params.lexical_scope\n  node @formal_params.params\n}\n\n(formal_parameters\n  (_)@param\n)@formal_params\n{\n  ; propagate lexical scope\n  edge @param.lexical_scope -> @formal_params.lexical_scope\n\n  ; collect param definitions\n  edge @formal_params.defs -> @param.defs\n\n  ; collect parameters for type\n  edge @formal_params.params -> @param.param\n\n  ; coparams for parameter type inference\n  edge @param.coparam -> @formal_params.coparams\n}\n\n\n\n;; Required & Optional Parameter\n\n; (required_parameter\n;   [(pattern) (this)]\n;   (type_annotation) ; opt\n;   value:(_) ; opt\n; )\n;\n; (optional_parameter\n;   [(pattern) (this)]\n;   (type_annotation) ; opt\n;   value:(_) ; opt\n; )\n\n[\n  (required_parameter)\n  (optional_parameter)\n]@param {\n  node @param.coparam\n  node @param.defs\n  node @param.lexical_scope\n  node @param.param\n}\n\n[\n  (required_parameter pattern:(_)@pattern)\n  (optional_parameter pattern:(_)@pattern)\n]@param {\n  ; propagate lexical scope\n  edge @pattern.lexical_scope -> @param.lexical_scope\n\n  ; expose parameter for type\n  attr (@param.param) pop_symbol = (named-child-index @param)\n\n  ; co-parameter for type inference\n  attr (@param.coparam) push_symbol = (named-child-index @param)\n\n  ; expose definitions\n  edge @param.defs -> @pattern.defs\n}\n\n[\n  (required_parameter pattern:(_)@pattern type:(_)@type)\n  (optional_parameter pattern:(_)@pattern type:(_)@type)\n]@param {\n  ; propagate lexical scope\n  edge @type.lexical_scope -> @param.lexical_scope\n\n  ; connect parameter to type annotation\n  edge @param.param -> @type.type\n\n  ; connect pattern to type annotation\n  edge @pattern.cotype -> @type.type\n}\n\n[\n  (required_parameter pattern:(_)@pattern !type)\n  (optional_parameter pattern:(_)@pattern !type)\n]@param {\n  ; connect parameter to coparameter\n  edge @param.param -> @param.coparam\n\n  ; connect pattern to coparameter\n  edge @pattern.cotype -> @param.coparam\n}\n\n[\n  (required_parameter value:(_)@value)\n  (optional_parameter value:(_)@value)\n]@param {\n  ; propagate lexical scope\n  edge @value.lexical_scope -> @param.lexical_scope\n}\n\n\n\n;; Arrow / Generator / Function Literals\n\n; function (x) {};\n\n; (function_expression\n;   (formal_parameters (identifier))\n;   (statement_block))\n\n; this captures the parameters\n; (function_expression\n;   parameters: (_)@params)\n\n; this captures the body\n; (function_expression\n;   body:(_)@body)@function\n\n; functions with names\n; (function_expression\n;   name:(_)@name\n;   parameters:(_)@call_sig)@fun {\n; }\n\n; x => x;\n; (x) => x;\n; () => {};\n\n; (arrow_function\n;   [ parameter:(identifier)@param parameters:(_)@params ]\n;   body:[(expression) (statement_block)]@body\n; )\n\n; function *() {};\n\n; (generator_function\n;   (formal_parameters)\n;   (statement_block))\n\n; this captures the parameters\n; (generator_function\n;   parameters:(_)@params)\n\n; this captures the body\n; (generator_function\n;   body:(_)@body)@function\n\n; generator functions with names\n; (generator_function\n;   name:(_)@name\n;   parameters:(_)@call_sig)@fun {\n; }\n\n[\n  (function_expression)\n  (arrow_function)\n  (generator_function)\n]@fun {\n  node @fun.callable\n  node @fun.callable__params\n  node @fun.callable__return\n  node @fun.cocallable\n  node @fun.cocallable__params\n\n  ; type is callable\n  edge @fun.type -> @fun.callable\n  ;\n  attr (@fun.callable) pop_symbol = \"->\"\n  edge @fun.callable -> @fun.callable__params\n  edge @fun.callable -> @fun.callable__return\n  ;\n  attr (@fun.callable__return) pop_symbol = \"<return>\"\n\n  ; cotype should also be callable\n  edge @fun.cocallable__params -> @fun.cocallable\n  ;\n  attr (@fun.cocallable) push_symbol = \"->\"\n  edge @fun.cocallable -> @fun.cotype\n}\n\n[\n  (function_expression parameters:(_)@call_sig)\n  (arrow_function      parameters:(_)@call_sig)\n  (generator_function  parameters:(_)@call_sig)\n]@fun {\n  ; propagate lexical scope\n  edge @call_sig.lexical_scope -> @fun.lexical_scope\n\n  ; parameters are visible in body\n  edge @fun.lexical_scope -> @call_sig.defs\n  attr (@fun.lexical_scope -> @call_sig.defs) precedence = 1\n\n  ; connect parameters\n  edge @fun.callable__params -> @call_sig.params\n\n  ; parameter types inferred via cotype\n  edge @call_sig.coparams -> @fun.cocallable__params\n}\n\n(arrow_function parameter:(_)@name)@fun {\n  node @name.expr_def\n  node @name.expr_def__ns\n  node @name.expr_def__typeof\n  node @name.param\n  node @name.coparam\n\n  ; expression definition\n  attr (@name.expr_def__ns) pop_symbol = \"%E\"\n  edge @name.expr_def__ns -> @name.expr_def\n  ;\n  attr (@name.expr_def) node_definition = @name\n\n  ; parameter definition is visible in body\n  edge @fun.lexical_scope -> @name.expr_def__ns\n\n  ; parameter type is inferred via coparam\n  edge @fun.callable__params -> @name.param\n  ;\n  attr (@name.param) pop_symbol = 0\n  edge @name.param -> @name.coparam\n\n  ; parameter type inferred via cotype\n  edge @name.expr_def -> @name.expr_def__typeof\n  ;\n  attr (@name.expr_def__typeof) pop_symbol = \":\"\n  edge @name.expr_def__typeof -> @name.coparam\n  ;\n  attr (@name.coparam) push_symbol = 0\n  edge @name.coparam -> @fun.cocallable__params\n}\n\n[\n  (function_expression body:(_)@body)\n  (arrow_function      body:(_)@body)\n  (generator_function  body:(_)@body)\n]@fun {\n  ; propagate lexical scope\n  edge @body.lexical_scope -> @fun.lexical_scope\n}\n\n;;;; specified return type\n\n[\n  (function_expression return_type:(_)@return_type)\n  (arrow_function      return_type:(_)@return_type)\n]@fun {\n  ; propagate lexical scope\n  edge @return_type.lexical_scope -> @fun.lexical_scope\n\n  ; callable type is return type\n  edge @fun.callable__return -> @return_type.type\n}\n\n;;;; inferred return type\n\n[\n  (function_expression \"async\"?@is_async !return_type body:(_)@body)\n  (arrow_function      \"async\"?@is_async !return_type body:(statement_block)@body)\n]@fun {\nif none @is_async {\n  ; callable is type of return statement\n  edge @fun.callable__return -> @body.return_type\n}\n}\n\n(arrow_function \"async\"?@is_async body:(expression)@expr)@fun {\nif none @is_async {\n  ; callable return type is type of body\n  edge @fun.callable__return -> @expr.type\n}\n}\n\n;;;; inferred async return type\n\n[\n  (function_expression \"async\" !return_type body:(_)@body)\n  (arrow_function      \"async\"              body:(statement_block)@body)\n]@fun_decl {\n  ; function returns body return type\n  edge @fun_decl.callable__return -> @fun_decl.async_type\n  ;\n  edge @fun_decl.await_type -> @body.return_type\n}\n\n(arrow_function \"async\" body:(expression)@expr)@fun_decl {\n  ; function returns body return type\n  edge @fun_decl.callable__return -> @fun_decl.async_type\n  ;\n  edge @fun_decl.await_type -> @expr.type\n}\n\n\n\n;; Function Calls\n\n; foo(1,2,3);\n\n; (call_expression\n;   (identifier)\n;   (arguments\n;     (number)\n;     (number)\n;     (number)))\n\n; (call_expression\n;   function:(_)\n;   type_arguments:(_) ; opt\n;   arguments:(_)\n; )\n\n; this gets the function\n; (call_expression\n;   function: (_)@function)@call\n\n; this gets the expression arguments\n; (call_expression\n;   arguments: (_expression)@argument)@call\n\n; this gets the spread arguments\n; (call_expression\n;   arguments: (spread_element)@spread)@call\n\n(call_expression\n  function:(_)@fun\n)@call_expr {\n  node @call_expr.callable\n  node @call_expr.callable__params\n  node @call_expr.callable__return\n\n  ; propagate lexical scope\n  edge @fun.lexical_scope -> @call_expr.lexical_scope\n\n  ; type of call is type applied callable\n  edge @call_expr.type ->  @call_expr.callable__return\n  ;\n  attr (@call_expr.callable__return) push_symbol = \"<return>\"\n  edge @call_expr.callable__return -> @call_expr.applied_type\n  ;\n  edge @call_expr.generic_type -> @call_expr.callable\n  ;\n  attr (@call_expr.callable) push_symbol = \"->\"\n  edge @call_expr.callable -> @fun.type\n}\n\n; type application is handled by the generics rules below\n\n(call_expression\n  function:(_) arguments: (_)@args\n)@call_expr {\n  ; propagate lexical scope\n  edge @args.lexical_scope -> @call_expr.lexical_scope\n}\n\n(call_expression\n  function:(_) arguments: (arguments)@args\n)@call_expr {\n  ; connect cotype to function params\n  edge @args.coargs -> @call_expr.callable__params ;; FIXME\n  ;\n  edge @call_expr.callable__params -> @call_expr.applied_type\n}\n\n\n\n;; Arguments\n\n(arguments)@args {\n  node @args.lexical_scope\n  node @args.coargs\n}\n\n(arguments (_)@arg)@args {\n  node @arg.coarg\n\n  ; propagate lexical scope\n  edge @arg.lexical_scope -> @args.lexical_scope\n\n  ; connect cotype\n  edge @arg.cotype -> @arg.coarg\n  ;\n  attr (@arg.coarg) push_symbol = (named-child-index @arg)\n  edge @arg.coarg -> @args.coargs\n}\n\n\n\n;; Property Access\n\n; foo.bar;\n; foo[\"bar\"];\n\n; (member_expression (identifier) (property_identifier))\n; (subscript_expression (identifier) (string))\n\n(member_expression\n  object:(_)@object\n  property:(_)@prop\n)@member_expr {\n  node @member_expr.member\n  node @prop.expr_ref\n  node @prop.expr_ref__typeof\n\n  ; propagate lexical scope\n  edge @object.lexical_scope -> @member_expr.lexical_scope\n\n  ; reference to property\n  attr (@prop.expr_ref) node_reference = @prop\n  edge @prop.expr_ref -> @member_expr.member\n  ;\n  attr (@member_expr.member) push_symbol = \".\"\n  edge @member_expr.member -> @object.type\n\n  ; type is type of property\n  edge @member_expr.type -> @prop.expr_ref__typeof\n  ;\n  attr (@prop.expr_ref__typeof) push_symbol = \":\"\n  edge @prop.expr_ref__typeof -> @prop.expr_ref\n}\n\n(subscript_expression\n  object: (_)@object\n  index: (_)@index\n)@subscript_expr {\n  ; propagate lexical scope\n  edge @object.lexical_scope -> @subscript_expr.lexical_scope\n  edge @index.lexical_scope -> @subscript_expr.lexical_scope\n}\n\n(subscript_expression\n  object: (_)@object\n  index: (string)@index\n)@subscript_expr {\n  node @index.expr_ref\n  node @index.expr_ref__typeof\n  node @subscript_expr.member\n\n  ; reference to index\n  attr (@index.expr_ref) symbol_reference = (replace (source-text @index) \"[\\\"\\\']\" \"\"), source_node = @index\n  edge @index.expr_ref -> @subscript_expr.member\n  ;\n  attr (@subscript_expr.member) push_symbol = \".\"\n  edge @subscript_expr.member -> @object.type\n\n  ; type is type of index\n  edge @subscript_expr.type -> @index.expr_ref__typeof\n  ;\n  attr (@index.expr_ref__typeof) push_symbol = \":\"\n  edge @index.expr_ref__typeof -> @index.expr_ref\n}\n\n(subscript_expression\n  object: (_)@object\n  index: (_) ; FIXME typeof index == number\n)@subscript_expr {\n  node @subscript_expr.indexable\n\n  ; type is type of index\n  edge @subscript_expr.type -> @subscript_expr.indexable\n\n  attr (@subscript_expr.indexable) push_symbol = \"[]\"\n  edge @subscript_expr.indexable -> @object.type\n}\n\n(subscript_expression\n  object: (_)\n  index: (number)@index\n)@subscript_expr {\n  node @subscript_expr.comp_index\n\n  ; type is specific index component, in case this is a tuple\n  edge @subscript_expr.type -> @subscript_expr.comp_index\n  ;\n  attr (@subscript_expr.comp_index) push_node = @index\n  edge @subscript_expr.comp_index -> @subscript_expr.indexable\n}\n\n\n\n;; Constructor Calls\n\n; new Foo;\n; new Bar(1,2);\n\n; (new_expression (identifier))\n; (new_expression\n;   (identifier)\n;   (arguments (number) (number)))\n\n; (new_expression\n;   constructor:(_)\n;   type_arguments:(_) ; opt\n;   arguments:(_)      ; opt\n; )\n\n(new_expression constructor:(_)@ctor)@new_expr {\n  node @new_expr.ctor_ref\n\n  ; propagate lexical scope\n  edge @ctor.lexical_scope -> @new_expr.lexical_scope\n\n  ; type of new is the return type of the constructor\n  edge @new_expr.type -> @new_expr.applied_type\n  ;\n  ; type application between reference and constructor type\n  ;\n  edge @new_expr.generic_type -> @new_expr.ctor_ref\n  ;\n  attr (@new_expr.ctor_ref) push_symbol = \"<new>\"\n  edge @new_expr.ctor_ref -> @ctor.type\n}\n\n; type application is handled by the generics rules below\n\n(new_expression\n  arguments:(_)@args\n)@new_expr {\n  ; propagate lexical scope\n  edge @args.lexical_scope -> @new_expr.lexical_scope\n}\n\n\n\n;; Awaits\n\n; await foo();\n\n; (await_expression\n;   (call_expression (identifier) (arguments)))\n\n(await_expression\n  (_)@awaited_expr\n)@await_expr {\n  ; propagate lexical scope\n  edge @awaited_expr.lexical_scope -> @await_expr.lexical_scope\n\n  ; type is the result type of the await\n  edge @await_expr.type -> @await_expr.await_type\n\n  ; await the type of the expression\n  edge @await_expr.async_type -> @awaited_expr.type\n}\n\n\n\n;; Math Operators\n\n; x++;\n; x--;\n; x + y;\n; x - y;\n; x * y;\n; x / y;\n; x % y;\n; x ** y;\n; +x;\n; -x;\n\n; lots of duplication here\n; (update_expression (identifier))\n; (update_expression (identifier))\n; (binary_expression (identifier) (identifier))\n; (binary_expression (identifier) (identifier))\n; (binary_expression (identifier) (identifier))\n; (binary_expression (identifier) (identifier))\n; (binary_expression (identifier) (identifier))\n; (binary_expression (identifier) (identifier))\n; (unary_expression (identifier))\n; (unary_expression (identifier))\n\n(update_expression argument: (_)@argument)@update_expr {\n  ; propagate lexical scope\n  edge @argument.lexical_scope -> @update_expr.lexical_scope\n}\n\n(binary_expression left: (_)@left right: (_)@right)@binary_expr {\n  ; propagate lexical scope\n  edge @left.lexical_scope -> @binary_expr.lexical_scope\n  edge @right.lexical_scope -> @binary_expr.lexical_scope\n}\n\n(unary_expression argument: (_)@argument)@unary_expr {\n  ; propagate lexical scope\n  edge @argument.lexical_scope -> @unary_expr.lexical_scope\n}\n\n\n\n;; Boolean Operators\n\n; x && y;\n; x || y;\n; !x;\n\n; redundant\n; (binary_expression (identifier) (identifier))\n; (binary_expression (identifier) (identifier))\n; (unary_expression (identifier))\n\n\n;; Null Coalescing Operator\n\n; x ?? y;\n\n; redundant\n; (binary_expression (identifier) (identifier))\n\n\n;; Bitwise Operators\n\n; x >> y;\n; x >>> y;\n; x << y;\n; x & y;\n; x | y;\n; x ^ y;\n; ~x;\n\n; redundant\n; (binary_expression (identifier) (identifier))\n; (binary_expression (identifier) (identifier))\n; (binary_expression (identifier) (identifier))\n; (binary_expression (identifier) (identifier))\n; (binary_expression (identifier) (identifier))\n; (binary_expression (identifier) (identifier))\n; (unary_expression (identifier))\n\n\n\n;; Comparator Operators\n\n; x < y;\n; x <= y;\n; x > y;\n; x >= y;\n; x == y;\n; x === y;\n; x != y;\n; x !== y;\n\n; redundant\n; (binary_expression (identifier) (identifier))\n; (binary_expression (identifier) (identifier))\n; (binary_expression (identifier) (identifier))\n; (binary_expression (identifier) (identifier))\n; (binary_expression (identifier) (identifier))\n; (binary_expression (identifier) (identifier))\n; (binary_expression (identifier) (identifier))\n; (binary_expression (identifier) (identifier))\n\n\n\n;; Assignment Expressions;\n\n; x = 0;\n; x.y = 0;\n; x[\"y\"] = 0;\n\n; (assignment_expression (identifier) (number))\n; (assignment_expression\n;   (member_expression (identifier) (property_identifier))\n;   (number))\n; (assignment_expression\n;   (subscript_expression (identifier) (string))\n;   (number))\n\n(assignment_expression\n  left: (_)@left\n  right: (_)@right\n)@assignment_expr {\n  ; propagate lexical scope\n  edge @left.lexical_scope -> @assignment_expr.lexical_scope\n  edge @right.lexical_scope -> @assignment_expr.lexical_scope\n\n  ; type is type of lhs\n  edge @assignment_expr.type -> @left.type\n}\n\n; _destructuring_pattern is used as an expression in assignment_expression\n(assignment_expression\n  left: [(object_pattern) (array_pattern)] @destruct_pat\n  right: (_)@left\n) {\n  node @destruct_pat.type\n\n  ; type is pattern cotype\n  edge @destruct_pat.type -> @destruct_pat.cotype\n\n  ; connect cotype to type\n  edge @destruct_pat.cotype -> @left.cotype\n}\n\n\n;; Augmented Assignment Expressions\n\n; x += y;\n; x.y -= z;\n\n; (augmented_assignment_expression\n;   (identifier)\n;   (identifier))\n; (augmented_assignment_expression\n;   (member_expression (identifier) (identifier))\n;   (identifier))\n\n(augmented_assignment_expression\n  left: (_)@left\n  right: (_)@right\n)@augmented_assignment_expr {\n  ; propagate lexical scope\n  edge @left.lexical_scope -> @augmented_assignment_expr.lexical_scope\n  edge @right.lexical_scope -> @augmented_assignment_expr.lexical_scope\n\n  ; type is type of lhs\n  edge @augmented_assignment_expr.type -> @left.type\n}\n\n\n\n;; Comma Operator\n\n; 1, 2;\n\n; (sequence_expression (number) (number))\n\n(sequence_expression (_)@expr)@sequence_expr {\n  ; propagate lexical scope\n  edge @expr.lexical_scope -> @sequence_expr.lexical_scope\n}\n\n(sequence_expression (_)@last .)@sequence_expr {\n  edge @sequence_expr.type -> @last.type\n}\n\n\n;; Ternary Expression\n\n; x ? y : z;\n\n; (ternary_expression\n;   (identifier)\n;   (identifier)\n;   (identifier))\n\n(ternary_expression\n  condition: (_)@condition\n  consequence: (_)@consequence\n  alternative: (_)@alternative\n)@ternary_expr {\n  ; propagate lexical scope\n  edge @condition.lexical_scope -> @ternary_expr.lexical_scope\n  edge @consequence.lexical_scope -> @ternary_expr.lexical_scope\n  edge @alternative.lexical_scope -> @ternary_expr.lexical_scope\n\n  ; type is union of branch types\n  edge @ternary_expr.type -> @consequence.type\n  edge @ternary_expr.type -> @alternative.type\n}\n\n\n\n;; Type Operators\n\n; typeof x;\n; x instanceof String;\n\n; redundant\n; (unary_expression (identifier))\n; (binary_expression (identifier) (identifier))\n\n\n\n;; Delete Expression\n\n; delete foo.bar;\n\n; redundant\n; (unary_expression\n;   (member_expression (identifier) (property_identifier)))\n\n\n\n;; Void Operator\n\n; void foo;\n\n; redundant\n; (unary_expression (identifier))\n\n\n\n;; Yield Expression\n(yield_expression (_)@yielded_expr)@yield_expr {\n  ; propagate lexical scope\n  edge @yielded_expr.lexical_scope -> @yield_expr.lexical_scope\n}\n\n\n\n;; Class Expressions\n\n; (class\n;   decorator:(_) ; rep\n;   name:(_) ; opt\n;   type_parameters:(_) ; opt\n;   (class_heritage) ; opt\n;   body:(_)\n; ) {}\n\n; (class { });\n; (class Foo { });\n; (class Bar extends Foo {\n;   baz() {}\n; });\n\n; (class)@class\n; (class name:(_)@name)@class\n; (class (_) (_)@superclass (_))@class\n\n; type parameters are handled in generics rules below\n\n(class (class_heritage)@heritage)@class_expr {\n  ; propagate lexical scope\n  edge @heritage.lexical_scope -> @class_expr.lexical_scope\n\n  ; class type inherits from heritage type\n  edge @class_expr.generic_inner_type -> @heritage.type_members\n  attr (@class_expr.generic_inner_type -> @heritage.type_members) precedence = 1\n\n  ; type of class expression inherits heritage static members\n  edge @class_expr.type -> @heritage.static_members\n  attr (@class_expr.type -> @heritage.static_members) precedence = 1\n\n  ; mark type scope as endpoint\n  attr (@class_expr.type) is_endpoint\n  attr (@class_expr.generic_inner_type) is_endpoint\n\n  ; expose super definition\n  edge @class_expr.generic_inner_lexical_scope -> @heritage.lexical_defs\n}\n\n; this\n(class)@class_expr {\n  node @class_expr.this__expr_def\n  node @class_expr.this__expr_def__ns\n  node @class_expr.this__expr_def__typeof\n  node @class_expr.this__type_def\n  node @class_expr.this__type_def__ns\n  node @class_expr.this__type_def__typeof\n\n  ; this expr definition\n  edge @class_expr.generic_inner_lexical_scope -> @class_expr.this__expr_def__ns\n  ;\n  attr (@class_expr.this__expr_def__ns) pop_symbol = \"%E\"\n  edge @class_expr.this__expr_def__ns -> @class_expr.this__expr_def\n  ;\n  attr (@class_expr.this__expr_def) pop_symbol = \"this\"\n  edge @class_expr.this__expr_def -> @class_expr.this__expr_def__typeof\n  ;\n  attr (@class_expr.this__expr_def__typeof) pop_symbol = \":\"\n  edge @class_expr.this__expr_def__typeof -> @class_expr.generic_inner_type\n\n  ; this type definition\n  ; FIXME this is more dynamic in reality\n  edge @class_expr.generic_inner_lexical_scope -> @class_expr.this__type_def__ns\n  ;\n  attr (@class_expr.this__type_def__ns) pop_symbol = \"%T\"\n  edge @class_expr.this__type_def__ns -> @class_expr.this__type_def\n  ;\n  attr (@class_expr.this__type_def) pop_symbol = \"this\"\n  edge @class_expr.this__type_def -> @class_expr.generic_inner_type\n}\n\n; decorators\n(class decorator:(_)@dec)@class_expr {\n  ; connect lexical scope\n  edge @dec.lexical_scope -> @class_expr.lexical_scope\n}\n\n; default constructor\n; FIXME only if no other constructor is defined\n(class)@class_expr {\n  node @class_expr.ctor_def\n\n  ; default nullary constructor\n  edge @class_expr.type -> @class_expr.ctor_def\n  ;\n  attr (@class_expr.ctor_def) pop_symbol = \"<new>\"\n  ; FIXME constructor inherits type parameters of surrounding class\n  edge @class_expr.ctor_def -> @class_expr.generic_type\n}\n\n; body\n(class body:(_)@body)@class_expr {\n  ; propagate lexical scope\n  edge @body.lexical_scope -> @class_expr.lexical_scope\n\n  ; class type consists of body members\n  edge @class_expr.generic_inner_type -> @body.type_members\n\n  ; type of class expression consists of static members\n  edge @class_expr.type -> @body.static_members\n}\n\n\n\n;; Non-null Expression\n\n(non_null_expression\n  (_)@expr\n)@non_null_expr {\n  ; propagate lexical scope\n  edge @expr.lexical_scope -> @non_null_expr.lexical_scope\n}\n\n\n\n;; Type Assertion\n\n; (type_assertion\n;   (type_arguments)\n;   (expression)\n; )\n\n(type_assertion\n  (type_arguments)\n  (expression)@expr\n)@type_assert {\n  ; propagate lexical scope\n  edge @expr.lexical_scope -> @type_assert.lexical_scope\n}\n\n\n\n;; As Expression\n\n; (as_expression\n;   (expression)\n;   (template_string)\n; )\n; (as_expression\n;   (expression)\n;   (_)@type\n; )\n\n(as_expression\n  (_)@expr\n  (_)@type\n)@as_expr {\n  ; propagate lexical scope\n  edge @expr.lexical_scope -> @as_expr.lexical_scope\n  edge @type.lexical_scope -> @as_expr.lexical_scope\n\n  ; type is type of annotation\n  edge @as_expr.type -> @type.type\n}\n\n\n\n; ######\n; #     #   ##   ##### ##### ###### #####  #    #  ####\n; #     #  #  #    #     #   #      #    # ##   # #\n; ######  #    #   #     #   #####  #    # # #  #  ####\n; #       ######   #     #   #      #####  #  # #      #\n; #       #    #   #     #   #      #   #  #   ## #    #\n; #       #    #   #     #   ###### #    # #    #  ####\n\n;; Attributes defined on patterns\n;\n; in .lexical_scope\n;\n; out .defs\n;\n; in .cotype\n;\n\n[\n  (array_pattern)\n  (assignment_pattern)\n  (object_assignment_pattern)\n  (object_pattern)\n  (pair_pattern)\n  (rest_pattern)\n  (shorthand_property_identifier_pattern)\n]@pat {\n  node @pat.cotype\n  node @pat.defs\n  node @pat.lexical_scope\n}\n; these also appear in pattern positions, but already gets some nodes from other rules\n[\n  (this)\n  (member_expression)\n  (subscript_expression)\n  (undefined)\n]@pat {\n  node @pat.defs\n}\n\n[\n  (for_in_statement [\"var\" \"let\" \"const\"] left:(identifier)@name)\n  (variable_declarator name:(identifier)@name)\n  (pattern/identifier)@name\n  (rest_pattern (identifier)@name)\n] {\n  node @name.defs\n  node @name.expr_def\n  node @name.expr_def__ns\n  node @name.expr_def__typeof\n\n  ; pattern defs are this def\n  edge @name.defs -> @name.expr_def__ns\n\n  attr (@name.expr_def__ns) pop_symbol = \"%E\"\n  edge @name.expr_def__ns -> @name.expr_def\n\n  ; local definition\n  attr (@name.expr_def) node_definition = @name\n  edge @name.expr_def -> @name.expr_def__typeof\n\n  ; definition type\n  attr (@name.expr_def__typeof) pop_symbol = \":\"\n  edge @name.expr_def__typeof -> @name.cotype\n}\n\n\n\n(object_pattern (_)@entry)@obj_pat {\n  edge @entry.lexical_scope -> @obj_pat.lexical_scope\n\n  edge @obj_pat.defs -> @entry.defs\n\n  edge @entry.cotype -> @obj_pat.cotype\n}\n\n\n\n; capture object field\n(shorthand_property_identifier_pattern)@prop_pat {\n  node @prop_pat.expr_def\n  node @prop_pat.expr_def__ns\n  node @prop_pat.expr_def__typeof\n  node @prop_pat.expr_ref\n  node @prop_pat.expr_ref__ns\n  node @prop_pat.expr_ref__typeof\n  node @prop_pat.member\n\n  ; link definitions\n  edge @prop_pat.defs -> @prop_pat.expr_def__ns\n\n  ; definition namespace\n  attr (@prop_pat.expr_def__ns) pop_symbol = \"%E\"\n  edge @prop_pat.expr_def__ns -> @prop_pat.expr_def\n\n  ; definition name\n  attr (@prop_pat.expr_def) node_definition = @prop_pat\n  edge @prop_pat.expr_def -> @prop_pat.expr_def__typeof\n\n  ; type of definition\n  attr (@prop_pat.expr_def__typeof) pop_symbol = \":\"\n  edge @prop_pat.expr_def__typeof -> @prop_pat.expr_ref__typeof\n\n  ; type of reference\n  attr (@prop_pat.expr_ref__typeof) push_symbol = \":\"\n  edge @prop_pat.expr_ref__typeof -> @prop_pat.expr_ref\n\n  ; reference name\n  attr (@prop_pat.expr_ref) node_reference = @prop_pat\n  edge @prop_pat.expr_ref -> @prop_pat.member\n\n  ; member projection\n  attr (@prop_pat.member) push_symbol = \".\"\n  edge @prop_pat.member -> @prop_pat.cotype\n}\n\n\n\n; capture object field with specific pattern\n(pair_pattern\n  key:(_)@key ; can be v or \"v\"!\n  value:(_)@value_pat\n)@pair_pat {\n  node @key.expr_ref\n  node @key.expr_ref__ns\n  node @key.expr_ref__typeof\n  node @pair_pat.member\n\n  edge @value_pat.lexical_scope -> @pair_pat.lexical_scope\n\n  edge @pair_pat.defs -> @value_pat.defs\n\n  ; value cotype through projection\n  edge @value_pat.cotype -> @key.expr_ref__typeof\n\n  ; type of reference\n  attr (@key.expr_ref__typeof) push_symbol = \":\"\n  edge @key.expr_ref__typeof -> @key.expr_ref\n\n  ; reference name\n  attr (@key.expr_ref) symbol_reference = (replace (source-text @key) \"[\\\"\\\']\" \"\")\n  edge @key.expr_ref -> @pair_pat.member\n\n  ; member projection\n  attr (@pair_pat.member) push_symbol = \".\"\n  edge @pair_pat.member -> @pair_pat.cotype\n}\n\n\n\n; capture object field with default value\n(object_assignment_pattern\n  left:(_)@pat\n  right:(_)@expr\n)@obj_assgn_pat {\n  ; propagate lexical scope\n  edge @pat.lexical_scope -> @obj_assgn_pat.lexical_scope\n  edge @expr.lexical_scope -> @obj_assgn_pat.lexical_scope\n\n  ; propagate cotype\n  edge @pat.cotype -> @obj_assgn_pat.cotype\n\n  ; propagate defs\n  edge @obj_assgn_pat.defs -> @pat.defs\n\n  ; use default assignment type for cotype\n  edge @pat.cotype -> @expr.type\n}\n\n\n\n(array_pattern)@array_pat {\n  node @array_pat.indexable\n\n  ; propagate cotype\n  attr (@array_pat.indexable) push_symbol = \"[]\"\n  edge @array_pat.indexable -> @array_pat.cotype\n}\n\n(array_pattern\n  (_)@pat\n)@array_pat {\n  node @pat.comp_index\n\n  ; propagate lexical scope\n  edge @pat.lexical_scope -> @array_pat.lexical_scope\n\n  ; propagate cotype components\n  edge @pat.cotype -> @pat.comp_index\n  ;\n  attr (@pat.comp_index) push_symbol = (named-child-index @pat)\n  edge @pat.comp_index -> @array_pat.indexable\n\n  ; propagate defs\n  edge @array_pat.defs -> @pat.defs ;; FIXME\n}\n\n\n\n(assignment_pattern\n  left:(_)@pat\n  right:(_)@expr\n)@assignment_pat {\n  ; propagate lexical scope\n  edge @pat.lexical_scope -> @assignment_pat.lexical_scope\n  edge @expr.lexical_scope -> @assignment_pat.lexical_scope\n\n  ; propagate cotype\n  edge @pat.cotype -> @assignment_pat.cotype\n\n  ; propagate defs\n  edge @assignment_pat.defs -> @pat.defs\n\n  ; use default assignment type for cotype\n  edge @pat.cotype -> @expr.type\n}\n\n\n\n(rest_pattern (_)@inner)@rest_pat {\n  ; propagate lexical scope\n  edge @inner.lexical_scope -> @rest_pat.lexical_scope\n\n  ; propagate cotype\n  ; FIXME what is the cotype?\n\n  ; propagate defs\n  edge @rest_pat.defs -> @inner.defs\n}\n\n\n\n; #     #\n; ##   ## ###### #    # #####  ###### #####   ####\n; # # # # #      ##  ## #    # #      #    # #\n; #  #  # #####  # ## # #####  #####  #    #  ####\n; #     # #      #    # #    # #      #####       #\n; #     # #      #    # #    # #      #   #  #    #\n; #     # ###### #    # #####  ###### #    #  ####\n\n;; Attributes defined on members\n;\n; in .lexical_scope\n;     Scope to resolve type names.\n;     Set by enclosing node.\n;\n; out .type_members\n;     Scope representing the declared type members.\n;\n; out .static_members\n;     Scope representing the declared static members.\n\n[\n  (abstract_method_signature)\n  (call_signature)\n  (class_static_block)\n  (construct_signature)\n  (decorator) ; not strictly a member, but appears in same positions\n  (index_signature)\n  (method_definition)\n  (method_signature)\n  (property_signature)\n  (public_field_definition)\n]@mem {\n  node @mem.lexical_scope\n  node @mem.type_members\n  node @mem.static_members\n}\n\n\n\n;; Decorator\n\n(decorator (_)@expr)@dec {\n  edge @expr.lexical_scope -> @dec.lexical_scope\n}\n\n\n\n;; Static Block\n\n(class_static_block body:(_)@body)@static {\n  edge @body.lexical_scope -> @static.lexical_scope\n}\n\n\n\n;; Construct Signature\n\n; (construct_signature\n;   (type_parameters) ; opt\n;   (formal_parameters)\n;   (type_annotation) ; opt\n; ) {}\n\n(construct_signature)@ctor_sig {\n  node @ctor_sig.ctor_def\n\n  ; constructor member\n  edge @ctor_sig.type_members -> @ctor_sig.ctor_def\n  ;\n  attr (@ctor_sig.ctor_def) pop_symbol = \"<new>\"\n  edge @ctor_sig.ctor_def -> @ctor_sig.generic_type\n}\n\n; type parameters are be handled by the generics rules\n\n(construct_signature\n  parameters:(_)@params\n)@construct_sig {\n  ; propagate lexical scope\n  edge @params.lexical_scope -> @construct_sig.generic_inner_lexical_scope\n}\n\n(construct_signature\n  type:(_)@type ; opt\n)@construct_sig {\n  ; propagate lexical scope\n  edge @type.lexical_scope -> @construct_sig.generic_inner_lexical_scope\n\n  ; propagate lexical scope\n  edge @construct_sig.generic_inner_type -> @type.type\n}\n\n\n\n;; Index Signature\n\n; (index_signature\n;   name:(_)@index_name\n;   index_type:(_)@index_type\n;   type:(_)@type\n; )@index_sig\n\n(index_signature\n  index_type:(_)@index_type\n  type:(_)@type\n)@index_sig {\n  node @index_sig.indexable\n\n  ; propagate lexical scope\n  edge @index_type.lexical_scope -> @index_sig.lexical_scope\n  edge @type.lexical_scope -> @index_sig.lexical_scope\n\n  ; member definition\n  edge @index_sig.type_members -> @index_sig.indexable\n  ;\n  attr (@index_sig.indexable) pop_symbol = \"[]\"\n  edge @index_sig.indexable -> @type.type\n}\n\n\n\n;; Call Signature\n\n; (call_signature\n;   type_parameters:(_) ; opt\n;   parameters:(_)\n;   return_type:[(type_annotation) (asserts) (type_predicate_annotation)] ; opt\n; ) {}\n\n(call_signature)@call_sig {\n  node @call_sig.callable\n  node @call_sig.callable__return\n\n  ; call definition\n  edge @call_sig.type_members -> @call_sig.callable\n  ;\n  attr (@call_sig.callable) pop_symbol = \"->\"\n  edge @call_sig.callable -> @call_sig.callable__return\n  ;\n  attr (@call_sig.callable__return) pop_symbol = \"<return>\"\n  edge @call_sig.callable__return -> @call_sig.generic_type\n}\n\n; type parameters are handled by generics rules below\n\n(call_signature\n  parameters:(_)@parameters\n)@call_sig {\n  ; propagate lexical scope\n  edge @parameters.lexical_scope -> @call_sig.generic_inner_lexical_scope\n}\n\n(call_signature\n  return_type:(_)@return_type\n)@call_sig {\n  ; propagate lexical scope\n  edge @return_type.lexical_scope -> @call_sig.generic_inner_lexical_scope\n\n  ; inner type is return type\n  edge @call_sig.generic_inner_type -> @return_type.type\n}\n\n\n\n;; Property Signature\n\n; (property_signature\n;   name:(_)@name\n;   type:(_)@type ; opt\n; )@sig\n\n(property_signature\n  name:(_)@name\n)@sig {\n  node @sig.member\n\n  ; member definition\n  edge @sig.type_members -> @sig.member\n  ;\n  attr (@sig.member) pop_symbol = \".\"\n  edge @sig.member -> @name.expr_def\n  ;\n  attr (@name.expr_def) node_definition = @name, syntax_type = \"field\"\n}\n\n(property_signature\n  name:(_)@name\n  type:(_)@type ; opt\n)@sig {\n  ; propagate lexical scope\n  edge @type.lexical_scope -> @sig.lexical_scope\n\n  ; type of property is type of annotation\n  edge @name.expr_def -> @name.expr_def__typeof\n  ;\n  attr (@name.expr_def__typeof) pop_symbol = \":\"\n  edge @name.expr_def__typeof -> @type.type\n}\n\n\n\n;; Public Field Definition\n\n; (public_field_definition\n;   name:(_)@name\n;   type:(_)@type ; opt\n;   value:(_)@value ; opt\n; )@def\n\n; decorators\n(public_field_definition decorator:(_)@dec)@def {\n  ; connect lexical scope\n  edge @dec.lexical_scope -> @def.lexical_scope\n}\n\n(public_field_definition\n  name:(_)@name\n)@def {\n  node @def.member\n\n  ; member definition\n  edge @def.type_members -> @def.member\n  ;\n  attr (@def.member) pop_symbol = \".\"\n  edge @def.member -> @name.expr_def\n  ;\n  attr (@name.expr_def) node_definition = @name, syntax_type = \"field\"\n}\n\n(public_field_definition\n  name:(_)@name\n  type:(_)@type ; opt\n)@def {\n  ; propagate lexical scope\n  edge @type.lexical_scope -> @def.lexical_scope\n\n  ; type of field is type of annotation\n  edge @name.expr_def -> @name.expr_def__typeof\n  ;\n  attr (@name.expr_def__typeof) pop_symbol = \":\"\n  edge @name.expr_def__typeof -> @type.type\n}\n\n(public_field_definition\n  name:(_)@name\n  !type ; opt\n  value:(_)@value ; opt\n) {\n  ; type of field is type of value\n  edge @name.expr_def -> @name.expr_def__typeof\n  ;\n  attr (@name.expr_def__typeof) pop_symbol = \":\"\n  edge @name.expr_def__typeof -> @value.type\n}\n\n(public_field_definition\n  value:(_)@value ; opt\n)@def {\n  ; propagate lexical scope\n  edge @value.lexical_scope -> @def.lexical_scope\n}\n\n\n\n;; (Abstract) Method Signature & Definition\n\n; (method_signature\n;   ; \'get\' | \'set\' | \'*\' ; opt\n;   name:(_)\n;   type_parameters:(_) ; opt\n;   parameters:(_)\n;   return_type:[(type_annotation) (asserts) (type_predicate_annotation)]\n; )\n;\n; (abstract_method_signature\n;   ; \'get\' | \'set\' | \'*\' ; opt\n;   name:(_)\n;   type_parameters:(_) ; opt\n;   parameters:(_)\n;   return_type:[(type_annotation) (asserts) (type_predicate_annotation)]\n; ) { }\n\n; (method_definition\n;   ; \'get\' | \'set\' | \'*\' ; opt\n;   name:(_)\n;   type_parameters:(_) ; opt\n;   parameters:(_)\n;   return_type:[(type_annotation) (asserts) (type_predicate_annotation)]\n;   body:(_)\n; )\n\n;;;; regular members (not \'get\' and \'set\', not constructors)\n\n[\n  (method_signature          [\"get\" \"set\"]?@is_acc name:(_)@name) ; FIXME name:^(\"constructor\")\n  (abstract_method_signature [\"get\" \"set\"]?@is_acc name:(_)@name) ; FIXME name:^(\"constructor\")\n  (method_definition         [\"get\" \"set\"]?@is_acc name:(_)@name) ; FIXME name:^(\"constructor\")\n]@mem {\nif none @is_acc {\n  node @mem.member\n  node @mem.callable\n  node @mem.callable__params\n  node @mem.callable__return\n\n  ; member definition\n  edge @mem.type_members -> @mem.member\n  ;\n  attr (@mem.member) pop_symbol = \".\"\n  edge @mem.member -> @name.expr_def\n  ;\n  attr (@name.expr_def) node_definition = @name, syntax_type = \"method\"\n\n  ; type of method is callable generic type\n  edge @name.expr_def -> @name.expr_def__typeof\n  ;\n  attr (@name.expr_def__typeof) pop_symbol = \":\"\n  edge @name.expr_def__typeof -> @mem.callable\n  ;\n  attr (@mem.callable) pop_symbol = \"->\"\n  edge @mem.callable -> @mem.generic_type\n  ;\n  edge @mem.generic_inner_type -> @mem.callable__params\n  edge @mem.generic_inner_type -> @mem.callable__return\n  ;\n  attr (@mem.callable__return) pop_symbol = \"<return>\"\n}\n}\n\n; type parameters are handled by generics rules below\n\n[\n  (method_signature          [\"get\" \"set\"]?@is_acc parameters:(_)@params)\n  (abstract_method_signature [\"get\" \"set\"]?@is_acc parameters:(_)@params)\n  (method_definition         [\"get\" \"set\"]?@is_acc parameters:(_)@params)\n]@mem {\nif none @is_acc {\n  ; propagate lexical scope\n  edge @params.lexical_scope -> @mem.generic_inner_lexical_scope\n\n  ; parameters are visible in body\n  edge @mem.generic_inner_lexical_scope -> @params.defs\n  attr (@mem.generic_inner_lexical_scope -> @params.defs) precedence = 1\n\n  ; connect paarams to type\n  edge @mem.callable__params -> @params.params\n}\n}\n\n[\n  (method_signature          [\"get\" \"set\"]?@is_acc return_type:(_)@return_type)\n  (abstract_method_signature [\"get\" \"set\"]?@is_acc return_type:(_)@return_type)\n  (method_definition         [\"get\" \"set\"]?@is_acc return_type:(_)@return_type)\n]@mem {\nif none @is_acc {\n  ; propagate lexical scope\n  edge @return_type.lexical_scope -> @mem.generic_inner_lexical_scope\n\n  ; inner type is return type\n  edge @mem.callable__return -> @return_type.type\n}\n}\n\n[\n  (method_definition [\"get\" \"set\" \"async\"]?@is_acc !return_type body:(_)@body)\n]@mem {\nif none @is_acc {\n  ; inner type is type of return statement\n  edge @mem.callable__return -> @body.return_type\n}\n}\n\n[\n  (method_definition \"async\" !return_type body:(_)@body)\n]@mem {\n  ; inner type is type of return statement\n  edge @mem.callable__return -> @mem.async_type\n  ;\n  edge @mem.await_type -> @body.return_type\n}\n\n;;;; \'get\' and \'set\' methods\n\n[\n  (method_signature          [\"get\" \"set\"] name:(_)@name)\n  (abstract_method_signature [\"get\" \"set\"] name:(_)@name)\n  (method_definition         [\"get\" \"set\"] name:(_)@name)\n]@mem {\n  node @mem.member\n\n  ; member definition\n  edge @mem.type_members -> @mem.member\n  ;\n  attr (@mem.member) pop_symbol = \".\"\n  edge @mem.member -> @name.expr_def\n  ;\n  attr (@name.expr_def) node_definition = @name, syntax_type = \"field\"\n}\n\n[\n  ; NOTE type_parameters and parameters are assumed to be empty\n  (method_signature          \"get\" name:(_)@name return_type:(_)@return_type)\n  (abstract_method_signature \"get\" name:(_)@name return_type:(_)@return_type)\n  (method_definition         \"get\" name:(_)@name return_type:(_)@return_type)\n]@mem {\n  ; propagate lexical scope\n  edge @return_type.lexical_scope -> @mem.lexical_scope\n\n  ; type of field is return type\n  edge @name.expr_def -> @name.expr_def__typeof\n  ;\n  attr (@name.expr_def__typeof) pop_symbol = \":\"\n  edge @name.expr_def__typeof -> @return_type.type\n}\n\n[\n  ; NOTE type_parameters and return_type are assumed to be empty\n  (method_signature          \"set\" name:(_)@name parameters:(formal_parameters (required_parameter (type_annotation)@param_type)))\n  (abstract_method_signature \"set\" name:(_)@name parameters:(formal_parameters (required_parameter (type_annotation)@param_type)))\n  (method_definition         \"set\" name:(_)@name parameters:(formal_parameters (required_parameter (type_annotation)@param_type)))\n]@mem {\n  ; propagate lexical scope\n  edge @param_type.lexical_scope -> @mem.lexical_scope\n\n  ; type of field is parameter type\n  edge @name.expr_def -> @name.expr_def__typeof\n  ;\n  attr (@name.expr_def__typeof) pop_symbol = \":\"\n  edge @name.expr_def__typeof -> @param_type.type\n}\n\n;;;; method body\n\n[\n  (method_definition body:(_)@body)\n]@mem {\n  ; propagate lexical scope\n  edge @body.lexical_scope -> @mem.generic_inner_lexical_scope\n}\n\n\n\n;;;; FIXME constructor methods\n\n\n\n;; Class Heritage\n\n; (class_heritage\n;   (extends_clause)@extends       ; opt\n;   (implements_clause)@implements ; opt\n; )@class_heritage\n\n[\n  (class_heritage)\n  (extends_clause)\n  (extends_type_clause)\n  (implements_clause)\n]@heritage {\n  node @heritage.lexical_scope\n  node @heritage.lexical_defs\n  node @heritage.type_members\n  node @heritage.static_members\n}\n\n(class_heritage\n  (_)@extends_or_implements ; opt\n)@class_heritage {\n  ; propagate lexical scope\n  edge @extends_or_implements.lexical_scope -> @class_heritage.lexical_scope\n\n  node super__expr_def\n  node super__expr_def__ns\n  node super__expr_def__typeof\n  ;\n  ; super expr definition\n  edge @class_heritage.lexical_defs -> super__expr_def__ns\n  ;\n  attr (super__expr_def__ns) pop_symbol = \"%E\"\n  edge super__expr_def__ns -> super__expr_def\n  ;\n  attr (super__expr_def) pop_symbol = \"super\", source_node = @class_heritage, empty_source_span\n  edge super__expr_def -> super__expr_def__typeof\n  ;\n  attr (super__expr_def__typeof) pop_symbol = \":\"\n\n  ; type members inherited from extends & implements clauses\n  edge @class_heritage.type_members -> @extends_or_implements.type_members\n  edge super__expr_def__typeof -> @extends_or_implements.type_members\n\n  ; static members inherited from extends & implements clauses\n  edge @class_heritage.static_members -> @extends_or_implements.static_members\n}\n\n\n\n;; Implements Clause\n\n; (implements_clause\n;   (_)@type ; commaSep1\n; )@implements\n\n(implements_clause)@implements {\n  edge @implements.type_members -> @implements.alias_type\n}\n\n(implements_clause\n  (_)@type ; commaSep1\n)@implements {\n  ; propagate lexical scope\n  edge @type.lexical_scope -> @implements.lexical_scope\n\n  ; type members from type of interface\n  edge @implements.aliased_type -> @type.type\n}\n\n\n\n;; Extends Clause\n\n; (extends_clause\n;   (expression)@expr ; commaSep1\n;   type_arguments:(_)@type_args ; commaSep1, opt\n; )@extends\n\n(extends_clause\n  (expression)@expr ; commaSep1\n; type_arguments\n)@extends {\n  node @extends.ctor_ref\n\n  ; propagate lexical scope\n  edge @expr.lexical_scope -> @extends.lexical_scope\n\n  ; static members from the super type\n  edge @extends.static_members -> @extends.alias_type\n  ;\n  edge @extends.aliased_type -> @expr.type\n\n  ; type members from the constructor return type\n  edge @extends.type_members -> @extends.ctor_ref\n  ;\n  attr (@extends.ctor_ref) push_symbol = \"<new>\"\n  edge @extends.ctor_ref -> @expr.type\n}\n\n(extends_clause\n  type_arguments:(_)@type_args\n)@extends {\n  ; propagate lexical scope\n  edge @type_args.lexical_scope -> @extends.lexical_scope\n\n  ; FIXME constructor type arguments are currently ignored\n}\n\n\n\n;; Extends Type Clause\n\n; (extends_type_clause\n;   [(type_identifier) (nested_type_identifier) (generic_type)]@type ; commaSep1\n; )@extends\n\n(extends_type_clause)@extends {\n  edge @extends.type_members -> @extends.alias_type\n}\n\n(extends_type_clause\n  (_)@type ; commaSep1\n)@extends {\n  ; propagate lexical scope\n  edge @type.lexical_scope -> @extends.lexical_scope\n\n  ; type members from the super interface\n  edge @extends.aliased_type -> @type.type\n}\n\n\n\n; #######\n;    #    #   # #####  ######  ####\n;    #     # #  #    # #      #\n;    #      #   #    # #####   ####\n;    #      #   #####  #           #\n;    #      #   #      #      #    #\n;    #      #   #      ######  ####\n;\n; ##################################\n\n;; Attributes defined on syntactic types\n;\n; in .lexical_scope\n;     Scope to resolve type names.\n;     Set by enclosing node.\n;\n; out .type\n;     Scope representing the type of the syntactic type.\n\n[\n  (array_type)\n  (asserts)\n  (asserts_annotation)\n  (conditional_type)\n  (constraint)\n  (constructor_type)\n  (default_type)\n  (existential_type)\n  (flow_maybe_type)\n  (function_type)\n  (generic_type)\n  (index_type_query)\n  (infer_type)\n  (intersection_type)\n  (literal_type)\n  (lookup_type)\n  (mapped_type_clause)\n  (nested_type_identifier)\n  (object_type)\n  (omitting_type_annotation)\n  (opting_type_annotation)\n  (optional_type)\n  (parenthesized_type)\n  (predefined_type)\n  (readonly_type)\n  (rest_type)\n  (template_literal_type)\n  (template_type)\n  (this_type)\n  (tuple_type)\n  (type_annotation)\n  (type_arguments)\n  (type_identifier)\n  (type_parameter)\n  (type_parameters)\n  (type_predicate)\n  (type_predicate_annotation)\n  (type_query)\n  (union_type)\n]@type {\n  node @type.lexical_scope\n  node @type.type\n}\n\n\n;; Accessibility Modifier\n\n; (accessibility_modifier) {}\n\n\n\n;; Omitting Type Annotation\n\n; (omitting_type_annotation\n;   (_)@type\n; )@type_annotation\n\n(omitting_type_annotation\n  (_)@type\n)@type_annotation {\n  ; propagate lexical scope\n  edge @type.lexical_scope -> @type_annotation.lexical_scope\n\n  ; type is type of inner\n  edge @type_annotation.type -> @type.type\n}\n\n\n\n;; Opting Type Annotation\n\n; (opting_type_annotation\n;   (_)@type\n; )@type_annotation\n\n(opting_type_annotation\n  (_)@type\n)@type_annotation {\n  ; propagate lexical scope\n  edge @type.lexical_scope -> @type_annotation.lexical_scope\n\n  ; type is type of inner\n  edge @type_annotation.type -> @type.type\n}\n\n\n\n;; Type Annotation\n\n; (type_annotation\n;   (_)@type\n; )@type_annotation\n\n(type_annotation\n  (_)@type\n)@type_annotation {\n  ; propagate lexical scope\n  edge @type.lexical_scope -> @type_annotation.lexical_scope\n\n  ; type is type of inner\n  edge @type_annotation.type -> @type.type\n}\n\n\n\n;; Assertion\n\n; (asserts\n;   [(type_predicate) (identifier) (this)]\n; ) {}\n\n(asserts\n  (_)@type\n)@asserts {\n  ; propagate lexical scope\n  edge @type.lexical_scope -> @asserts.lexical_scope\n}\n\n(asserts_annotation (_)@asserts)@asserts_annotation {\n  edge @asserts.lexical_scope -> @asserts_annotation.lexical_scope\n}\n\n\n;; Optional Type\n\n(optional_type\n  (_)@type\n)@opt_type {\n  ; propagate lexical scope\n  edge @type.lexical_scope -> @opt_type.lexical_scope\n\n  ; type is type of inner\n  edge @opt_type.type -> @type.type\n}\n\n\n\n;; Rest Type\n\n(rest_type\n  (_)@type\n)@rest_type {\n  ; propagate lexical scope\n  edge @type.lexical_scope -> @rest_type.lexical_scope\n\n  ; FIXME is this an array type?\n  edge @rest_type.type -> @type.type\n}\n\n\n\n;; Constructor Type\n\n; (constructor_type\n;   (type_parameters) ; opt\n;   (formal_parameters)\n;   (_)@type\n; ) {}\n\n(constructor_type)@ctor_type {\n  node @ctor_type.ctor_def\n\n  ; type is ctor member\n  edge @ctor_type.type -> @ctor_type.ctor_def\n  ;\n  attr (@ctor_type.ctor_def) pop_symbol = \"<new>\"\n  edge @ctor_type.ctor_def -> @ctor_type.generic_type\n}\n\n; type parameters are handled by generics rules below\n\n(constructor_type\n  parameters:(_)@params\n  type:(_)@type\n)@ctor_type {\n  ; propagate lexical scope\n  edge @params.lexical_scope -> @ctor_type.generic_inner_lexical_scope\n  edge @type.lexical_scope -> @ctor_type.generic_inner_lexical_scope\n\n  ; type is the return type\n  edge @ctor_type.generic_inner_type -> @type.type\n}\n\n\n\n;; Infer Type\n\n; (infer_type\n;   (type_identifier)\n; ) {}\n\n(infer_type\n  (_)@type\n)@infer_type {\n  ; propagate lexical scope\n  edge @type.lexical_scope -> @infer_type.lexical_scope\n\n  ; type is the inner type\n  edge @infer_type.type -> @type.type\n}\n\n\n\n;; Conditional Type\n\n; T1 extends T2 ? T3 : T4\n\n(conditional_type\n  left:(_)@left\n  right:(_)@right\n  consequence:(_)@consequence\n  alternative:(_)@alternative\n)@cond_type {\n  ; propagate lexical scope\n  edge @left.lexical_scope -> @cond_type.lexical_scope\n  edge @right.lexical_scope -> @cond_type.lexical_scope\n  edge @consequence.lexical_scope -> @cond_type.lexical_scope\n  edge @alternative.lexical_scope -> @cond_type.lexical_scope\n\n  ; type is the union of the possible result types (over-approximation)\n  edge @cond_type.type -> @consequence.type\n  edge @cond_type.type -> @alternative.type\n}\n\n\n\n;; Generic Type\n\n; (generic_type\n;   [(type_identifier) (nested_type_identifier)]\n;   (type_arguments)\n; ) {}\n\n(generic_type\n  name: (_)@type\n)@generic_type {\n  ; propagate lexical scope\n  edge @type.lexical_scope -> @generic_type.lexical_scope\n\n  ; type is applied generic type\n  edge @generic_type.type -> @generic_type.applied_type\n  ;\n  ; type application is handled by the generics rules below\n  ;\n  edge @generic_type.generic_type -> @type.type\n}\n\n\n\n;; Type Predicate\n\n; NAME is TYPE\n\n; (type_predicate\n;   [(identifier) (this)]\n;   (_)@type\n; ) {}\n\n(type_predicate\n  (_)@name\n  (_)@type\n)@type_pred {\n  ; propagate lexical scope\n  edge @name.lexical_scope -> @type_pred.lexical_scope\n  edge @type.lexical_scope -> @type_pred.lexical_scope\n}\n\n\n;; Type Predicate Annotation\n\n; (type_predicate_annotation\n;   (type_predicate)@type_pred\n; )@type_pred_anno {}\n\n(type_predicate_annotation\n  (type_predicate)@type_pred\n)@type_pred_anno {\n  ; propagate lexical scope\n  edge @type_pred.lexical_scope -> @type_pred_anno.lexical_scope\n}\n\n\n\n;; Type Query\n\n; typeof E\n\n; (type_query\n;   (_)@expr\n; ) {}\n\n(type_query\n  (_)@expr\n)@type_query {\n  ; propagate lexical scope\n  edge @expr.lexical_scope -> @type_query.lexical_scope\n\n  ; type is type of expression\n  edge @type_query.type -> @expr.type\n}\n\n\n\n;; Index Type Query\n\n; keyof T\n\n(index_type_query\n  (_)@type\n)@index_type_query {\n  ; propagate lexical scope\n  edge @type.lexical_scope -> @index_type_query.lexical_scope\n}\n\n\n\n;; Lookup Type\n\n; T1[T2]\n\n(lookup_type\n  (_)@primary_type\n  (_)@type\n)@lookup_type {\n  ; propagate lexical scope\n  edge @primary_type.lexical_scope -> @lookup_type.lexical_scope\n  edge @type.lexical_scope -> @lookup_type.lexical_scope\n}\n\n\n\n;; Mapped Type Clause\n\n; [T1 in T2]\n\n; (mapped_type_clause\n;   (type_identifier)\n;   (_)@type\n; ) {}\n\n(mapped_type_clause\n  type:(_)@type\n)@mapped_type_clause {\n  ; propagate lexical scope\n  edge @type.lexical_scope -> @mapped_type_clause.lexical_scope\n\n  ; FIXME is this correct?\n  edge @mapped_type_clause.type -> @type.type\n}\n\n\n\n;; Literal Type\n\n; (literal_type\n;   [(unary_expression operator:(_) argument:(number))\n;    (number)\n;    (string)\n;    (true)\n;    (false)]\n; ) {}\n\n\n\n;; Existential Type\n\n(existential_type) {}\n\n\n\n;; Maybe Type\n\n(flow_maybe_type\n  (_)@primary_type\n)@flow_type {\n  ; propagate lexical scope\n  edge @primary_type.lexical_scope -> @flow_type.lexical_scope\n\n  ; type is type of inner\n  edge @flow_type.type -> @primary_type.type\n}\n\n\n\n;; Parenthesized Type\n\n(parenthesized_type\n  (_)@type\n)@parens_type {\n  ; propagate lexical scope\n  edge @type.lexical_scope -> @parens_type.lexical_scope\n\n  ; type is type of inner\n  edge @parens_type.type -> @type.type\n}\n\n\n\n;; Predefined Type\n\n; (predefined_type) {}\n\n\n\n;; Type Arguments\n\n(type_arguments)@type_args {\n  node @type_args.type_args\n  attr (@type_args.type_args) is_exported\n}\n\n(type_arguments\n  (_)@type ; commaSep1\n)@type_args {\n  node @type.arg_index\n\n  ; propagate lexical scope\n  edge @type.lexical_scope -> @type_args.lexical_scope\n\n  ; type args are positional indexed types of sub terms\n  edge @type_args.type_args -> @type.arg_index\n  ;\n  attr (@type.arg_index) pop_symbol = (named-child-index @type)\n  edge @type.arg_index -> @type.type\n}\n\n\n\n;; Array Type\n\n; (array_type\n;   (_)@element_type\n; )@type\n\n(array_type)@type {\n  node @type.indexable\n\n  ; type is indexable element type\n  edge @type.type -> @type.indexable\n  ;\n  attr (@type.indexable) pop_symbol = \"[]\"\n}\n\n(array_type\n  (_)@element_type\n)@type {\n  ; propagate lexical scope\n  edge @element_type.lexical_scope -> @type.lexical_scope\n\n  edge @type.indexable -> @element_type.type\n}\n\n\n\n;; Tuple Type\n\n; (tuple_type\n;   (_)@component_type ; commaSep\n; )@type\n\n(tuple_type)@type {\n  node @type.indexable\n\n  ; type is indexable\n  edge @type.type -> @type.indexable\n  ;\n  attr (@type.indexable) pop_symbol = \"[]\"\n}\n\n(tuple_type\n  (_)@comp_type ; commaSep\n)@type {\n  node @comp_type.comp_index\n\n  ; propagate lexical scope\n  edge @comp_type.lexical_scope -> @type.lexical_scope\n\n  ; component indexed using position\n  edge @type.indexable -> @comp_type.comp_index\n  ;\n  attr (@comp_type.comp_index) pop_symbol = (named-child-index @comp_type)\n  edge @comp_type.comp_index -> @comp_type.type\n}\n\n; (tuple_parameter\n;   [(identifier) (rest_pattern)]\n;   (type_annotation)\n; ) {}\n\n; (optional_tuple_parameter\n;   (identifier)\n;   (type_annotation)\n; ) {}\n\n; tuple components can be parameters, but require extra properties\n(tuple_type [\n  (required_parameter)\n  (optional_parameter)\n]@_tuple_param) {\n  node @_tuple_param.type\n}\n(tuple_type [\n  (required_parameter type:(_)@type)\n  (optional_parameter type:(_)@type)\n]@_tuple_param) {\n  ; component type is type annotation\n  edge @_tuple_param.type -> @type.type\n}\n\n\n\n;; Readonly Type\n\n; (readonly_type\n;   (_)@inner_type\n; )@type\n\n(readonly_type\n  (_)@inner_type\n)@type {\n  ; propagate lexical scope\n  edge @inner_type.lexical_scope -> @type.lexical_scope\n\n  ; type is type of inner\n  edge @type.type -> @inner_type.type\n}\n\n\n\n;; Union Type\n\n; (union_type\n;   (_)@left_type ; opt\n;   (_)@right_type\n; )@type\n\n(union_type\n  (_)@inner_type\n)@type {\n  ; propagate lexical scope\n  edge @inner_type.lexical_scope -> @type.lexical_scope\n\n  ; type is union of types of inner\n  edge @type.type -> @inner_type.type\n}\n\n\n\n;; Intersection Type\n\n; (intersection_type\n;   (_)@left_type ; opt\n;   (_)@right_type\n; )@type\n\n(intersection_type\n  (_)@inner_type\n)@type {\n  ; propagate lexical scope\n  edge @inner_type.lexical_scope -> @type.lexical_scope\n\n  ; type is union of types of inner (over-approximation)\n  edge @type.type -> @inner_type.type\n}\n\n\n\n;; Function Type\n\n; (function_type\n;   (type_parameters) ; opt\n;   (formal_parameters)\n;   [(_)@type (type_predicate)]\n; ) {}\n\n(function_type)@fun_type {\n  node @fun_type.callable\n  node @fun_type.callable__params\n  node @fun_type.callable__return\n\n  ; type is callable generic type\n  edge @fun_type.type -> @fun_type.callable\n  ;\n  attr (@fun_type.callable) pop_symbol = \"->\"\n  edge @fun_type.callable -> @fun_type.generic_type\n  ;\n  edge @fun_type.generic_inner_type -> @fun_type.callable__params\n  edge @fun_type.generic_inner_type -> @fun_type.callable__return\n  ;\n  attr (@fun_type.callable__return) pop_symbol = \"<return>\"\n}\n\n; type parameters are handled by generics rules below\n\n(function_type parameters:(_)@params)@fun_type {\n  ; propagate lexical scope\n  edge @params.lexical_scope -> @fun_type.generic_inner_lexical_scope\n\n  ; connect params to type\n  edge @fun_type.callable__params -> @params.params\n}\n\n(function_type return_type:(_)@return_type)@fun_type {\n  ; propagate lexical scope\n  edge @return_type.lexical_scope -> @fun_type.generic_inner_lexical_scope\n\n  ; inner type is return type\n  edge @fun_type.callable__return -> @return_type.type\n}\n\n\n\n;; Type Identifier\n\n; (type_identifier)@name\n\n; FIXME shoulds not apply if\n;       - part of nested_type_identifier\n(type_identifier)@name {\n  node @name.type_ref\n  node @name.type_ref__ns\n\n  ; type reference\n  attr (@name.type_ref) node_reference = @name\n  edge @name.type_ref -> @name.type_ref__ns\n  ;\n  attr (@name.type_ref__ns) push_symbol = \"%T\"\n  edge @name.type_ref__ns -> @name.lexical_scope\n\n  ; type is the declaration\n  edge @name.type -> @name.type_ref\n}\n\n\n\n;; Nested Type Identifier\n\n; (nested_type_identifier\n;   module:[(identifier) (nested_identifier)]\n;   name:(_)\n; ) {}\n\n[\n  ; X\n  (nested_type_identifier module:(identifier)@name)\n  ; X._\n  (nested_identifier object:(identifier)@name)\n  ; _.X._\n  (member_expression object:(identifier)@name)\n  ; _.X\n  (nested_identifier property:(_)@name)\n  ; _._.X\n  (member_expression property:(_)@name)\n] {\n  node @name.type_ref\n  attr (@name.type_ref) node_reference = @name\n\n  node @name.type_ref_member\n  attr (@name.type_ref_member) push_symbol = \".\"\n\n  edge @name.type_ref_member -> @name.type_ref\n}\n\n[\n  (nested_identifier object:(_)@mod)\n  (member_expression object:[(member_expression) (identifier)]@mod)\n]@nested {\n  node @nested.type_ref\n  edge @mod.type_ref -> @nested.type_ref\n}\n\n[\n  (nested_identifier object:(_)@mod                                property:(_)@name)\n  (member_expression object:[(member_expression) (identifier)]@mod property:(_)@name)\n] {\n  edge @name.type_ref -> @mod.type_ref_member\n}\n\n[\n  (nested_identifier property:(_)@name)\n  (member_expression property:(_)@name)\n]@nested {\n  node @nested.type_ref_member\n  edge @nested.type_ref_member -> @name.type_ref_member\n}\n\n(nested_type_identifier module:(_)@mod)@nested_type_id {\n  node type_ns\n  attr (type_ns) push_symbol = \"%T\"\n\n  edge @mod.type_ref -> type_ns\n  edge type_ns -> @nested_type_id.lexical_scope\n}\n\n(nested_type_identifier module:(_)@mod name:(_)@name)@nested_type_id {\n  edge @nested_type_id.type -> @name.type_ref\n  edge @name.type_ref -> @mod.type_ref_member\n}\n\n\n\n;; Object Type\n\n; (object_type\n;   [(export_statement)\n;    (property_signature)\n;    (call_signature)\n;    (construct_signature)\n;    (index_signature)\n;    (method_signature)]@inner\n; )@type\n\n(object_type)@type {\n  ; mark type scope as endpoint\n  attr (@type.type) is_endpoint\n}\n\n(object_type\n  (_)@inner\n)@type {\n  ; propagate lexical scope\n  edge @inner.lexical_scope -> @type.lexical_scope\n\n  ; type consist of members\n  edge @type.type -> @inner.type_members\n}\n\n\n\n;; Type Parameters\n\n; (type_parameters\n;   (type_parameter) ; commaSep1\n; ) {}\n\n(type_parameters)@type_params {\n  node @type_params.defs\n}\n\n(type_parameters\n  (_)@param\n)@type_params {\n  ; propagate lexical scope\n  edge @param.lexical_scope -> @type_params.lexical_scope\n\n  ; type definitions are visible to each other\n  edge @param.lexical_scope -> @type_params.defs\n\n  ; expose type definitions\n  edge @type_params.defs -> @param.defs\n}\n\n; (type_parameter\n;   name:(type_identifier)\n;   constraint:(constraint) ; opt\n;   value:(default_type) ; opt\n; ) {}\n\n(type_parameter\n  name:(_)@name\n)@type_param {\n  node @name.type_def\n  node @name.type_def__ns\n  node @type_param.arg_index\n  node @type_param.defs\n\n  ; type definition\n  edge @type_param.defs -> @name.type_def__ns\n  ;\n  attr (@name.type_def__ns) pop_symbol = \"%T\"\n  edge @name.type_def__ns -> @name.type_def\n  ;\n  attr (@name.type_def) node_definition = @name\n\n  ; jump from parameter to positional type argument\n  edge @name.type_def -> @type_param.arg_index\n  ;\n  attr (@type_param.arg_index) push_symbol = (named-child-index @type_param)\n  edge @type_param.arg_index -> JUMP_TO_SCOPE_NODE\n}\n\n(type_parameter\n  name:(_)@name\n  value:(_)@type ; opt\n)@type_param {\n  ; propagate lexical scope\n  edge @type.lexical_scope -> @type_param.lexical_scope\n\n  ; type of definition is default type\n  edge @name.type_def -> @type_param.alias_type\n  ;\n  ; alias guards are set up by rules below\n  ;\n  edge @type_param.aliased_type -> @type.type\n}\n\n\n\n;; Default Type\n\n(default_type\n  (_)@type\n)@def_type {\n  ; propagate lexical scope\n  edge @type.lexical_scope -> @def_type.lexical_scope\n\n  ; type is type of inner\n  edge @def_type.type -> @type.type\n}\n\n\n\n;; Type Constraint\n\n(constraint\n  (_)@type\n)@type_c {\n  ; propagate lexical scope\n  edge @type.lexical_scope -> @type_c.lexical_scope\n\n  ; type is type of inner\n  edge @type_c.type -> @type.type\n}\n\n\n\n;; This Type\n\n(this_type)@this {\n  node @this.expr_ref\n  node @this.expr_ref__ns\n\n  ; expression reference\n  attr (@this.expr_ref) symbol_reference = \"this\", source_node = @this\n  edge @this.expr_ref -> @this.expr_ref__ns\n  ;\n  attr (@this.expr_ref__ns) push_symbol = \"%T\"\n  edge @this.expr_ref__ns -> @this.lexical_scope\n\n  ; type is the definition\n  edge @this.type -> @this.expr_ref\n}\n\n\n\n;; Template literal type\n\n; (template_literal_type)\n\n(template_literal_type (_)@inner)@type {\n  ; propagate lexical scope\n  edge @inner.lexical_scope -> @type.lexical_scope\n\n  ; type is type of inner\n  edge @type.type -> @inner.type\n}\n\n\n\n;; Template type\n\n; (template_type)\n\n(template_type (_)@inner)@type {\n  ; propagate lexical scope\n  edge @inner.lexical_scope -> @type.lexical_scope\n\n  ; type is type of inner\n  edge @type.type -> @inner.type\n}\n\n\n\n;  #####\n; #     # ###### #    # ###### #####  #  ####   ####\n; #       #      ##   # #      #    # # #    # #\n; #  #### #####  # #  # #####  #    # # #       ####\n; #     # #      #  # # #      #####  # #           #\n; #     # #      #   ## #      #   #  # #    # #    #\n;  #####  ###### #    # ###### #    # #  ####   ####\n\n;; Attributes defined on generic declarations\n;\n; in .lexical_scope\n;     Scope to resolve types in.\n;\n; out .generic_inner_lexical_scope\n;     Scope for types including the type parameters.\n;\n; out .generic_type\n;     Scope representing the (possibly) generic type.\n;\n; in .generic_inner_type\n;     Scope representing the type being abstracted over.\n\n[\n  (abstract_class_declaration)\n  (abstract_method_signature)\n  (call_signature)\n  (class)\n  (class_declaration)\n  (construct_signature)\n  (constructor_type)\n  (function_declaration)\n  (function_signature)\n  (function_type)\n  (generator_function_declaration)\n  (interface_declaration)\n  (method_definition)\n  (method_signature)\n  (type_alias_declaration)\n]@gen_decl {\n  node @gen_decl.generic_inner_lexical_scope\n  node @gen_decl.generic_inner_type\n  node @gen_decl.generic_type\n}\n\n[\n  (abstract_class_declaration     !type_parameters)\n  (abstract_method_signature      !type_parameters)\n  (call_signature                 !type_parameters)\n  (class                          !type_parameters)\n  (class_declaration              !type_parameters)\n  (construct_signature            !type_parameters)\n  (constructor_type               !type_parameters)\n  (function_declaration           !type_parameters)\n  (function_signature             !type_parameters)\n  (function_type                  !type_parameters)\n  (generator_function_declaration !type_parameters)\n  (interface_declaration          !type_parameters)\n  (method_definition              !type_parameters)\n  (method_signature               !type_parameters)\n  (type_alias_declaration         !type_parameters)\n]@gen_decl {\n  ; propagate lexical scope\n  edge @gen_decl.generic_inner_lexical_scope -> @gen_decl.lexical_scope\n\n  ; type is inner type, without abstraction\n  edge @gen_decl.generic_type -> @gen_decl.generic_inner_type\n}\n[\n  (abstract_class_declaration     type_parameters:(_)@type_params)\n  (abstract_method_signature      type_parameters:(_)@type_params)\n  (call_signature                 type_parameters:(_)@type_params)\n  (class                          type_parameters:(_)@type_params)\n  (class_declaration              type_parameters:(_)@type_params)\n  (construct_signature            type_parameters:(_)@type_params)\n  (constructor_type               type_parameters:(_)@type_params)\n  (function_declaration           type_parameters:(_)@type_params)\n  (function_signature             type_parameters:(_)@type_params)\n  (function_type                  type_parameters:(_)@type_params)\n  (generator_function_declaration type_parameters:(_)@type_params)\n  (interface_declaration          type_parameters:(_)@type_params)\n  (method_definition              type_parameters:(_)@type_params)\n  (method_signature               type_parameters:(_)@type_params)\n  (type_alias_declaration         type_parameters:(_)@type_params)\n]@gen_decl {\n  node @gen_decl.drop_type_args\n  node @gen_decl.drop_type_abs\n  node @gen_decl.type_abs\n\n  ; propagate lexical scope for parameters\n  edge @type_params.lexical_scope -> @gen_decl.lexical_scope\n\n  ; propagate lexical inner scope, dropping type arguments\n  edge @gen_decl.generic_inner_lexical_scope -> @gen_decl.drop_type_args\n  ;\n  attr (@gen_decl.drop_type_args) type = \"drop_scopes\"\n  edge @gen_decl.drop_type_args -> @gen_decl.lexical_scope\n\n  ; inner lexical scope includes type definitions\n  edge @gen_decl.generic_inner_lexical_scope -> @type_params.defs\n  attr (@gen_decl.generic_inner_lexical_scope -> @type_params.defs) precedence = 1\n\n  ; generic type is abstraction over inner type\n  edge @gen_decl.generic_type -> @gen_decl.type_abs\n  ;\n  attr (@gen_decl.type_abs) pop_scoped_symbol = \"<>\"\n  edge @gen_decl.type_abs -> @gen_decl.generic_inner_type\n}\n\n;; Attributes defined on generic applications\n;\n; in .lexical_scope\n;     Scope to resolve types in.\n;\n; out .applied_type\n;     Application of the generic type.\n;\n; in .generic_type\n;     Generic type to be applied.\n\n[\n  (call_expression)\n  (new_expression)\n  (generic_type)\n]@gen_expr {\n  node @gen_expr.applied_type\n  node @gen_expr.generic_type\n}\n\n[\n  (call_expression !type_arguments)\n  (new_expression  !type_arguments)\n]@gen_expr {\n  ; direct edge for non-generic functions\n  edge @gen_expr.applied_type -> @gen_expr.generic_type\n}\n\n[\n  (call_expression !type_arguments)\n  (new_expression  !type_arguments)\n]@gen_expr {\n  node @gen_expr.type_app\n  node @gen_expr.inferred_type_args\n  attr (@gen_expr.inferred_type_args) is_exported\n\n  ; push inferred type arguments\n  edge @gen_expr.applied_type -> @gen_expr.type_app\n  ;\n  attr (@gen_expr.type_app) push_scoped_symbol = \"<>\", scope = @gen_expr.inferred_type_args\n  edge @gen_expr.type_app -> @gen_expr.generic_type\n\n  ; FIXME infer type arguments\n}\n\n[\n  (call_expression type_arguments:(_)@type_args)\n  (new_expression  type_arguments:(_)@type_args)\n  (generic_type    type_arguments:(_)@type_args)\n]@gen_expr {\n  node @gen_expr.type_app\n\n  ; propagate lexical scope\n  edge @type_args.lexical_scope -> @gen_expr.lexical_scope\n\n  ; push given type arguments\n  edge @gen_expr.applied_type -> @gen_expr.type_app\n  ;\n  attr (@gen_expr.type_app) push_scoped_symbol = \"<>\", scope = @type_args.type_args\n  edge @gen_expr.type_app -> @gen_expr.generic_type\n}\n\n\n\n;    #\n;   # #   #      #   ##    ####  ######  ####\n;  #   #  #      #  #  #  #      #      #\n; #     # #      # #    #  ####  #####   ####\n; ####### #      # ######      # #           #\n; #     # #      # #    # #    # #      #    #\n; #     # ###### # #    #  ####  ######  ####\n\n; Attributes defined on type aliases\n;\n; out .alias_type\n;     Type with alias guards in place.\n;\n; in .aliased_type\n;     Type to be aliased.\n\n[\n  (extends_clause)\n  (extends_type_clause)\n  (implements_clause)\n  (type_alias_declaration)\n  (type_parameter)\n]@alias {\n  node @alias.alias_type\n  node @alias.alias_type__callable_pop\n  node @alias.alias_type__callable_push\n  node @alias.alias_type__ctor_pop\n  node @alias.alias_type__ctor_push\n  node @alias.alias_type__indexable_pop\n  node @alias.alias_type__indexable_push\n  node @alias.alias_type__member_pop\n  node @alias.alias_type__member_push\n  node @alias.aliased_type\n\n  ; alias members\n  edge @alias.alias_type -> @alias.alias_type__member_pop\n  ;\n  attr (@alias.alias_type__member_pop) pop_symbol = \".\"\n  edge @alias.alias_type__member_pop -> @alias.alias_type__member_push\n  ;\n  attr (@alias.alias_type__member_push) push_symbol = \".\"\n  edge @alias.alias_type__member_push -> @alias.aliased_type\n\n  ; alias callable\n  edge @alias.alias_type -> @alias.alias_type__callable_pop\n  ;\n  attr (@alias.alias_type__callable_pop) pop_symbol = \"->\"\n  edge @alias.alias_type__callable_pop -> @alias.alias_type__callable_push\n  ;\n  attr (@alias.alias_type__callable_push) push_symbol = \"->\"\n  edge @alias.alias_type__callable_push -> @alias.aliased_type\n\n  ; alias indexable\n  edge @alias.alias_type -> @alias.alias_type__indexable_pop\n  ;\n  attr (@alias.alias_type__indexable_pop) pop_symbol = \"[]\"\n  edge @alias.alias_type__indexable_pop -> @alias.alias_type__indexable_push\n  ;\n  attr (@alias.alias_type__indexable_push) push_symbol = \"[]\"\n  edge @alias.alias_type__indexable_push -> @alias.aliased_type\n\n  ; alias constructors\n  edge @alias.alias_type -> @alias.alias_type__ctor_pop\n  ;\n  attr (@alias.alias_type__ctor_pop) pop_symbol = \"<new>\"\n  edge @alias.alias_type__ctor_pop -> @alias.alias_type__ctor_push\n  ;\n  attr (@alias.alias_type__ctor_push) push_symbol = \"<new>\"\n  edge @alias.alias_type__ctor_push -> @alias.aliased_type\n}\n\n; Attributes defined on expr aliases\n;\n; out .alias_expr\n;     Type with alias guards in place.\n;\n; in .aliased_expr\n;     Type to be aliased.\n\n; [\n; ]@alias {\n;   ; type of expression\n;   edge @alias.alias_expr -> @alias.alias_expr__typeof\n;   ;\n;   attr (@alias.alias_expr__typeof) pop_symbol = \":\"\n\n;   ; alias members\n;   edge @alias.alias_expr__typeof -> @alias.alias_expr__member_pop\n;   ;\n;   attr (@alias.alias_expr__member_pop) pop_symbol = \".\"\n;   edge @alias.alias_expr__member_pop -> @alias.alias_expr__member_push\n;   ;\n;   attr (@alias.alias_expr__member_push) push_symbol = \".\"\n;   edge @alias.alias_expr__member_push -> @alias.aliased_expr__typeof\n\n;   ; alias callable\n;   edge @alias.alias_expr__typeof -> @alias.alias_expr__callable_pop\n;   ;\n;   attr (@alias.alias_expr__callable_pop) pop_symbol = \"->\"\n;   edge @alias.alias_expr__callable_pop -> @alias.alias_expr__callable_push\n;   ;\n;   attr (@alias.alias_expr__callable_push) push_symbol = \"->\"\n;   edge @alias.alias_expr__callable_push -> @alias.aliased_expr__typeof\n\n;   ; alias indexable\n;   edge @alias.alias_expr__typeof -> @alias.alias_expr__indexable_pop\n;   ;\n;   attr (@alias.alias_expr__indexable_pop) pop_symbol = \"[]\"\n;   edge @alias.alias_expr__indexable_pop -> @alias.alias_expr__indexable_push\n;   ;\n;   attr (@alias.alias_expr__indexable_push) push_symbol = \"[]\"\n;   edge @alias.alias_expr__indexable_push -> @alias.aliased_expr__typeof\n\n;   ; alias constructors\n;   edge @alias.alias_expr__typeof -> @alias.alias_expr__ctor_pop\n;   ;\n;   attr (@alias.alias_expr__ctor_pop) pop_symbol = \"<new>\"\n;   edge @alias.alias_expr__ctor_pop -> @alias.alias_expr__ctor_push\n;   ;\n;   attr (@alias.alias_expr__ctor_push) push_symbol = \"<new>\"\n;   edge @alias.alias_expr__ctor_push -> @alias.aliased_expr__typeof\n\n;   ; type of target\n;   attr (@alias.aliased_expr__typeof) push_symbol = \":\"\n;   edge @alias.aliased_expr__typeof -> @alias.aliased_expr\n; }\n\n\n\n;\n;    #                                        #       #\n;   # #    ####  #   # #    #  ####          #       # #   #    #   ##   # #####\n;  #   #  #       # #  ##   # #    #        #       #   #  #    #  #  #  #   #\n; #     #  ####    #   # #  # #            #       #     # #    # #    # #   #\n; #######      #   #   #  # # #           #        ####### # ## # ###### #   #\n; #     # #    #   #   #   ## #    #     #         #     # ##  ## #    # #   #\n; #     #  ####    #   #    #  ####     #          #     # #    # #    # #   #\n;\n\n; Attributes defined on await:\n;\n; in .async_type\n;   The async type being awaiting.\n;\n; out .await_type\n;   The type of the result of awaiting.\n\n[\n  (await_expression)\n]@await {\n  node @await.async_type\n  node @await.await_type\n  node @await.await_type__member\n  node @await.await_type__ref\n  node @await.await_type__typeof\n\n  ; type is the internal $Promise$T member of the promise type\n  edge @await.await_type -> @await.await_type__typeof\n  ;\n  attr (@await.await_type__typeof) push_symbol = \":\"\n  edge @await.await_type__typeof -> @await.await_type__ref\n  ;\n  attr (@await.await_type__ref) push_symbol = \"$Promise$T\"\n  edge @await.await_type__ref -> @await.await_type__member\n  ;\n  attr (@await.await_type__member) push_symbol = \".\"\n  edge @await.await_type__member -> @await.async_type\n}\n\n; Attributes defined on async:\n;\n; out .async_type\n;   The async type being returned.\n;\n; out .await_type\n;   The type of the result of awaiting.\n\n[\n  (arrow_function                 \"async\")\n  (function_expression            \"async\")\n  (function_declaration           \"async\")\n  (generator_function             \"async\")\n  (generator_function_declaration \"async\")\n  (method_definition              \"async\")\n]@async {\n  node @async.async_type\n  node @async.async_type__type_app\n  node @async.async_type__type_arg\n  node @async.async_type__type_args\n  attr (@async.async_type__type_args) is_exported\n  node @async.async_type__promise_ref\n  node @async.async_type__promise_ref__ns\n  node @async.await_type\n  node @async.await_type__member\n  node @async.await_type__ref\n  node @async.await_type__typeof\n\n  ; type arguments\n  edge @async.async_type__type_args -> @async.async_type__type_arg\n  ;\n  attr (@async.async_type__type_arg) pop_symbol = 0\n  edge @async.async_type__type_arg -> @async.await_type\n\n  ; type is applied Promise\n  edge @async.async_type -> @async.async_type__type_app\n  ;\n  attr (@async.async_type__type_app) push_scoped_symbol = \"<>\", scope = @async.async_type__type_args\n  edge @async.async_type__type_app -> @async.async_type__promise_ref\n  ;\n  attr (@async.async_type__promise_ref) symbol_reference = \"Promise\", source_node = @async, empty_source_span\n  edge @async.async_type__promise_ref -> @async.async_type__promise_ref__ns\n  ;\n  attr (@async.async_type__promise_ref__ns) push_symbol = \"%T\"\n  edge @async.async_type__promise_ref__ns -> @async.lexical_scope\n}\n\n;\n;       #  #####  #     #\n;       # #     #  #   #\n;       # #         # #\n;       #  #####     #\n; #     #       #   # #\n; #     # #     #  #   #\n;  #####   #####  #     #\n;\n; ;;;;;;;;;;;;;;;;;;;;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n; ;;;;;;;;;;;;;;;;;;;;\n";
Expand description

The stack graphs tsg source for this language