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