From 0afdd2a04ba9382cee780e9c77aa4eea56bb85b4 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Mon, 9 Oct 2023 16:25:38 +0200 Subject: [PATCH 01/46] Adds missing syntax types Co-authored-by: Rebecca Valentine --- .../tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index 600c77376..90e593b0d 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -4025,6 +4025,7 @@ inherit .return_or_yield ]@right)@assignment_expr { attr (@assignment_expr.pop) definiens_node = @right + attr (@assignment_expr.pop) syntax_type = "function" } @@ -4042,6 +4043,7 @@ inherit .return_or_yield attr (left_ignore_guard) pop_symbol = "GUARD:GANDALF" attr (left_definiens_hook) node_definition = @left attr (left_definiens_hook) definiens_node = @right + attr (left_definiens_hook) syntax_type = "function" edge @assignment_expr.pkg_pop -> left_ignore_guard edge left_ignore_guard -> left_definiens_hook } @@ -4056,6 +4058,7 @@ inherit .return_or_yield ]@initializer)) { attr (@name.pop) definiens_node = @initializer + attr (@name.pop) syntax_type = "function" } @@ -4069,6 +4072,7 @@ inherit .return_or_yield ]@initializer)) { attr (@name.pop) definiens_node = @initializer + attr (@name.pop) syntax_type = "function" } @@ -4086,6 +4090,7 @@ inherit .return_or_yield attr (name_ignore_guard) pop_symbol = "GUARD:GANDALF" attr (name_definiens_hook) node_definition = @name attr (name_definiens_hook) definiens_node = @value + attr (name_definiens_hook) syntax_type = "function" edge @pair_expr.pkg_pop -> name_ignore_guard edge name_ignore_guard -> name_definiens_hook From a352c39c59d88b4c6ac9508bfdf41f07c4f3c248 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Mon, 9 Oct 2023 17:55:26 +0200 Subject: [PATCH 02/46] Adds class to definiens rules for assignments etc Co-authored-by: Rebecca Valentine --- .../tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index 90e593b0d..9d55380d9 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -4022,6 +4022,7 @@ inherit .return_or_yield (function) (generator_function) (arrow_function) + (class) ]@right)@assignment_expr { attr (@assignment_expr.pop) definiens_node = @right @@ -4035,6 +4036,7 @@ inherit .return_or_yield (function) (generator_function) (arrow_function) + (class) ]@right)@assignment_expr { node left_definiens_hook @@ -4055,6 +4057,7 @@ inherit .return_or_yield (function) (generator_function) (arrow_function) + (class) ]@initializer)) { attr (@name.pop) definiens_node = @initializer @@ -4069,6 +4072,7 @@ inherit .return_or_yield (function) (generator_function) (arrow_function) + (class) ]@initializer)) { attr (@name.pop) definiens_node = @initializer @@ -4082,6 +4086,7 @@ inherit .return_or_yield (function) (generator_function) (arrow_function) + (class) ]@value)@pair_expr { node name_definiens_hook From 46dde3eef9a0c9fb759d89ea6afa77dfbffecfd0 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Mon, 9 Oct 2023 17:57:24 +0200 Subject: [PATCH 03/46] Excludes CommonJS exports from definiens Co-authored-by: Rebecca Valentine --- .../src/stack-graphs.tsg | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index 9d55380d9..b3cc547bc 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -4030,14 +4030,20 @@ inherit .return_or_yield } -(assignment_expression - left: (member_expression property:(_)@left) - right: [ - (function) - (generator_function) - (arrow_function) - (class) - ]@right)@assignment_expr { +( + (assignment_expression + left: (member_expression + object:(identifier)@_object + property:(_)@left + ) + right: [ + (function) + (generator_function) + (arrow_function) + ]@right)@assignment_expr + (#not-eq @_object "module") + (#not-eq @left "exports") +) { node left_definiens_hook node left_ignore_guard From e53474a1ff09d1c129025bb2c360333f70672a22 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Mon, 9 Oct 2023 18:24:31 +0200 Subject: [PATCH 04/46] Adds test case and fix Co-authored-by: Rebecca Valentine --- .../src/stack-graphs.tsg | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index b3cc547bc..8f22cdf7c 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -3838,7 +3838,7 @@ inherit .return_or_yield ;; ## ES6-style Imports ;; ES6 modules can also be imported using an import function. In general, -;; these look like `require(expr)`, but in practice the expression is a string +;; these look like `import(expr)`, but in practice the expression is a string ;; constant, which is the only case we handle. ( @@ -3881,11 +3881,15 @@ inherit .return_or_yield (#eq? @_exports "exports") ) { + node property_pop node property_pop_dot attr (property_pop) node_definition = @property attr (property_pop_dot) pop_symbol = "GUARD:MEMBER" - edge @assignment_expr.exports -> property_pop_dot + node assignment_expr_guard_default + attr (assignment_expr_guard_default) pop_symbol = "GUARD:DEFAULT" + edge assignment_expr_guard_default -> property_pop_dot + edge @assignment_expr.exports -> assignment_expr_guard_default edge property_pop_dot -> property_pop edge property_pop -> @right.value } @@ -3893,14 +3897,17 @@ inherit .return_or_yield ( (assignment_expression left: (member_expression - object:(identifier)@_module + object:(_)@_module property:(_)@_exports) right: (_)@right)@assignment_expr (#eq? @_module "module") (#eq? @_exports "exports") ) { - edge @assignment_expr.exports -> @right.value + node assignment_expr_guard_default + attr (assignment_expr_guard_default) pop_symbol = "GUARD:DEFAULT" + edge assignment_expr_guard_default -> @right.value + edge @assignment_expr.exports -> assignment_expr_guard_default } ;; ## CommonJS-style Imports @@ -3915,7 +3922,11 @@ inherit .return_or_yield arguments:(arguments (string)@source))@call_expr (#eq? @_require "require") ) { - edge @call_expr.value -> @source.exports + + node require_guard_default + attr (require_guard_default) push_symbol = "GUARD:DEFAULT" + edge require_guard_default -> @source.exports + edge @call_expr.value -> require_guard_default } From f3bb1d80345275f6b1c1cf2bedd6e89c23f2eef5 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Mon, 9 Oct 2023 18:27:05 +0200 Subject: [PATCH 05/46] Fix test assertion --- .../test/statements/for_statement.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/languages/tree-sitter-stack-graphs-javascript/test/statements/for_statement.js b/languages/tree-sitter-stack-graphs-javascript/test/statements/for_statement.js index 7a1f8b29f..7cdc5e19f 100644 --- a/languages/tree-sitter-stack-graphs-javascript/test/statements/for_statement.js +++ b/languages/tree-sitter-stack-graphs-javascript/test/statements/for_statement.js @@ -28,4 +28,4 @@ for (let y = (x, 1); // Flow around /**/ x; -// ^ defined 1 \ No newline at end of file +// ^ defined: 1 \ No newline at end of file From 0ffa7b4587d7bcc3b439280a06fe2fe28a512774 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Mon, 9 Oct 2023 18:42:48 +0200 Subject: [PATCH 06/46] Adds fix for default CommonJS default imports Co-authored-by: Rebecca Valentine --- .../src/stack-graphs.tsg | 21 +++++++++---------- ..._default_export_with_ES6_default_import.js | 12 +++++++++++ .../CommonJS_default_import_of_functions.js | 15 +++++++++++++ 3 files changed, 37 insertions(+), 11 deletions(-) create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/CommonJS_default_export_with_ES6_default_import.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/CommonJS_default_import_of_functions.js diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index 8f22cdf7c..c5822999f 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -747,10 +747,13 @@ inherit .return_or_yield ] { node source_push_guard_exports + node source_push_guard_default node source_push_guard_pkg node @source.exports attr (source_push_guard_exports) push_symbol = "GUARD:EXPORTS" + attr (source_push_guard_default) push_symbol = "GUARD:DEFAULT" + edge source_push_guard_default -> source_push_guard_exports scan (source-text @source) { "^[\"']((\.|\.\.)/.*)[\"']$" { @@ -781,6 +784,7 @@ inherit .return_or_yield attr (push_start) is_reference, source_node = @source edge @source.exports -> source_push_guard_exports + edge @source.exports -> source_push_guard_default edge source_push_guard_exports -> push_start edge source_push_end -> @source.pkg_push } @@ -803,6 +807,7 @@ inherit .return_or_yield } edge @source.exports -> source_push_guard_exports + edge @source.exports -> source_push_guard_default edge source_push_guard_exports -> push_start edge source_push_end -> source_push_guard_pkg attr (source_push_guard_pkg) push_symbol = "GUARD:PKG" @@ -3886,10 +3891,7 @@ inherit .return_or_yield node property_pop_dot attr (property_pop) node_definition = @property attr (property_pop_dot) pop_symbol = "GUARD:MEMBER" - node assignment_expr_guard_default - attr (assignment_expr_guard_default) pop_symbol = "GUARD:DEFAULT" - edge assignment_expr_guard_default -> property_pop_dot - edge @assignment_expr.exports -> assignment_expr_guard_default + edge @assignment_expr.exports -> property_pop_dot edge property_pop_dot -> property_pop edge property_pop -> @right.value } @@ -3898,14 +3900,14 @@ inherit .return_or_yield (assignment_expression left: (member_expression object:(_)@_module - property:(_)@_exports) + property:(_)@exports) right: (_)@right)@assignment_expr (#eq? @_module "module") - (#eq? @_exports "exports") + (#eq? @exports "exports") ) { node assignment_expr_guard_default - attr (assignment_expr_guard_default) pop_symbol = "GUARD:DEFAULT" + attr (assignment_expr_guard_default) symbol_definition = "GUARD:DEFAULT", source_node = @exports edge assignment_expr_guard_default -> @right.value edge @assignment_expr.exports -> assignment_expr_guard_default } @@ -3923,10 +3925,7 @@ inherit .return_or_yield (#eq? @_require "require") ) { - node require_guard_default - attr (require_guard_default) push_symbol = "GUARD:DEFAULT" - edge require_guard_default -> @source.exports - edge @call_expr.value -> require_guard_default + edge @call_expr.value -> @source.exports } diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/CommonJS_default_export_with_ES6_default_import.js b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/CommonJS_default_export_with_ES6_default_import.js new file mode 100644 index 000000000..5cecaa6f4 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/CommonJS_default_export_with_ES6_default_import.js @@ -0,0 +1,12 @@ +/*--- path: a.js ---*/ + +const f = 5; + +module.exports = f; + +/*--- path: b.js ---*/ + +import g from './a.js'; + +/**/ g; +// ^ defined: 3, 5, 9 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/CommonJS_default_import_of_functions.js b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/CommonJS_default_import_of_functions.js new file mode 100644 index 000000000..62f351e66 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/CommonJS_default_import_of_functions.js @@ -0,0 +1,15 @@ +/*--- path: a.js ---*/ +module.exports = function () { + +}; + +/*--- path: b.js ---*/ +let mod = require("./a.js"); + +/**/ mod; +// ^ defined: 2, 7 + +class Quux { + bar() { + } +} From 1bce68795d94db34dfec41d944fe972b3abfb789 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Mon, 9 Oct 2023 21:10:27 +0200 Subject: [PATCH 07/46] Adds current versions of tests, etc. Co-authored-by: Rebecca Valentine --- .../src/stack-graphs.tsg | 158 +++++++++--------- .../name_default_alias_default.js | 14 ++ .../name_default_alias_nondefault.js | 14 ++ .../name_nondefault_alias_default.js | 14 ++ .../unaliased_name_default.js | 14 ++ 5 files changed, 136 insertions(+), 78 deletions(-) create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_exports_using_the_name_or_alias_default/name_default_alias_default.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_exports_using_the_name_or_alias_default/name_default_alias_nondefault.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_exports_using_the_name_or_alias_default/name_nondefault_alias_default.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_exports_using_the_name_or_alias_default/unaliased_name_default.js diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index c5822999f..b3f16d696 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -576,82 +576,77 @@ inherit .return_or_yield } +; export { default } from ... +; export { default as ... } from ... ( (export_specifier name:(_)@name - !alias)@export_specifier + )@export_specifier (#not-eq? @name "default") ) { - node name_pop node name_push - - attr (name_pop) node_definition = @name attr (name_push) node_reference = @name - edge name_pop -> name_push + edge @export_specifier.pop -> name_push edge name_push -> @export_specifier.source - edge @export_specifier.exports -> name_pop } +; export { foo } from ... +; export { foo as ... } from ... ( (export_specifier name:(_)@name - alias:(_)@alias)@export_specifier - - (#not-eq? @alias "default") + )@export_specifier + (#eq? @name "default") ) { - node alias_pop - node name_push - - attr (alias_pop) node_definition = @alias - attr (name_push) node_reference = @name - edge alias_pop -> name_push - edge name_push -> @export_specifier.source + node export_specifier_push_guard_default + attr (export_specifier_push_guard_default) symbol_reference = "GUARD:DEFAULT", source_node = @name + edge @export_specifier.pop -> export_specifier_push_guard_default + edge export_specifier_push_guard_default -> @export_specifier.source - edge @export_specifier.exports -> alias_pop } -( - (export_specifier - name:(_)@name - !alias)@export_specifier - - (#eq? @name "default") +; export { foo } from ... +; export { ... as foo } from ... +( [ + (export_specifier + name:(_)@alias + !alias)@export_specifier + (export_specifier + name:(_) + alias:(_)@alias)@export_specifier + ] + (#not-eq? @alias "default") ) { - node export_specifier_pop_guard_default - node export_specifier_push_guard_default - - attr (export_specifier_pop_guard_default) symbol_definition = "GUARD:DEFAULT", source_node = @name - attr (export_specifier_push_guard_default) symbol_reference = "GUARD:DEFAULT", source_node = @name - edge @export_specifier.exports -> export_specifier_pop_guard_default - edge export_specifier_pop_guard_default -> export_specifier_push_guard_default - edge export_specifier_push_guard_default -> @export_specifier.source + node @export_specifier.pop + attr (@export_specifier.pop) node_definition = @alias + edge @export_specifier.exports -> @export_specifier.pop } -( - (export_specifier - name:(_)@name - alias:(_)@alias)@export_specifier +; export { default } from ... +; export { ... as default } from ... +( [ + (export_specifier + name:(_)@alias + !alias)@export_specifier + (export_specifier + name:(_) + alias:(_)@alias)@export_specifier + ] (#eq? @alias "default") - ) { - node export_specifier_guard_default - node name_push - - attr (name_push) push_node = @name - attr (export_specifier_guard_default) symbol_definition = "GUARD:DEFAULT", source_node = @alias - edge name_push -> @export_specifier.source - edge export_specifier_guard_default -> name_push - edge @export_specifier.exports -> export_specifier_guard_default + node @export_specifier.pop + attr (@export_specifier.pop) symbol_definition = "GUARD:DEFAULT", source_node = @alias + edge @export_specifier.exports -> @export_specifier.pop } @@ -747,13 +742,10 @@ inherit .return_or_yield ] { node source_push_guard_exports - node source_push_guard_default node source_push_guard_pkg node @source.exports attr (source_push_guard_exports) push_symbol = "GUARD:EXPORTS" - attr (source_push_guard_default) push_symbol = "GUARD:DEFAULT" - edge source_push_guard_default -> source_push_guard_exports scan (source-text @source) { "^[\"']((\.|\.\.)/.*)[\"']$" { @@ -784,7 +776,6 @@ inherit .return_or_yield attr (push_start) is_reference, source_node = @source edge @source.exports -> source_push_guard_exports - edge @source.exports -> source_push_guard_default edge source_push_guard_exports -> push_start edge source_push_end -> @source.pkg_push } @@ -807,7 +798,6 @@ inherit .return_or_yield } edge @source.exports -> source_push_guard_exports - edge @source.exports -> source_push_guard_default edge source_push_guard_exports -> push_start edge source_push_end -> source_push_guard_pkg attr (source_push_guard_pkg) push_symbol = "GUARD:PKG" @@ -3109,6 +3099,8 @@ inherit .return_or_yield attr (@assignment_expr.pop) node_definition = @left edge @assignment_expr.after_scope -> @assignment_expr.pop edge @assignment_expr.pop -> @right.value + + ; ensure the scope flows through the identifier edge @assignment_expr.after_scope -> @right.after_scope } @@ -3840,26 +3832,6 @@ inherit .return_or_yield } -;; ## ES6-style Imports - -;; ES6 modules can also be imported using an import function. In general, -;; these look like `import(expr)`, but in practice the expression is a string -;; constant, which is the only case we handle. - -( - (call_expression - function:(_)@_import - arguments:(arguments (string)@source))@call_expr - (#eq? @_import "import") -) { - - node call_expr_pop_dot - - attr (call_expr_pop_dot) pop_symbol = "GUARD:MEMBER" - edge @call_expr.value -> call_expr_pop_dot - edge call_expr_pop_dot -> @source.exports -} - ;; ### CommonJS-style Exports ;; CommonJS introduced an export style for pre-ES6 JavaScript that permitted @@ -3880,20 +3852,24 @@ inherit .return_or_yield ( (assignment_expression left: (member_expression - object:(identifier)@_exports + object:(identifier)@exports property:(_)@property) right: (_)@right)@assignment_expr - (#eq? @_exports "exports") + (#eq? @exports "exports") ) { - node property_pop node property_pop_dot + node assignment_expr_guard_default + attr (property_pop) node_definition = @property attr (property_pop_dot) pop_symbol = "GUARD:MEMBER" - edge @assignment_expr.exports -> property_pop_dot - edge property_pop_dot -> property_pop edge property_pop -> @right.value + edge property_pop_dot -> property_pop + attr (assignment_expr_guard_default) symbol_definition = "GUARD:DEFAULT", source_node = @exports + edge assignment_expr_guard_default -> property_pop_dot + edge @assignment_expr.exports -> assignment_expr_guard_default + } ( @@ -3907,25 +3883,51 @@ inherit .return_or_yield ) { node assignment_expr_guard_default + attr (assignment_expr_guard_default) symbol_definition = "GUARD:DEFAULT", source_node = @exports edge assignment_expr_guard_default -> @right.value edge @assignment_expr.exports -> assignment_expr_guard_default + edge @assignment_expr.exports -> @right.value + +} + +;; ## ES6-style Imports + +;; ES6 modules can also be imported using an import function. In general, +;; these look like `import(expr)`, but in practice the expression is a string +;; constant, which is the only case we handle. + +( + (call_expression + function:(_)@_import + arguments:(arguments (string)@source))@call_expr + (#eq? @_import "import") +) { + + node call_expr_pop_dot + + attr (call_expr_pop_dot) pop_symbol = "GUARD:MEMBER" + edge @call_expr.value -> call_expr_pop_dot + edge call_expr_pop_dot -> @source.exports } ;; ## CommonJS-style Imports ;; Similar to exports, CommonJS also defines a way to do imports. In general, ;; these look like `require(expr)`, but in practice the expression is a string -;; constant, which is the only case we hand. +;; constant, which is the only case we handle. ( (call_expression - function:(_)@_require + function:(_)@require arguments:(arguments (string)@source))@call_expr - (#eq? @_require "require") + (#eq? @require "require") ) { - edge @call_expr.value -> @source.exports + node default_guard_push + attr (default_guard_push) symbol_reference = "GUARD:DEFAULT", source_node = @require + edge @call_expr.value -> default_guard_push + edge default_guard_push -> @source.exports } diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_exports_using_the_name_or_alias_default/name_default_alias_default.js b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_exports_using_the_name_or_alias_default/name_default_alias_default.js new file mode 100644 index 000000000..9febf034b --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_exports_using_the_name_or_alias_default/name_default_alias_default.js @@ -0,0 +1,14 @@ +/*--- path: a.js ---*/ + +export default 1; + +/*--- path: b.js ---*/ + +export { default as default } from "./a.js"; + +/*--- path: c.js ---*/ + +import foo from "./b.js"; + +/**/ foo; +// ^ defined: 3, 7, 11 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_exports_using_the_name_or_alias_default/name_default_alias_nondefault.js b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_exports_using_the_name_or_alias_default/name_default_alias_nondefault.js new file mode 100644 index 000000000..108abcf58 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_exports_using_the_name_or_alias_default/name_default_alias_nondefault.js @@ -0,0 +1,14 @@ +/*--- path: a.js ---*/ + +export default 1; + +/*--- path: b.js ---*/ + +export { default as foo } from "./a.js"; + +/*--- path: c.js ---*/ + +import { foo } from "./b.js"; + +/**/ foo; +// ^ defined: 3, 7, 11 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_exports_using_the_name_or_alias_default/name_nondefault_alias_default.js b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_exports_using_the_name_or_alias_default/name_nondefault_alias_default.js new file mode 100644 index 000000000..3af922d65 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_exports_using_the_name_or_alias_default/name_nondefault_alias_default.js @@ -0,0 +1,14 @@ +/*--- path: a.js ---*/ + +export let foo = 1; + +/*--- path: b.js ---*/ + +export { foo as default } from "./a.js"; + +/*--- path: c.js ---*/ + +import bar from "./b.js"; + +/**/ bar; +// ^ defined: 3, 7, 11 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_exports_using_the_name_or_alias_default/unaliased_name_default.js b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_exports_using_the_name_or_alias_default/unaliased_name_default.js new file mode 100644 index 000000000..7f4853703 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_exports_using_the_name_or_alias_default/unaliased_name_default.js @@ -0,0 +1,14 @@ +/*--- path: a.js ---*/ + +export default 1; + +/*--- path: b.js ---*/ + +export { default } from "./a.js"; + +/*--- path: c.js ---*/ + +import foo from "./b.js"; + +/**/ foo; +// ^ defined: 3, 7, 11 From 5e978ce400188d52b66e62822fafc4ae19d0bfd7 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Tue, 10 Oct 2023 11:03:58 +0200 Subject: [PATCH 08/46] Reorgs Co-authored-by: Rebecca Valentine --- .../name_default_alias_default.js | 0 .../name_default_alias_nondefault.js | 0 .../name_nondefault_alias_default.js | 0 .../unaliased_name_default.js | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/{ES6_exports_using_the_name_or_alias_default => ES6_imports_and_exports_using_the_name_or_alias_default}/name_default_alias_default.js (100%) rename languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/{ES6_exports_using_the_name_or_alias_default => ES6_imports_and_exports_using_the_name_or_alias_default}/name_default_alias_nondefault.js (100%) rename languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/{ES6_exports_using_the_name_or_alias_default => ES6_imports_and_exports_using_the_name_or_alias_default}/name_nondefault_alias_default.js (100%) rename languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/{ES6_exports_using_the_name_or_alias_default => ES6_imports_and_exports_using_the_name_or_alias_default}/unaliased_name_default.js (100%) diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_exports_using_the_name_or_alias_default/name_default_alias_default.js b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/name_default_alias_default.js similarity index 100% rename from languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_exports_using_the_name_or_alias_default/name_default_alias_default.js rename to languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/name_default_alias_default.js diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_exports_using_the_name_or_alias_default/name_default_alias_nondefault.js b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/name_default_alias_nondefault.js similarity index 100% rename from languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_exports_using_the_name_or_alias_default/name_default_alias_nondefault.js rename to languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/name_default_alias_nondefault.js diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_exports_using_the_name_or_alias_default/name_nondefault_alias_default.js b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/name_nondefault_alias_default.js similarity index 100% rename from languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_exports_using_the_name_or_alias_default/name_nondefault_alias_default.js rename to languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/name_nondefault_alias_default.js diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_exports_using_the_name_or_alias_default/unaliased_name_default.js b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/unaliased_name_default.js similarity index 100% rename from languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_exports_using_the_name_or_alias_default/unaliased_name_default.js rename to languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/unaliased_name_default.js From 664772ed8e815830180f887f4aafac3c2123b2a2 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Tue, 10 Oct 2023 11:15:04 +0200 Subject: [PATCH 09/46] Reorg (cont.) Co-authored-by: Rebecca Valentine --- ...alias_default.js => export_with_name_default_alias_default.js} | 0 ...nondefault.js => export_with_name_default_alias_nondefault.js} | 0 ...as_default.js => export_with_name_nondefault_alias_default.js} | 0 ...ased_name_default.js => export_with_unaliased_name_default.js} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/{name_default_alias_default.js => export_with_name_default_alias_default.js} (100%) rename languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/{name_default_alias_nondefault.js => export_with_name_default_alias_nondefault.js} (100%) rename languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/{name_nondefault_alias_default.js => export_with_name_nondefault_alias_default.js} (100%) rename languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/{unaliased_name_default.js => export_with_unaliased_name_default.js} (100%) diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/name_default_alias_default.js b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/export_with_name_default_alias_default.js similarity index 100% rename from languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/name_default_alias_default.js rename to languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/export_with_name_default_alias_default.js diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/name_default_alias_nondefault.js b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/export_with_name_default_alias_nondefault.js similarity index 100% rename from languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/name_default_alias_nondefault.js rename to languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/export_with_name_default_alias_nondefault.js diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/name_nondefault_alias_default.js b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/export_with_name_nondefault_alias_default.js similarity index 100% rename from languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/name_nondefault_alias_default.js rename to languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/export_with_name_nondefault_alias_default.js diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/unaliased_name_default.js b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/export_with_unaliased_name_default.js similarity index 100% rename from languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/unaliased_name_default.js rename to languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/export_with_unaliased_name_default.js From ecba922a5b9cbb93b4c039ba1d6ff6704b53ad33 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Tue, 10 Oct 2023 11:34:26 +0200 Subject: [PATCH 10/46] Adds default import test & Fixes bugs Co-authored-by: Rebecca Valentine --- .../src/stack-graphs.tsg | 70 ++++++++++++------- .../export_with_name_default_alias_default.js | 4 +- ...port_with_name_default_alias_nondefault.js | 10 +++ 3 files changed, 58 insertions(+), 26 deletions(-) create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/import_with_name_default_alias_nondefault.js diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index b3f16d696..3bfd69b77 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -917,54 +917,76 @@ inherit .return_or_yield node @import_specifier.after_scope node @import_specifier.before_scope node @import_specifier.source + + edge @import_specifier.after_scope -> @import_specifier.before_scope } ( - (import_specifier name:(_)@name - !alias)@import_specifier + )@import_specifier (#not-eq? @name "default") - ) { - node name_pop - node name_push - - edge @import_specifier.after_scope -> @import_specifier.before_scope + node @import_specifier.push - attr (name_pop) node_definition = @name - attr (name_push) node_reference = @name - edge name_pop -> name_push - edge name_push -> @import_specifier.source - edge @import_specifier.after_scope -> name_pop + attr (@import_specifier.push) node_reference = @name + edge @import_specifier.push -> @import_specifier.source } ( - (import_specifier name:(_)@name - alias:(_)@alias)@import_specifier - - (#not-eq? @name "default") + )@import_specifier + (#eq? @name "default") ) { - node alias_pop - node name_push + node @import_specifier.push - edge @import_specifier.after_scope -> @import_specifier.before_scope + attr (@import_specifier.push) symbol_reference = "GUARD:DEFAULT", source_node = @name + edge @import_specifier.push -> @import_specifier.source - attr (alias_pop) node_definition = @alias - attr (name_push) node_reference = @name - edge alias_pop -> name_push - edge name_push -> @import_specifier.source - edge @import_specifier.after_scope -> alias_pop +} + +( [ + (import_specifier + name:(_)@alias + !alias)@import_specifier + (import_specifier + name:(_) + alias:(_)@alias)@import_specifier + ] + + (#not-eq? @alias "default") +) { + + node name_pop + + attr (name_pop) node_definition = @alias + edge name_pop -> @import_specifier.push + edge @import_specifier.after_scope -> name_pop } +; ( [ +; (import_specifier +; name:(_)@alias +; !alias)@import_specifier +; (import_specifier +; name:(_) +; alias:(_)@alias)@import_specifier +; ] +; +; (#eq? @name "default") +; ) { +; +; ;; IMPOSSIBLE SHOULD, NEVER HAPPEN +; +; } + ; (import_statement ; (import_clause ; (named_imports diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/export_with_name_default_alias_default.js b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/export_with_name_default_alias_default.js index 9febf034b..2dcd4f19f 100644 --- a/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/export_with_name_default_alias_default.js +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/export_with_name_default_alias_default.js @@ -8,7 +8,7 @@ export { default as default } from "./a.js"; /*--- path: c.js ---*/ -import foo from "./b.js"; +import bar from "./b.js"; -/**/ foo; +/**/ bar; // ^ defined: 3, 7, 11 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/import_with_name_default_alias_nondefault.js b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/import_with_name_default_alias_nondefault.js new file mode 100644 index 000000000..d34fd8898 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/import_with_name_default_alias_nondefault.js @@ -0,0 +1,10 @@ +/*--- path: a.js ---*/ + +export default 1; + +/*--- path: b.js ---*/ + +import { default as foo } from "./a.js"; + +/**/ foo; +// ^ defined: 3, 7 From 352530637e7d3010fe348bf204839e1dea6ef651 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Tue, 10 Oct 2023 11:45:12 +0200 Subject: [PATCH 11/46] Adds CJS versions of tests Co-authored-by: Rebecca Valentine --- .../export_with_name_default_alias_default.js | 14 ++++++++++++++ .../export_with_name_default_alias_nondefault.js | 14 ++++++++++++++ .../export_with_name_nondefault_alias_default.js | 15 +++++++++++++++ .../import_with_name_default_alias_nondefault.js | 10 ++++++++++ 4 files changed, 53 insertions(+) create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/CommonJS_imports_and_exports_using_defaults/export_with_name_default_alias_default.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/CommonJS_imports_and_exports_using_defaults/export_with_name_default_alias_nondefault.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/CommonJS_imports_and_exports_using_defaults/export_with_name_nondefault_alias_default.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/CommonJS_imports_and_exports_using_defaults/import_with_name_default_alias_nondefault.js diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/CommonJS_imports_and_exports_using_defaults/export_with_name_default_alias_default.js b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/CommonJS_imports_and_exports_using_defaults/export_with_name_default_alias_default.js new file mode 100644 index 000000000..97e1f028e --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/CommonJS_imports_and_exports_using_defaults/export_with_name_default_alias_default.js @@ -0,0 +1,14 @@ +/*--- path: a.js ---*/ + +module.exports = 1; + +/*--- path: b.js ---*/ + +module.exports = require("./a.js"); + +/*--- path: c.js ---*/ + +let bar = require("./b.js"); + +/**/ bar; +// ^ defined: 3, 7, 11 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/CommonJS_imports_and_exports_using_defaults/export_with_name_default_alias_nondefault.js b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/CommonJS_imports_and_exports_using_defaults/export_with_name_default_alias_nondefault.js new file mode 100644 index 000000000..9c7d90fc2 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/CommonJS_imports_and_exports_using_defaults/export_with_name_default_alias_nondefault.js @@ -0,0 +1,14 @@ +/*--- path: a.js ---*/ + +module.exports = 1; + +/*--- path: b.js ---*/ + +exports.foo = require("./a.js"); + +/*--- path: c.js ---*/ + +let { foo } = require("./b.js"); + +/**/ foo; +// ^ defined: 3, 7, 11 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/CommonJS_imports_and_exports_using_defaults/export_with_name_nondefault_alias_default.js b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/CommonJS_imports_and_exports_using_defaults/export_with_name_nondefault_alias_default.js new file mode 100644 index 000000000..8b99bd45f --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/CommonJS_imports_and_exports_using_defaults/export_with_name_nondefault_alias_default.js @@ -0,0 +1,15 @@ +/*--- path: a.js ---*/ + +exports.foo = 1; + +/*--- path: b.js ---*/ + +let { foo } = require("./a.js"); +module.exports = foo; + +/*--- path: c.js ---*/ + +let bar = require("./b.js"); + +/**/ bar; +// ^ defined: 3, 7, 8, 12 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/CommonJS_imports_and_exports_using_defaults/import_with_name_default_alias_nondefault.js b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/CommonJS_imports_and_exports_using_defaults/import_with_name_default_alias_nondefault.js new file mode 100644 index 000000000..d9052a27f --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/CommonJS_imports_and_exports_using_defaults/import_with_name_default_alias_nondefault.js @@ -0,0 +1,10 @@ +/*--- path: a.js ---*/ + +module.exports = 1; + +/*--- path: b.js ---*/ + +let foo = require("./a.js"); + +/**/ foo; +// ^ defined: 3, 7 From 37ef4a2866450360f3ca5292716a101cff3474c4 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Tue, 10 Oct 2023 11:47:59 +0200 Subject: [PATCH 12/46] Removes some commented out queries Co-authored-by: Rebecca Valentine --- .../src/stack-graphs.tsg | 27 ++++++++----------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index 3bfd69b77..944fb9996 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -921,6 +921,17 @@ inherit .return_or_yield edge @import_specifier.after_scope -> @import_specifier.before_scope } +;; The following two cases should never happen in valid code: +;; +;; - aliased name, with alias = `default` +;; - non-aliased name, with name = `default` +;; +;; These are both invalid JavaScript and so should never actually +;; occur in valid code. But, of course, sometimes people write +;; bad code, and also they do parse according to the Tree-sitter +;; grammar. We should never ever match against them and produce +;; any sort of graph components however. + ( (import_specifier name:(_)@name @@ -971,22 +982,6 @@ inherit .return_or_yield } -; ( [ -; (import_specifier -; name:(_)@alias -; !alias)@import_specifier -; (import_specifier -; name:(_) -; alias:(_)@alias)@import_specifier -; ] -; -; (#eq? @name "default") -; ) { -; -; ;; IMPOSSIBLE SHOULD, NEVER HAPPEN -; -; } - ; (import_statement ; (import_clause ; (named_imports From a59505546927347f0e3c559465c7e5db9aa0d94a Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Tue, 10 Oct 2023 12:18:29 +0200 Subject: [PATCH 13/46] Adds first vea test Co-authored-by: Rebecca Valentine --- .../export_with_name_default_alias_default.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_default_alias_default.js diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_default_alias_default.js b/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_default_alias_default.js new file mode 100644 index 000000000..a928b3438 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_default_alias_default.js @@ -0,0 +1,14 @@ +/*--- path: a.js ---*/ + +export default function foo() { } + +/*--- path: index.js ---*/ + +export { default as default } from "./a.js"; + +// --- path: index2.js --- + +import bar from "./index.js"; + +/**/ bar; +// ^ defined: 3, 7, 11 From 8b4bfee5811c4b9f657a2038a72be5bbd53da744 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Tue, 10 Oct 2023 11:54:02 +0200 Subject: [PATCH 14/46] Fixes small bug Co-authored-by: Rebecca Valentine --- .../src/stack-graphs.tsg | 11 +++++++++++ ...ort_function_with_name_default_alias_default.js | 14 ++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/export_function_with_name_default_alias_default.js diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index 944fb9996..d25804497 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -486,8 +486,19 @@ inherit .return_or_yield (export_statement (declaration)@decl)@export_stmt { + edge @decl.before_scope -> @export_stmt.before_scope edge @export_stmt.after_scope -> @decl.after_scope + + ; !!!! TODO HACK + ; the tree-sitter grammar doesn't make it possible to distinguish + ; between default exports and non-default exports so this is required + ; to ensure that default exports work properly + node export_stmt_pop_guard_default + attr (export_stmt_pop_guard_default) symbol_definition = "GUARD:DEFAULT", source_node = @decl + edge @export_stmt.exports -> export_stmt_pop_guard_default + ;; edge export_stmt_pop_guard_default -> @decl.value ;; FIXME declarations have no .value + } (export_statement diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/export_function_with_name_default_alias_default.js b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/export_function_with_name_default_alias_default.js new file mode 100644 index 000000000..bf0ff8f1e --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ES6_imports_and_exports_using_the_name_or_alias_default/export_function_with_name_default_alias_default.js @@ -0,0 +1,14 @@ +/*--- path: a.js ---*/ + +export default function foo() { }; + +/*--- path: b.js ---*/ + +export { default as default } from "./a.js"; + +/*--- path: c.js ---*/ + +import bar from "./b.js"; + +/**/ bar; +// ^ defined: 3, 7, 11 From c4f5b45b3d7ed9ca5983f493818a8341831cefc5 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Tue, 10 Oct 2023 12:07:11 +0200 Subject: [PATCH 15/46] Adds bug fixes for transitive callers Co-authored-by: Rebecca Valentine --- .../src/stack-graphs.tsg | 38 +++++++++++++++---- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index d25804497..56489cc70 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -249,7 +249,9 @@ inherit .builtins_string inherit .builtins_undefined inherit .class_value inherit .constructor +inherit .export_statement inherit .exports +inherit .import_statement inherit .pkg_pop inherit .pkg_push inherit .return_or_yield @@ -460,6 +462,10 @@ inherit .return_or_yield ;; #### Export +(export_statement)@export_stmt { + let @export_stmt.export_statement = @export_stmt +} + ; exports of just names ; eg ; export { foo, bar as baz }; @@ -495,7 +501,7 @@ inherit .return_or_yield ; between default exports and non-default exports so this is required ; to ensure that default exports work properly node export_stmt_pop_guard_default - attr (export_stmt_pop_guard_default) symbol_definition = "GUARD:DEFAULT", source_node = @decl + attr (export_stmt_pop_guard_default) symbol_definition = "GUARD:DEFAULT", source_node = @decl, definiens_node = @export_stmt.export_statement edge @export_stmt.exports -> export_stmt_pop_guard_default ;; edge export_stmt_pop_guard_default -> @decl.value ;; FIXME declarations have no .value @@ -513,6 +519,18 @@ inherit .return_or_yield ; TODO this doesn't support destructuring exports edge @export_stmt.exports -> @name.pop + +} + +; set definiens for exported declarations that do not normally have a definiens associated +(export_statement + declaration: [ + (lexical_declaration (variable_declarator name:(identifier)@name)) + (variable_declaration (variable_declarator name:(identifier)@name)) + ]@decl)@_export_stmt { + + attr (@name.pop) definiens_node = @decl + } ; TODO @@ -636,7 +654,7 @@ inherit .return_or_yield ) { node @export_specifier.pop - attr (@export_specifier.pop) node_definition = @alias + attr (@export_specifier.pop) node_definition = @alias, definiens_node = @export_specifier.export_statement edge @export_specifier.exports -> @export_specifier.pop } @@ -656,7 +674,7 @@ inherit .return_or_yield ) { node @export_specifier.pop - attr (@export_specifier.pop) symbol_definition = "GUARD:DEFAULT", source_node = @alias + attr (@export_specifier.pop) symbol_definition = "GUARD:DEFAULT", source_node = @alias, definiens_node = @export_specifier.export_statement edge @export_specifier.exports -> @export_specifier.pop } @@ -669,7 +687,7 @@ inherit .return_or_yield node export_stmt_default_guard - attr (export_stmt_default_guard) symbol_definition = "GUARD:DEFAULT", source_node = @export_stmt + attr (export_stmt_default_guard) symbol_definition = "GUARD:DEFAULT", source_node = @export_stmt, definiens_node = @export_stmt.export_statement edge @default_expr.before_scope -> @export_stmt.before_scope edge @export_stmt.after_scope -> @default_expr.after_scope edge @export_stmt.exports -> export_stmt_default_guard @@ -702,7 +720,7 @@ inherit .return_or_yield edge @export_statement.after_scope -> @export_statement.before_scope - attr (alias_pop) node_definition = @alias + attr (alias_pop) node_definition = @alias, definiens_node = @export_statement.export_statement attr (alias_pop_dot) pop_symbol = "GUARD:MEMBER" edge @export_statement.exports -> alias_pop edge alias_pop -> alias_pop_dot @@ -745,6 +763,10 @@ inherit .return_or_yield ;; - ES6: https://nodejs.org/api/esm.html, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import ;; - CommonJS: https://nodejs.org/api/modules.html +(import_statement)@import_stmt { + let @import_stmt.import_statement = @import_stmt +} + [ (import_statement source:(_)@source) (export_statement source:(_)@source) @@ -850,7 +872,7 @@ inherit .return_or_yield edge @namespace_import.after_scope -> @namespace_import.before_scope - attr (imported_as_pop) node_definition = @imported_as + attr (imported_as_pop) node_definition = @imported_as, definiens_node = @namespace_import.import_statement attr (imported_as_pop_dot) pop_symbol = "GUARD:MEMBER" edge imported_as_pop -> imported_as_pop_dot edge imported_as_pop_dot -> @namespace_import.source @@ -987,7 +1009,7 @@ inherit .return_or_yield node name_pop - attr (name_pop) node_definition = @alias + attr (name_pop) node_definition = @alias, definiens_node = @import_specifier.import_statement edge name_pop -> @import_specifier.push edge @import_specifier.after_scope -> name_pop @@ -1034,7 +1056,7 @@ inherit .return_or_yield edge @import_clause.after_scope -> @import_clause.before_scope - attr (default_name_pop) node_definition = @default_name + attr (default_name_pop) node_definition = @default_name, definiens_node = @import_clause.import_statement attr (default_name_push_guard_default) symbol_reference = "GUARD:DEFAULT", source_node = @default_name edge default_name_pop -> default_name_push_guard_default edge default_name_push_guard_default -> @import_clause.source From 050a6cbb65a03daccc656e73c245a750bb4d8601 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Tue, 10 Oct 2023 13:40:10 +0200 Subject: [PATCH 16/46] Adds some new tests and fixes Co-authored-by: Rebecca Valentine --- .../src/stack-graphs.tsg | 23 +++++++++++++++++++ .../export_with_name_default_alias_default.js | 14 +++++++++++ .../export_with_name_default_alias_default.js | 4 ++-- ...port_with_name_default_alias_nondefault.js | 12 ++++++++++ ...port_with_name_nondefault_alias_default.js | 12 ++++++++++ ...t_with_name_nondefault_alias_nondefault.js | 12 ++++++++++ ...port_with_name_nondefault_alias_default.js | 14 +++++++++++ 7 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/CommonJS_import_export_patterns/export_with_name_default_alias_default.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_default_alias_nondefault.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_nondefault_alias_default.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_nondefault_alias_nondefault.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/import_with_name_nondefault_alias_default.js diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index 56489cc70..4010eba31 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -4118,6 +4118,29 @@ inherit .return_or_yield edge left_ignore_guard -> left_definiens_hook } +( + (assignment_expression + left: (member_expression + object:(identifier)@_object + property:(_)@left + ) + right: (_)@right)@assignment_expr + (#eq @_object "module") + (#eq @left "exports") +) { + + node left_definiens_hook + node left_ignore_guard + + attr (left_ignore_guard) pop_symbol = "GUARD:GANDALF" + attr (left_definiens_hook) node_definition = @left + attr (left_definiens_hook) definiens_node = @right + attr (left_definiens_hook) syntax_type = "function" + edge @assignment_expr.pkg_pop -> left_ignore_guard + edge left_ignore_guard -> left_definiens_hook + +} + (variable_declaration (variable_declarator name:(identifier)@name diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/CommonJS_import_export_patterns/export_with_name_default_alias_default.js b/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/CommonJS_import_export_patterns/export_with_name_default_alias_default.js new file mode 100644 index 000000000..26cd74c45 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/CommonJS_import_export_patterns/export_with_name_default_alias_default.js @@ -0,0 +1,14 @@ +/*--- path: a.js ---*/ + +module.exports = function foo() { }; + +/*--- path: index.js ---*/ + +module.exports = require("./a.js"); + +/*--- path: index2.js ---*/ + +let bar = require("./index.js"); + +/**/ bar; +// ^ defined: 3, 7, 11 \ No newline at end of file diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_default_alias_default.js b/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_default_alias_default.js index a928b3438..33dbb2713 100644 --- a/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_default_alias_default.js +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_default_alias_default.js @@ -6,9 +6,9 @@ export default function foo() { } export { default as default } from "./a.js"; -// --- path: index2.js --- +/*--- path: index2.js ---*/ import bar from "./index.js"; /**/ bar; -// ^ defined: 3, 7, 11 +// ^ defined: 3, 7, 11 \ No newline at end of file diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_default_alias_nondefault.js b/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_default_alias_nondefault.js new file mode 100644 index 000000000..4e0b9ab39 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_default_alias_nondefault.js @@ -0,0 +1,12 @@ +/*--- path: a.js ---*/ + +export default function foo() { } + +/*--- path: index.js ---*/ + +export { default as bar } from "./a.js"; + +// --- path: index2.js --- + +import { bar } from "./index.js"; +// ^ defined: 3, 7 \ No newline at end of file diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_nondefault_alias_default.js b/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_nondefault_alias_default.js new file mode 100644 index 000000000..574df9d55 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_nondefault_alias_default.js @@ -0,0 +1,12 @@ +/*--- path: a.js ---*/ + +export function foo() { } + +/*--- path: index.js ---*/ + +export { foo as default } from "./a.js"; + +/*--- path: index2.js ---*/ + +import bar from "./index.js"; +// ^ defined: 3, 7 \ No newline at end of file diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_nondefault_alias_nondefault.js b/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_nondefault_alias_nondefault.js new file mode 100644 index 000000000..4b3c50203 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_nondefault_alias_nondefault.js @@ -0,0 +1,12 @@ +/*--- path: a.js ---*/ + +export function foo() { } + +/*--- path: index.js ---*/ + +export { foo as bar } from "./a.js"; + +/*--- path: index2.js ---*/ + +import { bar } from "./index"; +// ^ defined: 3, 7 \ No newline at end of file diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/import_with_name_nondefault_alias_default.js b/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/import_with_name_nondefault_alias_default.js new file mode 100644 index 000000000..02178ff18 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/import_with_name_nondefault_alias_default.js @@ -0,0 +1,14 @@ +/*--- path: a.js ---*/ + +export default function foo() { } + +/*--- path: index.js ---*/ + +import { default as foo } from "./a.js"; + +export { foo }; + +/*--- path: index2.js ---*/ + +import { foo } from "./index.js"; +// ^ defined: 3, 7, 9 \ No newline at end of file From f6a6b0851fab87f54afe5c0fc7f396d63f5146b5 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Wed, 11 Oct 2023 11:35:16 +0200 Subject: [PATCH 17/46] Removes no-longer-needed definition baselines Co-authored-by: Rebecca Valentine --- .../test/old/binding/simple.js | 10 ---------- .../export_with_name_default_alias_default.js | 14 -------------- .../export_with_name_default_alias_default.js | 14 -------------- .../export_with_name_default_alias_nondefault.js | 12 ------------ .../export_with_name_nondefault_alias_default.js | 12 ------------ ...export_with_name_nondefault_alias_nondefault.js | 12 ------------ .../import_with_name_nondefault_alias_default.js | 14 -------------- 7 files changed, 88 deletions(-) delete mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/binding/simple.js delete mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/CommonJS_import_export_patterns/export_with_name_default_alias_default.js delete mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_default_alias_default.js delete mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_default_alias_nondefault.js delete mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_nondefault_alias_default.js delete mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_nondefault_alias_nondefault.js delete mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/import_with_name_nondefault_alias_default.js diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/binding/simple.js b/languages/tree-sitter-stack-graphs-javascript/test/old/binding/simple.js deleted file mode 100644 index 5f504b306..000000000 --- a/languages/tree-sitter-stack-graphs-javascript/test/old/binding/simple.js +++ /dev/null @@ -1,10 +0,0 @@ -var x = 1; -let y = 2; -const z = 3; - -/**/ x; -// ^ defined: 1 -/**/ y; -// ^ defined: 2 -/**/ z; -// ^ defined: 3 \ No newline at end of file diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/CommonJS_import_export_patterns/export_with_name_default_alias_default.js b/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/CommonJS_import_export_patterns/export_with_name_default_alias_default.js deleted file mode 100644 index 26cd74c45..000000000 --- a/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/CommonJS_import_export_patterns/export_with_name_default_alias_default.js +++ /dev/null @@ -1,14 +0,0 @@ -/*--- path: a.js ---*/ - -module.exports = function foo() { }; - -/*--- path: index.js ---*/ - -module.exports = require("./a.js"); - -/*--- path: index2.js ---*/ - -let bar = require("./index.js"); - -/**/ bar; -// ^ defined: 3, 7, 11 \ No newline at end of file diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_default_alias_default.js b/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_default_alias_default.js deleted file mode 100644 index 33dbb2713..000000000 --- a/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_default_alias_default.js +++ /dev/null @@ -1,14 +0,0 @@ -/*--- path: a.js ---*/ - -export default function foo() { } - -/*--- path: index.js ---*/ - -export { default as default } from "./a.js"; - -/*--- path: index2.js ---*/ - -import bar from "./index.js"; - -/**/ bar; -// ^ defined: 3, 7, 11 \ No newline at end of file diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_default_alias_nondefault.js b/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_default_alias_nondefault.js deleted file mode 100644 index 4e0b9ab39..000000000 --- a/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_default_alias_nondefault.js +++ /dev/null @@ -1,12 +0,0 @@ -/*--- path: a.js ---*/ - -export default function foo() { } - -/*--- path: index.js ---*/ - -export { default as bar } from "./a.js"; - -// --- path: index2.js --- - -import { bar } from "./index.js"; -// ^ defined: 3, 7 \ No newline at end of file diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_nondefault_alias_default.js b/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_nondefault_alias_default.js deleted file mode 100644 index 574df9d55..000000000 --- a/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_nondefault_alias_default.js +++ /dev/null @@ -1,12 +0,0 @@ -/*--- path: a.js ---*/ - -export function foo() { } - -/*--- path: index.js ---*/ - -export { foo as default } from "./a.js"; - -/*--- path: index2.js ---*/ - -import bar from "./index.js"; -// ^ defined: 3, 7 \ No newline at end of file diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_nondefault_alias_nondefault.js b/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_nondefault_alias_nondefault.js deleted file mode 100644 index 4b3c50203..000000000 --- a/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/export_with_name_nondefault_alias_nondefault.js +++ /dev/null @@ -1,12 +0,0 @@ -/*--- path: a.js ---*/ - -export function foo() { } - -/*--- path: index.js ---*/ - -export { foo as bar } from "./a.js"; - -/*--- path: index2.js ---*/ - -import { bar } from "./index"; -// ^ defined: 3, 7 \ No newline at end of file diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/import_with_name_nondefault_alias_default.js b/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/import_with_name_nondefault_alias_default.js deleted file mode 100644 index 02178ff18..000000000 --- a/languages/tree-sitter-stack-graphs-javascript/test/old/vea_validation_definition_baselines/ES6_import_export_patterns/import_with_name_nondefault_alias_default.js +++ /dev/null @@ -1,14 +0,0 @@ -/*--- path: a.js ---*/ - -export default function foo() { } - -/*--- path: index.js ---*/ - -import { default as foo } from "./a.js"; - -export { foo }; - -/*--- path: index2.js ---*/ - -import { foo } from "./index.js"; -// ^ defined: 3, 7, 9 \ No newline at end of file From b2f53702642ad8c14e38158d94bbd5e632cb5ddb Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Wed, 11 Oct 2023 11:41:30 +0200 Subject: [PATCH 18/46] Adds more tests and some bug fixes Co-authored-by: Rebecca Valentine --- .../src/stack-graphs.tsg | 33 ++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index 4010eba31..fe4354358 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -522,17 +522,6 @@ inherit .return_or_yield } -; set definiens for exported declarations that do not normally have a definiens associated -(export_statement - declaration: [ - (lexical_declaration (variable_declarator name:(identifier)@name)) - (variable_declaration (variable_declarator name:(identifier)@name)) - ]@decl)@_export_stmt { - - attr (@name.pop) definiens_node = @decl - -} - ; TODO ; export let [x,y] = [1,2]; (export_statement @@ -4141,6 +4130,22 @@ inherit .return_or_yield } +(variable_declaration + (variable_declarator + name:(identifier)@name))@decl { + + attr (@name.pop) definiens_node = @decl + +} + +(lexical_declaration + (variable_declarator + name:(identifier)@name))@decl { + + attr (@name.pop) definiens_node = @decl + +} + (variable_declaration (variable_declarator name:(identifier)@name @@ -4149,9 +4154,8 @@ inherit .return_or_yield (generator_function) (arrow_function) (class) - ]@initializer)) { + ])) { - attr (@name.pop) definiens_node = @initializer attr (@name.pop) syntax_type = "function" } @@ -4164,9 +4168,8 @@ inherit .return_or_yield (generator_function) (arrow_function) (class) - ]@initializer)) { + ])) { - attr (@name.pop) definiens_node = @initializer attr (@name.pop) syntax_type = "function" } From 5c817dc2a6d5e27f7a78be4bfe55376aceb2308c Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Wed, 11 Oct 2023 12:52:08 +0200 Subject: [PATCH 19/46] Reorgs and fixes some bugs Co-authored-by: Rebecca Valentine --- .../tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index fe4354358..c5dda28e5 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -288,6 +288,7 @@ inherit .return_or_yield node prog_module_pop node prog_module_scope node prog_exports_pop + node prog_exports_pop_dot node prog_pkg_pop_guard node prog_pkg_push_guard node prog_legacy_qname_guard @@ -342,6 +343,9 @@ inherit .return_or_yield attr (prog_exports_pop) pop_symbol = "GUARD:EXPORTS" edge module_pop_end -> prog_exports_pop edge prog_exports_pop -> @prog.exports + attr (prog_exports_pop_dot) pop_symbol = "GUARD:MEMBER" + edge prog_exports_pop -> prog_exports_pop_dot + edge prog_exports_pop_dot -> @prog.exports ; allow direct access from the package to the modules exports ; this is used from package.json From fec4e4574541b8a5c7b2c7f62da5385839ca1e79 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 12 Oct 2023 11:45:07 +0200 Subject: [PATCH 20/46] Add remaining tests and bug fixes Co-authored-by: Rebecca Valentine --- .../src/stack-graphs.tsg | 152 ++++++++++++------ .../export_with_name_default.js | 11 ++ .../export_with_name_nondefault.js | 10 ++ ...port_with_name_default_alias_nondefault.js | 16 ++ ...eexport_with_name_default_alias_default.js | 15 ++ ...port_with_name_default_alias_nondefault.js | 14 ++ ...port_with_name_nondefault_alias_default.js | 15 ++ ...t_with_name_nondefault_alias_nondefault.js | 14 ++ .../reexport_with_unaliased_name.js | 14 ++ .../export_with_name_default.js | 18 +++ .../export_with_name_nondefault.js | 17 ++ ...port_with_name_default_alias_nondefault.js | 22 +++ ...eexport_with_name_default_alias_default.js | 23 +++ ...port_with_name_default_alias_nondefault.js | 22 +++ ...port_with_name_nondefault_alias_default.js | 23 +++ ...t_with_name_nondefault_alias_nondefault.js | 22 +++ .../reexport_with_unaliased_name.js | 21 +++ ...iable_visible_through_nonbinding_import.js | 6 + 18 files changed, 389 insertions(+), 46 deletions(-) create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/export_with_name_default.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/export_with_name_nondefault.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/import_with_name_default_alias_nondefault.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/reexport_with_name_default_alias_default.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/reexport_with_name_default_alias_nondefault.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/reexport_with_name_nondefault_alias_default.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/reexport_with_name_nondefault_alias_nondefault.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/reexport_with_unaliased_name.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/export_with_name_default.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/export_with_name_nondefault.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/import_with_name_default_alias_nondefault.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/reexport_with_name_default_alias_default.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/reexport_with_name_default_alias_nondefault.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/reexport_with_name_nondefault_alias_default.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/reexport_with_name_nondefault_alias_nondefault.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/reexport_with_unaliased_name.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/variable_visible_through_nonbinding_import.js diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index c5dda28e5..eb86ac913 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -288,7 +288,6 @@ inherit .return_or_yield node prog_module_pop node prog_module_scope node prog_exports_pop - node prog_exports_pop_dot node prog_pkg_pop_guard node prog_pkg_push_guard node prog_legacy_qname_guard @@ -343,9 +342,6 @@ inherit .return_or_yield attr (prog_exports_pop) pop_symbol = "GUARD:EXPORTS" edge module_pop_end -> prog_exports_pop edge prog_exports_pop -> @prog.exports - attr (prog_exports_pop_dot) pop_symbol = "GUARD:MEMBER" - edge prog_exports_pop -> prog_exports_pop_dot - edge prog_exports_pop_dot -> @prog.exports ; allow direct access from the package to the modules exports ; this is used from package.json @@ -801,7 +797,6 @@ inherit .return_or_yield } attr (push_start) is_reference, source_node = @source - edge @source.exports -> source_push_guard_exports edge source_push_guard_exports -> push_start edge source_push_end -> @source.pkg_push } @@ -823,13 +818,15 @@ inherit .return_or_yield } } - edge @source.exports -> source_push_guard_exports edge source_push_guard_exports -> push_start edge source_push_end -> source_push_guard_pkg attr (source_push_guard_pkg) push_symbol = "GUARD:PKG" edge source_push_guard_pkg -> @source.pkg_push } } + + edge @source.exports -> source_push_guard_exports + } ; import "foo.js"; @@ -3894,24 +3891,43 @@ inherit .return_or_yield ( (assignment_expression - left: (member_expression - object:(identifier)@exports - property:(_)@property) + left: [ + ( ; exports.foo = ... + (member_expression + object:(identifier)@exports + property:(_)@property) + (#eq? @exports "exports") + ) + ( ; module.exports.foo = ... + (member_expression + object:(member_expression + object:(identifier)@_module + property:(_)@exports) + property:(_)@property) + (#eq? @_module "module") + (#eq? @exports "exports") + ) + ] right: (_)@right)@assignment_expr - (#eq? @exports "exports") + ) { - node property_pop - node property_pop_dot - node assignment_expr_guard_default + node pop_default_guard + node pop_dot + node pop_name - attr (property_pop) node_definition = @property - attr (property_pop_dot) pop_symbol = "GUARD:MEMBER" - edge property_pop -> @right.value - edge property_pop_dot -> property_pop - attr (assignment_expr_guard_default) symbol_definition = "GUARD:DEFAULT", source_node = @exports - edge assignment_expr_guard_default -> property_pop_dot - edge @assignment_expr.exports -> assignment_expr_guard_default + attr (pop_default_guard) symbol_definition = "GUARD:DEFAULT", source_node = @exports + edge @assignment_expr.exports -> pop_default_guard + + attr (pop_dot) pop_symbol = "GUARD:MEMBER" + edge pop_default_guard -> pop_dot + + attr (pop_name) node_definition = @property + edge pop_dot -> pop_name + edge pop_name -> @right.value + + ;; For ES6 interoperability, expose members as named exports + edge @assignment_expr.exports -> pop_name } @@ -3925,36 +3941,21 @@ inherit .return_or_yield (#eq? @exports "exports") ) { - node assignment_expr_guard_default - - attr (assignment_expr_guard_default) symbol_definition = "GUARD:DEFAULT", source_node = @exports - edge assignment_expr_guard_default -> @right.value - edge @assignment_expr.exports -> assignment_expr_guard_default - edge @assignment_expr.exports -> @right.value + node pop_default_guard + node pop_dot -} - -;; ## ES6-style Imports + attr (pop_default_guard) symbol_definition = "GUARD:DEFAULT", source_node = @exports + edge @assignment_expr.exports -> pop_default_guard + edge pop_default_guard -> @right.value -;; ES6 modules can also be imported using an import function. In general, -;; these look like `import(expr)`, but in practice the expression is a string -;; constant, which is the only case we handle. + ;; For ES6 interoperability, expose members as named exports + attr (pop_dot) pop_symbol = "GAURD:MEMBER" + edge @assignment_expr.exports -> pop_dot + edge pop_dot -> @right.value -( - (call_expression - function:(_)@_import - arguments:(arguments (string)@source))@call_expr - (#eq? @_import "import") -) { - - node call_expr_pop_dot - - attr (call_expr_pop_dot) pop_symbol = "GUARD:MEMBER" - edge @call_expr.value -> call_expr_pop_dot - edge call_expr_pop_dot -> @source.exports } -;; ## CommonJS-style Imports +;; ### CommonJS-style Imports ;; Similar to exports, CommonJS also defines a way to do imports. In general, ;; these look like `require(expr)`, but in practice the expression is a string @@ -3962,19 +3963,78 @@ inherit .return_or_yield ( (call_expression - function:(_)@require + function:(identifier)@require arguments:(arguments (string)@source))@call_expr (#eq? @require "require") ) { node default_guard_push + attr (default_guard_push) symbol_reference = "GUARD:DEFAULT", source_node = @require edge @call_expr.value -> default_guard_push edge default_guard_push -> @source.exports + } +;; ### Dynamic Imports + +;; Both ES6 and CommonJS modules can be imported using an import function. +;; In general, these look like `import(expr)`, but in practice the expression +;; is a string constant, which is the only case we handle. +;; +;; The return value of the import function is an object whose properties are +;; the exports of the module. The default export is assigned to the `default` +;; property. +;; +;; The import function is async and returns a promise. Since we do not support +;; async functions and promises, we only support the case where the function +;; is called as `await import(...)`. + +( + (await_expression + (call_expression + function:(_)@_import + arguments:(arguments (string)@source)) + )@await_expr + (#eq? @_import "import") +) { + node pop_dot + node pop_default + node push_guard_default + attr (pop_dot) pop_symbol = "GUARD:MEMBER" + edge @await_expr.value -> pop_dot + edge pop_dot -> @source.exports + + attr (pop_default) pop_symbol = "default" + edge pop_dot -> pop_default + + attr (push_guard_default) push_symbol = "GUARD:DEFAULT" + edge pop_default -> push_guard_default + edge push_guard_default -> @source.exports + +} + +;; ### ES6 and CommonJS interoperability + +;; Nodes supports some interoperability between ES6 and CommonJS modules. +;; +;; A CommonJS module can be imported in an ES6 module: +;; +;; - `import foo from "cjs_module"` binds `foo` to the value of `module.exports`. +;; - `import { foo } from "cjs_module"` binds `foo` to the value of `module.exports.foo`. +;; - `import("cjs_module")` returns (a promise to) an object with +;; - property `default` bound to the value of `module.exports`, and +;; - other properties bound to the value of those properties in `module.exports` +;; (e.g., `foo` binds `module.exports.foo`). +;; +;; A ES6 module can be import in an CommonJS module: +;; +;; - `import("es6_module")` returns (a promise to) an object with +;; - property default bound to the value of `export default`, and +;; - other properties bound to named exports (e.g., `foo` binds `export { foo }`). +;; - `require("es6_module")` is not supported. diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/export_with_name_default.js b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/export_with_name_default.js new file mode 100644 index 000000000..cb450bf73 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/export_with_name_default.js @@ -0,0 +1,11 @@ +/*--- path: index.js ---*/ + +export default function foo() { } + +/*--- path: index2.js ---*/ + +let bar = await import("./index.js"); + +/**/ bar.default; +// ^ defined: 7 +// ^ defined: 3 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/export_with_name_nondefault.js b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/export_with_name_nondefault.js new file mode 100644 index 000000000..6c4ed5062 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/export_with_name_nondefault.js @@ -0,0 +1,10 @@ +/*--- path: index.js ---*/ + +export function foo() { } + +/*--- path: index2.js ---*/ + +let { foo } = await import("./index.js"); + +/**/ foo; +// ^ defined: 3, 7 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/import_with_name_default_alias_nondefault.js b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/import_with_name_default_alias_nondefault.js new file mode 100644 index 000000000..2c12f935f --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/import_with_name_default_alias_nondefault.js @@ -0,0 +1,16 @@ +/*--- path: a.js ---*/ + +export default function foo() { } + +/*--- path: index.js ---*/ + +import { default as bar } from "./a.js"; + +export { bar }; + +/*--- path: index2.js ---*/ + +let { bar } = await import("./index.js"); + +/**/ bar; +// ^ defined: 3, 7, 9, 13 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/reexport_with_name_default_alias_default.js b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/reexport_with_name_default_alias_default.js new file mode 100644 index 000000000..cee2ee151 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/reexport_with_name_default_alias_default.js @@ -0,0 +1,15 @@ +/*--- path: a.js ---*/ + +export default function foo() { } + +/*--- path: index.js ---*/ + +export { default as default } from "./a.js"; + +/*--- path: index2.js ---*/ + +let bar = await import("./index.js"); + +/**/ bar.default; +// ^ defined: 11 +// ^ defined: 3, 7 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/reexport_with_name_default_alias_nondefault.js b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/reexport_with_name_default_alias_nondefault.js new file mode 100644 index 000000000..e99346fa5 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/reexport_with_name_default_alias_nondefault.js @@ -0,0 +1,14 @@ +/*--- path: a.js ---*/ + +export default function foo() { } + +/*--- path: index.js ---*/ + +export { default as bar } from "./a.js"; + +/*--- path: index2.js ---*/ + +let { bar } = await import("./index.js"); + +/**/ bar; +// ^ defined: 3, 7, 11 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/reexport_with_name_nondefault_alias_default.js b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/reexport_with_name_nondefault_alias_default.js new file mode 100644 index 000000000..99e922f17 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/reexport_with_name_nondefault_alias_default.js @@ -0,0 +1,15 @@ +/*--- path: a.js ---*/ + +export function foo() { } + +/*--- path: index.js ---*/ + +export { foo as default } from "./a.js"; + +/*--- path: index2.js ---*/ + +let bar = await import("./index.js"); + +/**/ bar.default; +// ^ defined: 11 +// ^ defined: 3, 7 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/reexport_with_name_nondefault_alias_nondefault.js b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/reexport_with_name_nondefault_alias_nondefault.js new file mode 100644 index 000000000..a806336b8 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/reexport_with_name_nondefault_alias_nondefault.js @@ -0,0 +1,14 @@ +/*--- path: a.js ---*/ + +export function foo() { } + +/*--- path: index.js ---*/ + +export { foo as bar } from "./a.js"; + +/*--- path: index2.js ---*/ + +let { bar } = await import("./index.js"); + +/**/ bar; +// ^ defined: 3, 7, 11 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/reexport_with_unaliased_name.js b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/reexport_with_unaliased_name.js new file mode 100644 index 000000000..18bbc303c --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/reexport_with_unaliased_name.js @@ -0,0 +1,14 @@ +/*--- path: a.js ---*/ + +export function foo() { } + +/*--- path: index.js ---*/ + +export { foo } from "./a.js"; + +/*--- path: index2.js ---*/ + +let { foo } = await import("./index.js"); + +/**/ foo; +// ^ defined: 3, 7, 11 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/export_with_name_default.js b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/export_with_name_default.js new file mode 100644 index 000000000..70afda69a --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/export_with_name_default.js @@ -0,0 +1,18 @@ +/*--- path: index.js ---*/ + +module.exports = function foo() { }; + +/*--- path: index2.js ---*/ + +import bar from "./index.js"; + +/**/ bar; +// ^ defined: 3, 7 + +/*--- path: index3.js ---*/ + +let bar = await import("./index.js"); + +/**/ bar.default; +// ^ defined: 14 +// ^ defined: 3 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/export_with_name_nondefault.js b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/export_with_name_nondefault.js new file mode 100644 index 000000000..a1ff71b5d --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/export_with_name_nondefault.js @@ -0,0 +1,17 @@ +/*--- path: index.js ---*/ + +exports.foo = function () { }; + +/*--- path: index2.js ---*/ + +import { foo } from "./index.js"; + +/**/ foo; +// ^ defined: 3, 7 + +/*--- path: index3.js ---*/ + +let { foo } = await import("./index.js"); + +/**/ foo; +// ^ defined: 3, 14 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/import_with_name_default_alias_nondefault.js b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/import_with_name_default_alias_nondefault.js new file mode 100644 index 000000000..a059a5a81 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/import_with_name_default_alias_nondefault.js @@ -0,0 +1,22 @@ +/*--- path: a.js ---*/ + +module.exports = function foo() { }; + +/*--- path: index.js ---*/ + +let mod = require("./a.js"); +exports.bar = mod; + +/*--- path: index2.js ---*/ + +import { bar } from "./index.js"; + +/**/ bar; +// ^ defined: 3, 7, 8, 12 + +/*--- path: index3.js ---*/ + +let { bar } = await import("./index.js"); + +/**/ bar; +// ^ defined: 3, 7, 8, 19 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/reexport_with_name_default_alias_default.js b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/reexport_with_name_default_alias_default.js new file mode 100644 index 000000000..3275812e4 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/reexport_with_name_default_alias_default.js @@ -0,0 +1,23 @@ +/*--- path: a.js ---*/ + +module.exports = function foo() { }; + +/*--- path: index.js ---*/ + +let mod = require("./a.js"); +module.exports = mod; + +/*--- path: index2.js ---*/ + +import bar from "./index.js"; + +/**/ bar; +// ^ defined: 3, 7, 8, 12 + +/*--- path: index3.js ---*/ + +let bar = await import("./index.js"); + +/**/ bar.default; +// ^ defined: 19 +// ^ defined: 3, 7, 8 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/reexport_with_name_default_alias_nondefault.js b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/reexport_with_name_default_alias_nondefault.js new file mode 100644 index 000000000..a059a5a81 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/reexport_with_name_default_alias_nondefault.js @@ -0,0 +1,22 @@ +/*--- path: a.js ---*/ + +module.exports = function foo() { }; + +/*--- path: index.js ---*/ + +let mod = require("./a.js"); +exports.bar = mod; + +/*--- path: index2.js ---*/ + +import { bar } from "./index.js"; + +/**/ bar; +// ^ defined: 3, 7, 8, 12 + +/*--- path: index3.js ---*/ + +let { bar } = await import("./index.js"); + +/**/ bar; +// ^ defined: 3, 7, 8, 19 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/reexport_with_name_nondefault_alias_default.js b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/reexport_with_name_nondefault_alias_default.js new file mode 100644 index 000000000..cc1722f16 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/reexport_with_name_nondefault_alias_default.js @@ -0,0 +1,23 @@ +/*--- path: a.js ---*/ + +exports.foo = function () { }; + +/*--- path: index.js ---*/ + +let mod = require("./a.js"); +module.exports = mod.foo + +/*--- path: index2.js ---*/ + +import bar from "./index.js"; + +/**/ bar; +// ^ defined: 3, 8, 12 + +/*--- path: index3.js ---*/ + +let bar = await import("./index.js"); + +/**/ bar.default; +// ^ defined: 19 +// ^ defined: 3, 8 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/reexport_with_name_nondefault_alias_nondefault.js b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/reexport_with_name_nondefault_alias_nondefault.js new file mode 100644 index 000000000..6963f7c5e --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/reexport_with_name_nondefault_alias_nondefault.js @@ -0,0 +1,22 @@ +/*--- path: a.js ---*/ + +exports.foo = function () { }; + +/*--- path: index.js ---*/ + +let mod = require("./a.js"); +exports.bar = mod.foo; + +/*--- path: index2.js ---*/ + +import { bar } from "./index.js"; + +/**/ bar; +// ^ defined: 3, 8, 12 + +/*--- path: index3.js ---*/ + +let { bar } = await import("./index.js"); + +/**/ bar; +// ^ defined: 3, 8, 19 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/reexport_with_unaliased_name.js b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/reexport_with_unaliased_name.js new file mode 100644 index 000000000..1dd099e14 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/reexport_with_unaliased_name.js @@ -0,0 +1,21 @@ +/*--- path: a.js ---*/ + +exports.foo = function () { }; +/*--- path: index.js ---*/ + +let mod = require("./a.js"); +exports.foo = mod.foo; + +/*--- path: index2.js ---*/ + +import { foo } from "./index.js"; + +/**/ foo; +// ^ defined: 3, 7, 11 + +/*--- path: index3.js ---*/ + +let { foo } = await import("./index.js"); + +/**/ foo; +// ^ defined: 3, 7, 18 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/variable_visible_through_nonbinding_import.js b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/variable_visible_through_nonbinding_import.js new file mode 100644 index 000000000..8ce998c2c --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/variable_visible_through_nonbinding_import.js @@ -0,0 +1,6 @@ +let x = 42; + +import "./foo"; + +/**/ x; +// ^ defined: 1 From 2f582a91c5d5981693ec20abde1228519f50e993 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 12 Oct 2023 11:55:41 +0200 Subject: [PATCH 21/46] Adds more tests and testing info Co-authored-by: Rebecca Valentine --- ...fault_object_import_of_exported_default_object.js | 12 ++++++++++++ ...ault_object_import_of_exported_nondefault_name.js | 10 ++++++++++ ...fault_object_import_of_exported_default_object.js | 12 ++++++++++++ ...ault_object_import_of_exported_nondefault_name.js | 10 ++++++++++ ...fault_object_import_of_exported_default_object.js | 12 ++++++++++++ ...ault_object_import_of_exported_nondefault_name.js | 10 ++++++++++ ...fault_object_import_of_exported_default_object.js | 12 ++++++++++++ ...ault_object_import_of_exported_nondefault_name.js | 10 ++++++++++ 8 files changed, 88 insertions(+) create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/field_on_default_object_import_of_exported_default_object.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/field_on_default_object_import_of_exported_nondefault_name.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_export/field_on_default_object_import_of_exported_default_object.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_export/field_on_default_object_import_of_exported_nondefault_name.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/field_on_default_object_import_of_exported_default_object.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/field_on_default_object_import_of_exported_nondefault_name.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_export/field_on_default_object_import_of_exported_default_object.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_export/field_on_default_object_import_of_exported_nondefault_name.js diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/field_on_default_object_import_of_exported_default_object.js b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/field_on_default_object_import_of_exported_default_object.js new file mode 100644 index 000000000..2e3c427c8 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/field_on_default_object_import_of_exported_default_object.js @@ -0,0 +1,12 @@ +/*--- path: index.js ---*/ + +export default { + foo: 1 +}; + +/*--- path: index2.js ---*/ + +let mod = await import("./index.js"); + +mod.default.foo; +// ^ defined: 4 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/field_on_default_object_import_of_exported_nondefault_name.js b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/field_on_default_object_import_of_exported_nondefault_name.js new file mode 100644 index 000000000..9bc1a8120 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_ES6_export/field_on_default_object_import_of_exported_nondefault_name.js @@ -0,0 +1,10 @@ +/*--- path: index.js ---*/ + +export function foo() { } + +/*--- path: index2.js ---*/ + +let mod = await import("./index.js"); + +mod.foo; +// ^ defined: 3 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_export/field_on_default_object_import_of_exported_default_object.js b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_export/field_on_default_object_import_of_exported_default_object.js new file mode 100644 index 000000000..8bfed4d87 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_export/field_on_default_object_import_of_exported_default_object.js @@ -0,0 +1,12 @@ +/*--- path: index.js ---*/ + +module.exports = { + foo: 1 +}; + +/*--- path: index2.js ---*/ + +let mod = require("./index.js"); + +mod.foo; +// ^ defined: 4 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_export/field_on_default_object_import_of_exported_nondefault_name.js b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_export/field_on_default_object_import_of_exported_nondefault_name.js new file mode 100644 index 000000000..a699fc2a5 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_export/field_on_default_object_import_of_exported_nondefault_name.js @@ -0,0 +1,10 @@ +/*--- path: index.js ---*/ + +exports.foo = function () { }; + +/*--- path: index2.js ---*/ + +let mod = require("./index.js"); + +mod.foo; +// ^ defined: 3 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/field_on_default_object_import_of_exported_default_object.js b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/field_on_default_object_import_of_exported_default_object.js new file mode 100644 index 000000000..c05ea891d --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/field_on_default_object_import_of_exported_default_object.js @@ -0,0 +1,12 @@ +/*--- path: index.js ---*/ + +module.exports = { + foo: 1 +}; + +/*--- path: index2.js ---*/ + +import mod from "./index.js"; + +mod.foo; +// ^ defined: 4 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/field_on_default_object_import_of_exported_nondefault_name.js b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/field_on_default_object_import_of_exported_nondefault_name.js new file mode 100644 index 000000000..a091abeaf --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/field_on_default_object_import_of_exported_nondefault_name.js @@ -0,0 +1,10 @@ +/*--- path: index.js ---*/ + +exports.foo = function () { }; + +/*--- path: index2.js ---*/ + +import mod from "./index.js"; + +mod.foo; +// ^ defined: 3 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_export/field_on_default_object_import_of_exported_default_object.js b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_export/field_on_default_object_import_of_exported_default_object.js new file mode 100644 index 000000000..ed6a119c7 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_export/field_on_default_object_import_of_exported_default_object.js @@ -0,0 +1,12 @@ +/*--- path: index.js ---*/ + +export default { + foo: 1 +}; + +/*--- path: index2.js ---*/ + +import mod from "./index.js"; + +mod.foo; +// ^ defined: 4 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_export/field_on_default_object_import_of_exported_nondefault_name.js b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_export/field_on_default_object_import_of_exported_nondefault_name.js new file mode 100644 index 000000000..b8cf8d0c9 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_export/field_on_default_object_import_of_exported_nondefault_name.js @@ -0,0 +1,10 @@ +/*--- path: index.js ---*/ + +export function foo() { } + +/*--- path: index2.js ---*/ + +import mod from "./index.js"; + +mod.foo; +// ^ defined: From e0f66aade03e84c6ca418383ce70d03d0c656269 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 12 Oct 2023 12:12:23 +0200 Subject: [PATCH 22/46] Fixes definiens syntax types Co-authored-by: Rebecca Valentine --- .../src/stack-graphs.tsg | 98 ++++++++++++++----- 1 file changed, 75 insertions(+), 23 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index eb86ac913..e25345fd5 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -3130,15 +3130,15 @@ inherit .return_or_yield ; augmentation of scope via identifiers (assignment_expression - left: (identifier)@left + left: (identifier)@name right: (_)@right)@assignment_expr { - node @assignment_expr.pop + node @name.pop ; augments the scope by adding a lookup edge, ie. a pop - attr (@assignment_expr.pop) node_definition = @left - edge @assignment_expr.after_scope -> @assignment_expr.pop - edge @assignment_expr.pop -> @right.value + attr (@name.pop) node_definition = @name + edge @assignment_expr.after_scope -> @name.pop + edge @name.pop -> @right.value ; ensure the scope flows through the identifier edge @assignment_expr.after_scope -> @right.after_scope @@ -4132,16 +4132,39 @@ inherit .return_or_yield ;; kinds of definitions. (assignment_expression - left: (identifier)@_left + left: [ + (identifier)@left + ; (member_expression property:(_)@left) ; FIXME member expressions are references and have no .pop + ] + right: [ + (function) + (generator_function) + (arrow_function) + ]) { + + attr (@left.pop) syntax_type = "function" +} + +(assignment_expression + left: [ + (identifier)@left + ; (member_expression property:(_)@left) ; FIXME member expressions are references and have no .pop + ] + right: (class)) { + + attr (@left.pop) syntax_type = "class" +} + +(assignment_expression + left: (identifier)@left right: [ (function) (generator_function) (arrow_function) (class) - ]@right)@assignment_expr { + ]@right) { - attr (@assignment_expr.pop) definiens_node = @right - attr (@assignment_expr.pop) syntax_type = "function" + attr (@left.pop) definiens_node = @right } @@ -4151,11 +4174,7 @@ inherit .return_or_yield object:(identifier)@_object property:(_)@left ) - right: [ - (function) - (generator_function) - (arrow_function) - ]@right)@assignment_expr + right: (_)@right)@assignment_expr (#not-eq @_object "module") (#not-eq @left "exports") ) { @@ -4166,7 +4185,6 @@ inherit .return_or_yield attr (left_ignore_guard) pop_symbol = "GUARD:GANDALF" attr (left_definiens_hook) node_definition = @left attr (left_definiens_hook) definiens_node = @right - attr (left_definiens_hook) syntax_type = "function" edge @assignment_expr.pkg_pop -> left_ignore_guard edge left_ignore_guard -> left_definiens_hook } @@ -4188,7 +4206,6 @@ inherit .return_or_yield attr (left_ignore_guard) pop_symbol = "GUARD:GANDALF" attr (left_definiens_hook) node_definition = @left attr (left_definiens_hook) definiens_node = @right - attr (left_definiens_hook) syntax_type = "function" edge @assignment_expr.pkg_pop -> left_ignore_guard edge left_ignore_guard -> left_definiens_hook @@ -4217,13 +4234,21 @@ inherit .return_or_yield (function) (generator_function) (arrow_function) - (class) ])) { attr (@name.pop) syntax_type = "function" } +(variable_declaration + (variable_declarator + name:(identifier)@name + value: (class))) { + + attr (@name.pop) syntax_type = "class" + +} + (lexical_declaration (variable_declarator name:(identifier)@name @@ -4231,13 +4256,41 @@ inherit .return_or_yield (function) (generator_function) (arrow_function) - (class) ])) { attr (@name.pop) syntax_type = "function" } +(lexical_declaration + (variable_declarator + name:(identifier)@name + value: (class))) { + + attr (@name.pop) syntax_type = "class" + +} + +(pair + key: (_)@name + value: [ + (function) + (generator_function) + (arrow_function) + ]) { + + attr (@name.definiens_hook) syntax_type = "function" + +} + +(pair + key: (_)@name + value: (class)) { + + attr (@name.definiens_hook) syntax_type = "class" + +} + (pair key: (_)@name value: [ @@ -4247,14 +4300,13 @@ inherit .return_or_yield (class) ]@value)@pair_expr { - node name_definiens_hook + node @name.definiens_hook node name_ignore_guard attr (name_ignore_guard) pop_symbol = "GUARD:GANDALF" - attr (name_definiens_hook) node_definition = @name - attr (name_definiens_hook) definiens_node = @value - attr (name_definiens_hook) syntax_type = "function" + attr (@name.definiens_hook) node_definition = @name + attr (@name.definiens_hook) definiens_node = @value edge @pair_expr.pkg_pop -> name_ignore_guard - edge name_ignore_guard -> name_definiens_hook + edge name_ignore_guard -> @name.definiens_hook } From 310995db7c528c458b4b3fc50b396d3f5bfa4ae4 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 12 Oct 2023 12:17:59 +0200 Subject: [PATCH 23/46] Remove unnecessary patterns Co-authored-by: Rebecca Valentine --- .../tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index e25345fd5..91bd88610 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -3894,14 +3894,14 @@ inherit .return_or_yield left: [ ( ; exports.foo = ... (member_expression - object:(identifier)@exports + object:(_)@exports property:(_)@property) (#eq? @exports "exports") ) ( ; module.exports.foo = ... (member_expression object:(member_expression - object:(identifier)@_module + object:(_)@_module property:(_)@exports) property:(_)@property) (#eq? @_module "module") From 9b13fc1e37af5cb107d3d549b4a2f24edbc9fc6e Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 12 Oct 2023 12:28:47 +0200 Subject: [PATCH 24/46] Adds empty statement block bug fix Co-authored-by: Rebecca Valentine --- .../src/stack-graphs.tsg | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index 91bd88610..94dedc6a1 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -1561,6 +1561,12 @@ inherit .return_or_yield ;; #### Statement Block +(statement_block (_)* @stmts)@statement_block { + if (is-empty @stmts) { + edge @statement_block.after_scope -> @statement_block.before_scope + } +} + ; statement block, first statement (statement_block . From a543dbdcdc439d280472c13b6244bdcbca04830f Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 12 Oct 2023 13:10:26 +0200 Subject: [PATCH 25/46] Hoisting changes: - Adds hoisting tests - Fixes strange bug in test case - Adds base hoist points - Adds more hoisting tests - Adds fixes for new hoisting tests Co-authored-by: Rebecca Valentine --- .../src/stack-graphs.tsg | 82 ++++++++- .../test/old/hoisting/basic_functions.js | 8 + .../old/hoisting/functions_in_subscopes.js | 163 ++++++++++++++++++ .../test/old/hoisting/imports.js | 10 ++ 4 files changed, 257 insertions(+), 6 deletions(-) create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/hoisting/basic_functions.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/hoisting/functions_in_subscopes.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/hoisting/imports.js diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index 94dedc6a1..cf6bc5424 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -251,6 +251,7 @@ inherit .class_value inherit .constructor inherit .export_statement inherit .exports +inherit .hoist_point inherit .import_statement inherit .pkg_pop inherit .pkg_push @@ -292,6 +293,7 @@ inherit .return_or_yield node prog_pkg_push_guard node prog_legacy_qname_guard node @prog.exports + node @prog.hoist_point node @prog.pkg_pop node @prog.pkg_push @@ -322,6 +324,7 @@ inherit .return_or_yield } edge @prog.before_scope -> @prog.pkg_push + edge @prog.before_scope -> @prog.hoist_point attr (prog_module_scope) pop_symbol = "GUARD:MODULE" edge @prog.pkg_pop -> prog_module_pop_start @@ -880,8 +883,10 @@ inherit .return_or_yield (import_clause)@import_clause source:(_)@source)@import_stmt { + edge @import_stmt.after_scope -> @import_stmt.before_scope + edge @import_clause.before_scope -> @import_stmt.before_scope - edge @import_stmt.after_scope -> @import_clause.after_scope + edge @import_stmt.hoist_point -> @import_clause.after_scope edge @import_clause.source -> @source.exports @@ -1210,7 +1215,7 @@ inherit .return_or_yield ; with an augmentation for the function attr (@name.pop) node_definition = @name - edge @fun_decl.after_scope -> @name.pop + edge @fun_decl.hoist_point -> @name.pop edge @name.pop -> fun_decl_function_value ; function values have drop nodes that handle closures, that points to the @@ -1294,7 +1299,7 @@ inherit .return_or_yield ; with an augmentation for the function attr (@name.pop) node_definition = @name - edge @fun_decl.after_scope -> @name.pop + edge @fun_decl.hoist_point -> @name.pop edge @name.pop -> fun_decl_function_value ; function values have drop nodes that handle closures, that points to the @@ -1561,6 +1566,13 @@ inherit .return_or_yield ;; #### Statement Block +(statement_block)@statement_block { + + node @statement_block.hoist_point + edge @statement_block.before_scope -> @statement_block.hoist_point + +} + (statement_block (_)* @stmts)@statement_block { if (is-empty @stmts) { edge @statement_block.after_scope -> @statement_block.before_scope @@ -1599,6 +1611,13 @@ inherit .return_or_yield ;; #### If +(if_statement + consequence:(_)@consequence)@if_stmt { + + let @if_stmt.hoist_point = @consequence.before_scope + +} + (if_statement condition:(_)@condition)@if_stmt { ; scopes flow from the if statement to the condition edge @condition.before_scope -> @if_stmt.before_scope @@ -1611,6 +1630,7 @@ inherit .return_or_yield ; scopes flow from the condition to the consequence, then to the if statement edge @consequence.before_scope -> @condition.after_scope edge @if_stmt.after_scope -> @consequence.after_scope + } (if_statement @@ -1622,6 +1642,13 @@ inherit .return_or_yield edge @if_stmt.after_scope -> @alternative.after_scope } +(else_clause + (_)@inner)@else_clause { + + let @else_clause.hoist_point = @inner.before_scope + +} + (else_clause (_)@inner)@else_clause { node @else_clause.after_scope node @else_clause.before_scope @@ -1650,7 +1677,15 @@ inherit .return_or_yield (switch_body)@switch_body { node @switch_body.after_scope node @switch_body.before_scope - edge @switch_body.after_scope -> @switch_body.before_scope + node @switch_body.hoist_point + + edge @switch_body.before_scope -> @switch_body.hoist_point +} + +(switch_body (_)* @choices)@switch_body { + if (is-empty @choices) { + edge @switch_body.after_scope -> @switch_body.before_scope + } } ; switch body, first choice @@ -1769,6 +1804,13 @@ inherit .return_or_yield ;; #### For +(for_statement + body:(_)@body)@for_stmt { + + let @for_stmt.hoist_point = @body.before_scope + +} + (for_statement initializer:(_)@initializer condition:(_)@condition @@ -1787,12 +1829,20 @@ inherit .return_or_yield ; scopes also flow from condition out to statement edge @for_stmt.after_scope -> @condition.after_scope + } ;; #### For In +(for_in_statement + body:(_)@body)@for_in_stmt { + + let @for_in_stmt.hoist_point = @body.before_scope + +} + (for_in_statement left:(_)@_left right:(_)@right @@ -1822,6 +1872,13 @@ inherit .return_or_yield ;; #### While +(while_statement + body:(_)@body)@while_stmt { + + let @while_stmt.hoist_point = @body.before_scope + +} + (while_statement condition:(_)@condition body:(_)@body)@while_stmt @@ -1834,12 +1891,20 @@ inherit .return_or_yield ; scopes also flow back into the condition edge @condition.before_scope -> @body.after_scope + } ;; #### Do +(do_statement + body:(_)@body)@do_stmt { + + let @do_stmt.hoist_point = @body.before_scope + +} + (do_statement body:(_)@body condition:(_)@condition)@do_stmt @@ -1930,12 +1995,18 @@ inherit .return_or_yield ;; #### With +(with_statement body:(_)@body)@with_stmt { + + let @with_stmt.hoist_point = @body.before_scope + +} + (with_statement object:(_)@object body:(_)@body)@with_stmt { - node with_stmt_push_dot + node with_stmt_push_dot ; scopes flow from the statement into the object then into the body then back out edge @object.before_scope -> @with_stmt.before_scope @@ -1944,7 +2015,6 @@ inherit .return_or_yield edge @with_stmt.after_scope -> @with_stmt.before_scope attr (@with_stmt.after_scope -> @with_stmt.before_scope) precedence = 1 - attr (with_stmt_push_dot) push_symbol = "GUARD:MEMBER" edge with_stmt_push_dot -> @object.value edge @body.before_scope -> with_stmt_push_dot diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/hoisting/basic_functions.js b/languages/tree-sitter-stack-graphs-javascript/test/old/hoisting/basic_functions.js new file mode 100644 index 000000000..69382ca19 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/hoisting/basic_functions.js @@ -0,0 +1,8 @@ +/**/ foo; +// ^ defined: 7 + +/**/ bar; +// ^ defined: 8 + +function foo() { } +function* bar() { } \ No newline at end of file diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/hoisting/functions_in_subscopes.js b/languages/tree-sitter-stack-graphs-javascript/test/old/hoisting/functions_in_subscopes.js new file mode 100644 index 000000000..a6c25ada4 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/hoisting/functions_in_subscopes.js @@ -0,0 +1,163 @@ +/**/ f1; +// ^ defined: +/**/ f2; +// ^ defined: +/**/ f3; +// ^ defined: +/**/ f4; +// ^ defined: +/**/ f5; +// ^ defined: +/**/ f6; +// ^ defined: +/**/ f7; +// ^ defined: +/**/ f8; +// ^ defined: +/**/ f9; +// ^ defined: +/**/ f10; +// ^ defined: +/**/ f11; +// ^ defined: +/**/ f12; +// ^ defined: +/**/ f13; +// ^ defined: +/**/ f14; +// ^ defined: +/**/ f15; +// ^ defined: +/**/ f16; +// ^ defined: +/**/ f17; +// ^ defined: + +while (x) { + /**/ f1; + // ^ defined: 40 + + function f1() { } +} + +for (let x = 0; x < 10; x++) { + /**/ f2; + // ^ defined: 47 + + function f2() { } +} + +if (x) { + /**/ f3; + // ^ defined: 54 + + function f3() { } +} else { + /**/ f4; + // ^ defined: 59 + + function f4() { } +} + +for (x in y) { + /**/ f5; + // ^ defined: 66 + + function f5() { } +} + +do { + /**/ f6; + // ^ defined: 73 + + function f6() { } +} while (x); + +try { + /**/ f7; + // ^ defined: 80 + + function f7() { } +} catch { + /**/ f8; + // ^ defined: 85 + + function f8() { } +} finally { + /**/ f9; + // ^ defined: 90 + + function f9() { } +} + +with (x) { + /**/ f10; + // ^ defined: 97 + + function f10() { } +} + +switch (x) { + case 0: + /**/ f11; + // ^ defined: 105 + + function f11() { } +} + +{ + /**/ f12; + // ^ defined: 112 + + function f12() { } +} + +function foo() { + /**/ f13; + // ^ defined: 119 + + function f13() { } +} + +function* foo() { + /**/ f14; + // ^ defined: 126 + + function f14() { } +} + +(function () { + /**/ f15; + // ^ defined: 133 + + function f15() { } +}); + +(function* () { + /**/ f16; + // ^ defined: 140 + + function f16() { } +}); + +(() => { + /**/ f17; + // ^ defined: 147 + + function f17() { } +}); + +// Some tests of bare single-statement bodies + +while (x) function f1() { } + +for (let x = 0; x < 10; x++) function f2() { } + +if (x) function f3() { } +else function f4() { } + +for (x in y) function f5() { } + +do function f6() { } while (x); + +with (x) function f10() { } diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/hoisting/imports.js b/languages/tree-sitter-stack-graphs-javascript/test/old/hoisting/imports.js new file mode 100644 index 000000000..1045e5512 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/hoisting/imports.js @@ -0,0 +1,10 @@ +/*--- path: a.js ---*/ + +export let foo = 1; + +/*--- path: b.js ---*/ + +/**/ bar; +// ^ defined: 3, 10 + +import { foo as bar } from "./a.js"; \ No newline at end of file From 182ab99bf7154f9b49ce8d750b4ad76ecf7e9ab8 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 12 Oct 2023 13:13:35 +0200 Subject: [PATCH 26/46] Adds support for `import`'s default field Co-authored-by: Rebecca Valentine --- .../imports_and_exports/import_function.js | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/import_function.js diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/import_function.js b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/import_function.js new file mode 100644 index 000000000..02b9de496 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/import_function.js @@ -0,0 +1,20 @@ +/*--- path: a.js ---*/ + +exports.foo = 2; +module.exports = 1; + +/*--- path: b.js ---*/ + +let mod = await import("./a.js"); + +mod.foo; +// ^ defined: 3 + +mod.default; +// ^ defined: 3, 4 +// !!!! TODO 3 is here because the `exports.foo` on line 3 also defines +// the default object. this is a current limitation of the import/export +// system to support CommonJS behavior + +mod.default.foo; +// ^ defined: 3 From b9d5119ae435bf69798087ca028bb6b93a54c574 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 12 Oct 2023 13:18:34 +0200 Subject: [PATCH 27/46] Adds tests for module.exports.foo pattern Co-authored-by: Rebecca Valentine --- ...t_object_import_of_exported_default_object_field.js | 10 ++++++++++ ...t_object_import_of_exported_default_object_field.js | 10 ++++++++++ 2 files changed, 20 insertions(+) create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_export/field_on_default_object_import_of_exported_default_object_field.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/field_on_default_object_import_of_exported_default_object_field.js diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_export/field_on_default_object_import_of_exported_default_object_field.js b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_export/field_on_default_object_import_of_exported_default_object_field.js new file mode 100644 index 000000000..16d60547a --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/CommonJS_import_export/field_on_default_object_import_of_exported_default_object_field.js @@ -0,0 +1,10 @@ +/*--- path: a.js ---*/ + +module.exports.foo = 1; + +/*--- path: b.js ---*/ + +let mod = require("./a.js"); + +mod.foo; +// ^ defined: 3 \ No newline at end of file diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/field_on_default_object_import_of_exported_default_object_field.js b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/field_on_default_object_import_of_exported_default_object_field.js new file mode 100644 index 000000000..b3b8c5456 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/imports_and_exports/ES6_import_CommonJS_export/field_on_default_object_import_of_exported_default_object_field.js @@ -0,0 +1,10 @@ +/*--- path: a.js ---*/ + +module.exports.foo = 1; + +/*--- path: b.js ---*/ + +import { foo } from "./a.js"; + +/**/ foo; +// ^ defined: 3, 7 \ No newline at end of file From 6c33f752af76745162b8727a2af96874b2777305 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 12 Oct 2023 13:27:08 +0200 Subject: [PATCH 28/46] Adds fix for ES6 default exports Co-authored-by: Rebecca Valentine --- .../src/stack-graphs.tsg | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index cf6bc5424..120611406 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -499,10 +499,11 @@ inherit .return_or_yield edge @decl.before_scope -> @export_stmt.before_scope edge @export_stmt.after_scope -> @decl.after_scope - ; !!!! TODO HACK - ; the tree-sitter grammar doesn't make it possible to distinguish - ; between default exports and non-default exports so this is required - ; to ensure that default exports work properly +} + +(export_statement "default" + (declaration)@decl)@export_stmt { + node export_stmt_pop_guard_default attr (export_stmt_pop_guard_default) symbol_definition = "GUARD:DEFAULT", source_node = @decl, definiens_node = @export_stmt.export_statement edge @export_stmt.exports -> export_stmt_pop_guard_default From 83a470ca37c1833a7d4d1a7a9044f2f9384cb058 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Tue, 10 Oct 2023 14:03:29 +0200 Subject: [PATCH 29/46] Add comment explaining import & export specifier rules --- .../src/stack-graphs.tsg | 87 ++++++++++++------- 1 file changed, 55 insertions(+), 32 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index 120611406..7d86b629b 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -588,16 +588,27 @@ inherit .return_or_yield edge @export_clause.after_scope -> @last_export.after_scope } +;; Export specifiers have several cases: +;; - the reference into the source module can be default or named +;; - the definition from this module can be default or named. +;; +;; We model this using seperate sets of rules, two rules for the reference, +;; and two rules for the definition. The `.def_to_ref` node is used to connect +;; the two. + (export_specifier)@export_specifier { node @export_specifier.after_scope node @export_specifier.before_scope + node @export_specifier.def_to_ref node @export_specifier.source edge @export_specifier.after_scope -> @export_specifier.before_scope } +;; Export specifier reference rules + ; export { default } from ... ; export { default as ... } from ... ( @@ -610,7 +621,7 @@ inherit .return_or_yield node name_push attr (name_push) node_reference = @name - edge @export_specifier.pop -> name_push + edge @export_specifier.def_to_ref -> name_push edge name_push -> @export_specifier.source } @@ -625,13 +636,16 @@ inherit .return_or_yield (#eq? @name "default") ) { - node export_specifier_push_guard_default - attr (export_specifier_push_guard_default) symbol_reference = "GUARD:DEFAULT", source_node = @name - edge @export_specifier.pop -> export_specifier_push_guard_default - edge export_specifier_push_guard_default -> @export_specifier.source + node push_guard_default + + attr (push_guard_default) symbol_reference = "GUARD:DEFAULT", source_node = @name + edge @export_specifier.def_to_ref -> push_guard_default + edge push_guard_default -> @export_specifier.source } +;; Export specifier definition rules + ; export { foo } from ... ; export { ... as foo } from ... ( [ @@ -646,9 +660,11 @@ inherit .return_or_yield (#not-eq? @alias "default") ) { - node @export_specifier.pop - attr (@export_specifier.pop) node_definition = @alias, definiens_node = @export_specifier.export_statement - edge @export_specifier.exports -> @export_specifier.pop + node name_pop + + attr (name_pop) node_definition = @alias, definiens_node = @export_specifier.export_statement + edge @export_specifier.exports -> name_pop + edge name_pop -> @export_specifier.def_to_ref } @@ -666,9 +682,11 @@ inherit .return_or_yield (#eq? @alias "default") ) { - node @export_specifier.pop - attr (@export_specifier.pop) symbol_definition = "GUARD:DEFAULT", source_node = @alias, definiens_node = @export_specifier.export_statement - edge @export_specifier.exports -> @export_specifier.pop + node pop_guard_default + + attr (pop_guard_default) symbol_definition = "GUARD:DEFAULT", source_node = @alias, definiens_node = @export_specifier.export_statement + edge @export_specifier.exports -> pop_guard_default + edge pop_guard_default -> @export_specifier.def_to_ref } @@ -678,13 +696,13 @@ inherit .return_or_yield (export_statement value:(_)@default_expr)@export_stmt { - node export_stmt_default_guard + node pop_default_guard - attr (export_stmt_default_guard) symbol_definition = "GUARD:DEFAULT", source_node = @export_stmt, definiens_node = @export_stmt.export_statement + attr (pop_default_guard) symbol_definition = "GUARD:DEFAULT", source_node = @export_stmt, definiens_node = @export_stmt.export_statement edge @default_expr.before_scope -> @export_stmt.before_scope edge @export_stmt.after_scope -> @default_expr.after_scope - edge @export_stmt.exports -> export_stmt_default_guard - edge export_stmt_default_guard -> @default_expr.value + edge @export_stmt.exports -> pop_default_guard + edge pop_default_guard -> @default_expr.value } @@ -942,24 +960,25 @@ inherit .return_or_yield edge @named_imports.after_scope -> @last_import.after_scope } +;; Import specifiers have several cases: +;; - the reference into the source module can be default or named +;; - the definition from this module can be default or named. +;; The case where the definition is default instead of named is invalid. +;; +;; We model this using seperate sets of rules, two rules for the reference, +;; and one rules for the definition. The `.def_to_ref` node is used to connect +;; the two. + (import_specifier)@import_specifier { node @import_specifier.after_scope node @import_specifier.before_scope + node @import_specifier.def_to_ref node @import_specifier.source edge @import_specifier.after_scope -> @import_specifier.before_scope } -;; The following two cases should never happen in valid code: -;; -;; - aliased name, with alias = `default` -;; - non-aliased name, with name = `default` -;; -;; These are both invalid JavaScript and so should never actually -;; occur in valid code. But, of course, sometimes people write -;; bad code, and also they do parse according to the Tree-sitter -;; grammar. We should never ever match against them and produce -;; any sort of graph components however. +;; Import specifier reference rules ( (import_specifier @@ -969,10 +988,11 @@ inherit .return_or_yield (#not-eq? @name "default") ) { - node @import_specifier.push + node name_push - attr (@import_specifier.push) node_reference = @name - edge @import_specifier.push -> @import_specifier.source + attr (name_push) node_reference = @name + edge name_push -> @import_specifier.source + edge @import_specifier.def_to_ref -> name_push } @@ -984,13 +1004,16 @@ inherit .return_or_yield (#eq? @name "default") ) { - node @import_specifier.push + node push_guard_default - attr (@import_specifier.push) symbol_reference = "GUARD:DEFAULT", source_node = @name - edge @import_specifier.push -> @import_specifier.source + attr (push_guard_default) symbol_reference = "GUARD:DEFAULT", source_node = @name + edge push_guard_default -> @import_specifier.source + edge @import_specifier.def_to_ref -> push_guard_default } +;; Import specifier definition rules + ( [ (import_specifier name:(_)@alias @@ -1006,7 +1029,7 @@ inherit .return_or_yield node name_pop attr (name_pop) node_definition = @alias, definiens_node = @import_specifier.import_statement - edge name_pop -> @import_specifier.push + edge name_pop -> @import_specifier.def_to_ref edge @import_specifier.after_scope -> name_pop } From 03d755d8898a953a1a1075ccc7299e998ec1de1c Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Tue, 10 Oct 2023 14:19:54 +0200 Subject: [PATCH 30/46] Fix definiens warning --- .../src/stack-graphs.tsg | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index 7d86b629b..b3a6b4454 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -1466,12 +1466,10 @@ inherit .return_or_yield (#eq? @name "constructor") ) { - node name_constructor_guard - ; augmentation for the constructor - attr (name_constructor_guard) symbol_definition = "GUARD:CONSTRUCTOR", source_node = @name - edge @method_def.class_value -> name_constructor_guard - edge name_constructor_guard -> @method_def.constructor + attr (@name.pop) symbol_definition = "GUARD:CONSTRUCTOR", source_node = @name + edge @method_def.class_value -> @name.pop + edge @name.pop -> @method_def.constructor edge @method_def.constructor -> @method_def.method_value } From 2e2e221352b0da92b8128a053e534460cf7e7c08 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Tue, 10 Oct 2023 14:46:35 +0200 Subject: [PATCH 31/46] Drop explicit tree-sitter version dependency --- languages/tree-sitter-stack-graphs-javascript/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/languages/tree-sitter-stack-graphs-javascript/Cargo.toml b/languages/tree-sitter-stack-graphs-javascript/Cargo.toml index 42960b6fb..624edbab2 100644 --- a/languages/tree-sitter-stack-graphs-javascript/Cargo.toml +++ b/languages/tree-sitter-stack-graphs-javascript/Cargo.toml @@ -31,7 +31,6 @@ clap = { version = "4", optional = true } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" stack-graphs = { version = "0.12", path = "../../stack-graphs" } -tree-sitter = "=0.20.9" tree-sitter-stack-graphs = { version = "0.7", path = "../../tree-sitter-stack-graphs" } tree-sitter-javascript = { git = "https://github.com/tree-sitter/tree-sitter-javascript", rev = "5720b249490b3c17245ba772f6be4a43edb4e3b7" } From d8e6c282b191db3416d95ba42d9184eaa2a8ebfa Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Wed, 11 Oct 2023 10:17:27 +0200 Subject: [PATCH 32/46] Remove unconditional scope pass-throughs for empty elements Elements that could be empty (i.e., not have subnodes) connected their before and after scopes unconditionally. This could lead to exponential blow ups when they were not empty: the direct pass through and the path through the elements were equivalent. Guarding the pass-through with a conditional that ensures it is only created when there are indeed no sub nodes prevents this. --- .../src/stack-graphs.tsg | 104 +++++++++--------- 1 file changed, 54 insertions(+), 50 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index b3a6b4454..402ec18ed 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -554,10 +554,10 @@ inherit .return_or_yield node @export_clause.source } -; LATER-TODO tree sitter doesn't yet support empty switch bodies -; THIS IS A HUGE HACK AND MUST BE FIXED -(export_clause)@export_clause { - edge @export_clause.after_scope -> @export_clause.before_scope +(export_clause (_)* @clauses)@export_clause { + if (is-empty @clauses) { + edge @export_clause.after_scope -> @export_clause.before_scope + } } (export_clause @@ -853,9 +853,7 @@ inherit .return_or_yield ; import "foo.js"; ; only used for side effects not imports. -; HACK this is not a good solution, but we can't do better with the -; current tree sitter grammar -(import_statement)@import_stmt { +(import_statement . source:(_))@import_stmt { edge @import_stmt.after_scope -> @import_stmt.before_scope } @@ -926,10 +924,10 @@ inherit .return_or_yield node @named_imports.source } -; LATER-TODO tree sitter doesn't yet support empty named imports -; THIS IS A HUGE HACK AND MUST BE FIXED -(named_imports)@named_imports { - edge @named_imports.after_scope -> @named_imports.before_scope +(named_imports (_)* @specs)@named_imports { + if (is-empty @specs) { + edge @named_imports.after_scope -> @named_imports.before_scope + } } (named_imports @@ -1421,12 +1419,15 @@ inherit .return_or_yield } -; LATER-TODO tree sitter doesn't yet support empty switch bodies -; THIS IS A HUGE HACK AND MUST BE FIXED (class_body)@class_body { node @class_body.after_scope node @class_body.before_scope - edge @class_body.after_scope -> @class_body.before_scope +} + +(class_body (_)* @decls)@class_body { + if (is-empty @decls) { + edge @class_body.after_scope -> @class_body.before_scope + } } (class_body @@ -1694,8 +1695,6 @@ inherit .return_or_yield edge @switch_stmt.after_scope -> @body.after_scope } -; LATER-TODO tree sitter doesn't yet support empty switch bodies -; THIS IS A HUGE HACK AND MUST BE FIXED (switch_body)@switch_body { node @switch_body.after_scope node @switch_body.before_scope @@ -1743,10 +1742,10 @@ inherit .return_or_yield node @switch_case.before_scope } -; LATER-TODO tree sitter doesnt yet support switch case's with no statements -; THIS IS A HUGE HACK AND MUST BE FIXED -(switch_case)@switch_case { +(switch_case (_)* @stmts)@switch_case { + if (is-empty @stmts) { edge @switch_case.after_scope -> @switch_case.before_scope + } } ; switch case, non-empty statements, first statement @@ -1786,10 +1785,10 @@ inherit .return_or_yield node @switch_default.before_scope } -; LATER-TODO tree sitter doesnt yet support empty defaults -; THIS IS A HUGE HACK AND MUST BE FIXED -(switch_default)@switch_default { - edge @switch_default.after_scope -> @switch_default.before_scope +(switch_default (_)* @defaults)@switch_default { + if (is-empty @defaults) { + edge @switch_default.after_scope -> @switch_default.before_scope + } } ; switch default, non-empty statements, first statement @@ -2237,10 +2236,10 @@ inherit .return_or_yield ;; #### Template Strings ; template_strings w/ no substitutions -; LATER-TODO tree sitter queries don't let us find the absence of substitutions -; THIS IS A HUGE HACK AND MUST BE FIXED -(template_string)@template_string { - edge @template_string.after_scope -> @template_string.before_scope +(template_string (_)* @substs)@template_string { + if (is-empty @substs) { + edge @template_string.after_scope -> @template_string.before_scope + } } ; nonempty template string, value @@ -2390,10 +2389,10 @@ inherit .return_or_yield } ; empty objects -; LATER-TODO currently unsupported by tree sitter queries -; THIS IS A HUGE HACK AND MUST BE FIXED -(object)@object_expr { - edge @object_expr.after_scope -> @object_expr.before_scope +(object (_)* @entries)@object_expr { + if (is-empty @entries) { + edge @object_expr.after_scope -> @object_expr.before_scope + } } ; non-empty objects, scopes, first entry @@ -2541,10 +2540,10 @@ inherit .return_or_yield } ; empty arrays -; LATER-TODO currently unsupported by tree sitter queries -; THIS IS A HUGE HACK AND MUST BE FIXED -(array)@array_expr { - edge @array_expr.after_scope -> @array_expr.before_scope +(array (_)* @elems)@array_expr { + if (is-empty @elems) { + edge @array_expr.after_scope -> @array_expr.before_scope + } } ; nonempty arrays, first element @@ -2587,14 +2586,15 @@ inherit .return_or_yield ;; #### Formal Parameters -; LATER-TODO scope propagation through empty formal parameters -; currently unsupported by tree sitter queries -; THIS IS A HUGE HACK AND MUST BE FIXED - (formal_parameters)@formal_params { node @formal_params.after_scope node @formal_params.before_scope - edge @formal_params.after_scope -> @formal_params.before_scope +} + +(formal_parameters (_)* @params)@formal_params { + if (is-empty @params) { + edge @formal_params.after_scope -> @formal_params.before_scope + } } ; first parameter @@ -2985,12 +2985,15 @@ inherit .return_or_yield ;; #### Arguments -; LATER-TODO currently unsupported by tree sitter queries -; THIS IS A HUGE HACK AND MUST BE FIXED (arguments)@arguments { node @arguments.after_scope node @arguments.before_scope - edge @arguments.after_scope -> @arguments.before_scope +} + +(arguments (_)* @args)@arguments { + if (is-empty @args) { + edge @arguments.after_scope -> @arguments.before_scope + } } (arguments @@ -3701,8 +3704,10 @@ inherit .return_or_yield ; LATER-TODO scope propagation through empty object patterns ; currently unsupported by tree sitter queries ; THIS IS A HUGE HACK AND MUST BE FIXED -(object_pattern)@object_pat { - edge @object_pat.after_scope -> @object_pat.before_scope +(object_pattern (_)* @entries)@object_pat { + if (is-empty @entries) { + edge @object_pat.after_scope -> @object_pat.before_scope + } } ; scope propagation through object patterns, first entry @@ -3823,11 +3828,10 @@ inherit .return_or_yield ;; #### Array Patterns -; LATER-TODO scope propagation through empty array patterns -; currently unsupported by tree sitter queries -; THIS IS A HUGE HACK AND MUST BE FIXED -(array_pattern)@array_pat { - edge @array_pat.after_scope -> @array_pat.before_scope +(array_pattern (_)* @pats)@array_pat { + if (is-empty @pats) { + edge @array_pat.after_scope -> @array_pat.before_scope + } } ; scope propagation through array patterns, first element From 4be77c5fc4eb043766eb2a65befbc1532cb5bc39 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 12 Oct 2023 17:16:05 +0200 Subject: [PATCH 33/46] Fix bug when main is unset in package.json and clarify behavior --- .../rust/npm_package.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/languages/tree-sitter-stack-graphs-javascript/rust/npm_package.rs b/languages/tree-sitter-stack-graphs-javascript/rust/npm_package.rs index d5e1ad944..5a46d6ee1 100644 --- a/languages/tree-sitter-stack-graphs-javascript/rust/npm_package.rs +++ b/languages/tree-sitter-stack-graphs-javascript/rust/npm_package.rs @@ -86,6 +86,10 @@ impl FileAnalyzer for NpmPackageAnalyzer { // [root] -> [pop "GUARD:PKG"] -> [pop PKG_NAME]* -> [push PKG_INTERNAL_NAME] -> [push "GUARD:PKG_INTERNAL"] -> [root] // if !npm_pkg.name.is_empty() { + // NOTE Because all modules expose their exports at the top-level, both paths created below are equivalent for + // exports of the main module. This means multiple equivalent paths to those exports, which is bad for + // performance. At the moment, we have no mechanism to prevent this from happening. + // reach package internals via package name // // [root] -> [pop "GUARD:PKG"] -> [pop pkg_name]* -> [push pkg_internal_name] @@ -112,7 +116,9 @@ impl FileAnalyzer for NpmPackageAnalyzer { "exports_guard_pop", ); replace_edge(graph, pkg_name_pop, exports_guard_pop, 1); - let main = NormalizedRelativePath::from_str(&npm_pkg.main) + let main = Some(npm_pkg.main) + .filter(|main| !main.is_empty()) + .and_then(|main| NormalizedRelativePath::from_str(&main)) .map(|p| p.into_path_buf()) .unwrap_or(PathBuf::from("index")) .with_extension(""); From 80d73caab8b2b32d0443308cfa683415a7433ff0 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Fri, 13 Oct 2023 11:58:52 +0200 Subject: [PATCH 34/46] Make subscripts proper references --- .../src/stack-graphs.tsg | 4 ++-- .../test/old/compound_literals/objects.js | 21 +++++++++++++------ .../test/old/simple_expressions/comma.js | 7 +++++++ .../simple_expressions/template_strings.js | 4 ++++ .../test/old/simple_expressions/ternary.js | 4 ++++ .../test/old/simple_expressions/variables.js | 9 ++++++++ 6 files changed, 41 insertions(+), 8 deletions(-) create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/simple_expressions/comma.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/simple_expressions/template_strings.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/simple_expressions/ternary.js create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/simple_expressions/variables.js diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index 402ec18ed..e918457d7 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -3064,7 +3064,6 @@ inherit .return_or_yield edge subscript_expr_push_dot -> @object.value ; this is done differently depending on what the index is - ; attr @index.push "push" = @index, "reference" edge @subscript_expr.value -> @subscript_expr.index_push edge @subscript_expr.index_push -> subscript_expr_push_dot @@ -3075,7 +3074,8 @@ inherit .return_or_yield index: (string)@index)@subscript_expr { - attr (@subscript_expr.index_push) push_symbol = (replace (source-text @index) "[\"\']" "") + attr (@subscript_expr.index_push) symbol_reference = (replace (source-text @index) "[\"\']" ""), source_node = @index + } (subscript_expression diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/compound_literals/objects.js b/languages/tree-sitter-stack-graphs-javascript/test/old/compound_literals/objects.js index fe5bf1c55..6d4bb76b5 100644 --- a/languages/tree-sitter-stack-graphs-javascript/test/old/compound_literals/objects.js +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/compound_literals/objects.js @@ -1,15 +1,24 @@ -let obj = { x: 1, y: 2, 0: "z" }; +let obj = { + x: 1, y: 2, 0: "z" }; + let obj_x = obj.x; +// ^ defined: 1 +// ^ defined: 2 let x = obj_x; -// ^ defined: 1, 2 +// ^ defined: 4, 2 + let obj_y = obj["y"]; +// ^ defined: 1 +// ^ defined: 2 let y = obj_y; -// ^ defined: 1, 5 +// ^ defined: 10, 2 let obj_z = obj[0]; +// ^ defined: 1 +// ^ defined: 2 let z = obj_z; -// ^ defined: 1, 9 +// ^ defined: 16, 2 let obj2 = { x, y }; -// ^ defined: 1, 2, 3 -// ^ defined: 1, 5, 6 +// ^ defined: 7, 4, 2 +// ^ defined: 13, 10, 2 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/simple_expressions/comma.js b/languages/tree-sitter-stack-graphs-javascript/test/old/simple_expressions/comma.js new file mode 100644 index 000000000..58a51610e --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/simple_expressions/comma.js @@ -0,0 +1,7 @@ +let x = 1; +let y = (1, x); +// ^ defined: 1 + +let y = (1, x = 5); +let z = x; +// ^ defined: 1, 5 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/simple_expressions/template_strings.js b/languages/tree-sitter-stack-graphs-javascript/test/old/simple_expressions/template_strings.js new file mode 100644 index 000000000..099cd1d37 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/simple_expressions/template_strings.js @@ -0,0 +1,4 @@ +let x = 1; + +let y = `template ${ x } string`; +// ^ defined: 1 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/simple_expressions/ternary.js b/languages/tree-sitter-stack-graphs-javascript/test/old/simple_expressions/ternary.js new file mode 100644 index 000000000..4c7947e5a --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/simple_expressions/ternary.js @@ -0,0 +1,4 @@ +let x = 1; +let y = true ? x++ : 2; +let z = x; +// ^ defined: 1, 2 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/simple_expressions/variables.js b/languages/tree-sitter-stack-graphs-javascript/test/old/simple_expressions/variables.js new file mode 100644 index 000000000..394da591f --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/simple_expressions/variables.js @@ -0,0 +1,9 @@ +let x = 1; +const y = 2; + +var z = x + y; +// ^ defined: 1 +// ^ defined: 2 + +let w = z; +// ^ defined: 1, 2, 4 From 00ea067d0d6df3985d9cadf084a1b6c56a984709 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Fri, 13 Oct 2023 15:14:46 +0200 Subject: [PATCH 35/46] Add definiens for CommonJS exports --- .../tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg | 2 ++ 1 file changed, 2 insertions(+) diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index e918457d7..db2aecd64 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -4025,6 +4025,7 @@ inherit .return_or_yield edge pop_default_guard -> pop_dot attr (pop_name) node_definition = @property + attr (pop_name) definiens_node = @assignment_expr edge pop_dot -> pop_name edge pop_name -> @right.value @@ -4047,6 +4048,7 @@ inherit .return_or_yield node pop_dot attr (pop_default_guard) symbol_definition = "GUARD:DEFAULT", source_node = @exports + attr (pop_default_guard) definiens_node = @assignment_expr edge @assignment_expr.exports -> pop_default_guard edge pop_default_guard -> @right.value From 271df519f0833301deef085102dc9b2ead7dfe61 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Fri, 13 Oct 2023 15:36:11 +0200 Subject: [PATCH 36/46] Fix some default guard definiens --- .../tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index db2aecd64..570f11bae 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -4074,7 +4074,7 @@ inherit .return_or_yield node default_guard_push - attr (default_guard_push) symbol_reference = "GUARD:DEFAULT", source_node = @require + attr (default_guard_push) symbol_reference = "GUARD:DEFAULT", source_node = @source edge @call_expr.value -> default_guard_push edge default_guard_push -> @source.exports @@ -4114,7 +4114,7 @@ inherit .return_or_yield attr (pop_default) pop_symbol = "default" edge pop_dot -> pop_default - attr (push_guard_default) push_symbol = "GUARD:DEFAULT" + attr (push_guard_default) symbol_reference = "GUARD:DEFAULT", source_node = @source edge pop_default -> push_guard_default edge push_guard_default -> @source.exports From a25b9c4d87c2775df52ea0ea1eac2629e5f8ae43 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Fri, 13 Oct 2023 17:02:08 +0200 Subject: [PATCH 37/46] Use statement as definiens like the old code --- .../src/stack-graphs.tsg | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index 570f11bae..3b81b02b8 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -4067,9 +4067,9 @@ inherit .return_or_yield ( (call_expression - function:(identifier)@require + function:(identifier)@_require arguments:(arguments (string)@source))@call_expr - (#eq? @require "require") + (#eq? @_require "require") ) { node default_guard_push @@ -4266,9 +4266,9 @@ inherit .return_or_yield (generator_function) (arrow_function) (class) - ]@right) { + ])@assignment_expr { - attr (@left.pop) definiens_node = @right + attr (@left.pop) definiens_node = @assignment_expr } @@ -4402,14 +4402,14 @@ inherit .return_or_yield (generator_function) (arrow_function) (class) - ]@value)@pair_expr { + ])@pair_expr { node @name.definiens_hook node name_ignore_guard attr (name_ignore_guard) pop_symbol = "GUARD:GANDALF" attr (@name.definiens_hook) node_definition = @name - attr (@name.definiens_hook) definiens_node = @value + attr (@name.definiens_hook) definiens_node = @pair_expr edge @pair_expr.pkg_pop -> name_ignore_guard edge name_ignore_guard -> @name.definiens_hook From 84015cc6d71838a88c43843aae053dd0b4ac8b44 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Fri, 13 Oct 2023 17:17:15 +0200 Subject: [PATCH 38/46] Consolidate syntax type rules --- .../src/stack-graphs.tsg | 107 ++++++++---------- 1 file changed, 47 insertions(+), 60 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index 3b81b02b8..731f44764 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -4235,30 +4235,6 @@ inherit .return_or_yield ;; do provide at least some information about definiens for these ;; kinds of definitions. -(assignment_expression - left: [ - (identifier)@left - ; (member_expression property:(_)@left) ; FIXME member expressions are references and have no .pop - ] - right: [ - (function) - (generator_function) - (arrow_function) - ]) { - - attr (@left.pop) syntax_type = "function" -} - -(assignment_expression - left: [ - (identifier)@left - ; (member_expression property:(_)@left) ; FIXME member expressions are references and have no .pop - ] - right: (class)) { - - attr (@left.pop) syntax_type = "class" -} - (assignment_expression left: (identifier)@left right: [ @@ -4331,50 +4307,39 @@ inherit .return_or_yield } -(variable_declaration - (variable_declarator - name:(identifier)@name - value: [ - (function) - (generator_function) - (arrow_function) - ])) { - - attr (@name.pop) syntax_type = "function" - -} - -(variable_declaration - (variable_declarator - name:(identifier)@name - value: (class))) { - - attr (@name.pop) syntax_type = "class" - -} - -(lexical_declaration - (variable_declarator - name:(identifier)@name - value: [ +[ + (variable_declaration + (variable_declarator + name:(identifier)@name + value: [ + (function) + (generator_function) + (arrow_function) + ])) + (lexical_declaration + (variable_declarator + name:(identifier)@name + value: [ + (function) + (generator_function) + (arrow_function) + ])) + (assignment_expression + left: [ + (identifier)@name + ; (member_expression property:(_)@name) ; FIXME member expressions are references and have no .pop + ] + right: [ (function) (generator_function) (arrow_function) - ])) { + ]) +] { attr (@name.pop) syntax_type = "function" } -(lexical_declaration - (variable_declarator - name:(identifier)@name - value: (class))) { - - attr (@name.pop) syntax_type = "class" - -} - (pair key: (_)@name value: [ @@ -4387,6 +4352,28 @@ inherit .return_or_yield } + +[ + (variable_declaration + (variable_declarator + name:(identifier)@name + value: (class))) + (lexical_declaration + (variable_declarator + name:(identifier)@name + value: (class))) + (assignment_expression + left: [ + (identifier)@name + ; (member_expression property:(_)@name) ; FIXME member expressions are references and have no .pop + ] + right: (class)) +] { + + attr (@name.pop) syntax_type = "class" + +} + (pair key: (_)@name value: (class)) { From 1178fc26e38a39b930a8af9a9d477ea2a390c7d0 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Fri, 13 Oct 2023 17:53:49 +0200 Subject: [PATCH 39/46] Port detour nodes --- .../src/stack-graphs.tsg | 112 +++++++++++++++++- 1 file changed, 109 insertions(+), 3 deletions(-) diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index 731f44764..35818168d 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -504,11 +504,49 @@ inherit .return_or_yield (export_statement "default" (declaration)@decl)@export_stmt { - node export_stmt_pop_guard_default - attr (export_stmt_pop_guard_default) symbol_definition = "GUARD:DEFAULT", source_node = @decl, definiens_node = @export_stmt.export_statement - edge @export_stmt.exports -> export_stmt_pop_guard_default + node pop_guard_default + attr (pop_guard_default) symbol_definition = "GUARD:DEFAULT", source_node = @decl, definiens_node = @export_stmt.export_statement + edge @export_stmt.exports -> pop_guard_default ;; edge export_stmt_pop_guard_default -> @decl.value ;; FIXME declarations have no .value + ; !!!! HACK These detour nodes are a massive hack to allow find all refs land on defs + ; for the default values of modules that have useful names like the module name or + ; package name + + node detour_push + node detour_pop + + scan FILE_PATH { + + "^(.+/)?([^/]+)/index\.js$" { + let module_name = $2 + attr (detour_push) push_symbol = module_name + attr (detour_pop) symbol_definition = module_name, source_node = @decl, definiens_node = @export_stmt + edge pop_guard_default -> detour_push + edge detour_push -> detour_pop + ; edge detour_pop -> @decl.value ;; FIXME declarations have no .value + } + + "^(.+/)?([^/]+)\.js$" { + let module_name = $2 + attr (detour_push) push_symbol = module_name + attr (detour_pop) symbol_definition = module_name, source_node = @decl, definiens_node = @export_stmt + edge pop_guard_default -> detour_push + edge detour_push -> detour_pop + ; edge detour_pop -> @decl.value ;; FIXME declarations have no .value + } + + } + + node default_detour_push + node default_detour_pop + + attr (default_detour_push) push_symbol = "default" + attr (default_detour_pop) symbol_definition = "default", source_node = @decl, definiens_node = @decl + edge pop_guard_default -> default_detour_push + edge default_detour_push -> default_detour_pop + ; edge default_detour_pop -> @decl.value ;; FIXME declarations have no .value + } (export_statement @@ -4032,6 +4070,40 @@ inherit .return_or_yield ;; For ES6 interoperability, expose members as named exports edge @assignment_expr.exports -> pop_name + node detour_push + node detour_pop + + scan FILE_PATH { + + "^(.+/)?([^/]+)/index\.js$" { + let module_name = $2 + attr (detour_push) push_symbol = module_name + attr (detour_pop) symbol_definition = module_name, source_node = @assignment_expr, definiens_node = @assignment_expr + edge pop_default_guard -> detour_push + edge detour_push -> detour_pop + edge detour_pop -> @right.value + } + + "^(.+/)?([^/]+)\.js$" { + let module_name = $2 + attr (detour_push) push_symbol = module_name + attr (detour_pop) symbol_definition = module_name, source_node = @assignment_expr, definiens_node = @assignment_expr + edge pop_default_guard -> detour_push + edge detour_push -> detour_pop + edge detour_pop -> @right.value + } + + } + + node default_detour_push + node default_detour_pop + + attr (default_detour_push) push_symbol = "default" + attr (default_detour_pop) symbol_definition = "default", source_node = @assignment_expr, definiens_node = @assignment_expr + edge pop_default_guard -> default_detour_push + edge default_detour_push -> default_detour_pop + edge default_detour_pop -> @right.value + } ( @@ -4057,6 +4129,40 @@ inherit .return_or_yield edge @assignment_expr.exports -> pop_dot edge pop_dot -> @right.value + node detour_push + node detour_pop + + scan FILE_PATH { + + "^(.+/)?([^/]+)/index\.js$" { + let module_name = $2 + attr (detour_push) push_symbol = module_name + attr (detour_pop) symbol_definition = module_name, source_node = @assignment_expr, definiens_node = @assignment_expr + edge pop_default_guard -> detour_push + edge detour_push -> detour_pop + edge detour_pop -> @right.value + } + + "^(.+/)?([^/]+)\.js$" { + let module_name = $2 + attr (detour_push) push_symbol = module_name + attr (detour_pop) symbol_definition = module_name, source_node = @assignment_expr, definiens_node = @assignment_expr + edge pop_default_guard -> detour_push + edge detour_push -> detour_pop + edge detour_pop -> @right.value + } + + } + + node default_detour_push + node default_detour_pop + + attr (default_detour_push) push_symbol = "default" + attr (default_detour_pop) symbol_definition = "default", source_node = @assignment_expr, definiens_node = @assignment_expr + edge pop_default_guard -> default_detour_push + edge default_detour_push -> default_detour_pop + edge default_detour_pop -> @right.value + } ;; ### CommonJS-style Imports From 2a81b45c5c3081e66115c0dc3e0ee231ad63ff3b Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Fri, 13 Oct 2023 18:23:24 +0200 Subject: [PATCH 40/46] Add missing expression --- .../tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg | 1 + 1 file changed, 1 insertion(+) diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index 35818168d..4219fd877 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -2237,6 +2237,7 @@ inherit .return_or_yield (update_expression) (new_expression) (yield_expression) + (spread_element) ]@expr { node @expr.after_scope From 769d9841fc92e2888ab560e98c0cf8f3c9a9a633 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Sat, 14 Oct 2023 17:13:55 +0200 Subject: [PATCH 41/46] Fix scope after member assignment --- .../src/stack-graphs.tsg | 30 ++++++++++++++----- .../array_assignment_interrupts_scope.js | 10 +++++++ 2 files changed, 33 insertions(+), 7 deletions(-) create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/array_assignment_interrupts_scope.js diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index 4219fd877..ed789146e 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -3094,17 +3094,17 @@ inherit .return_or_yield node subscript_expr_push_dot ; scopes flow left to right - edge @object.before_scope -> @subscript_expr.before_scope + edge @object.before_scope -> @subscript_expr.before_scope edge @index.before_scope -> @object.after_scope - edge @subscript_expr.after_scope -> @index.after_scope + edge @subscript_expr.after_scope -> @index.after_scope ; value is a subscript lookup, ie a push then push dot - attr (subscript_expr_push_dot) push_symbol = "GUARD:MEMBER" - edge subscript_expr_push_dot -> @object.value + attr (subscript_expr_push_dot) push_symbol = "GUARD:MEMBER" + edge subscript_expr_push_dot -> @object.value ; this is done differently depending on what the index is - edge @subscript_expr.value -> @subscript_expr.index_push - edge @subscript_expr.index_push -> subscript_expr_push_dot + edge @subscript_expr.value -> @subscript_expr.index_push + edge @subscript_expr.index_push -> subscript_expr_push_dot } @@ -3263,7 +3263,7 @@ inherit .return_or_yield ; scopes flow into the RHS then back out to the whole expr, ; augmented (in subsequent rules) by the LHS edge @right.before_scope -> @assignment_expr.before_scope - + ; value of the whole thing is value of the RHS edge @assignment_expr.value -> @right.value } @@ -3285,6 +3285,21 @@ inherit .return_or_yield } +(assignment_expression + left: [ + (member_expression) + (subscript_expression) + ]@left + right: (_)@right)@assignment_expr { + + ; scope flows from LHS into pattern then back to assignment + edge @left.before_scope -> @assignment_expr.before_scope + + ; ensure the scope flows through the identifier + edge @assignment_expr.after_scope -> @right.after_scope + +} + ; assignment to direct fields on `this` (assignment_expression left: (member_expression @@ -3322,6 +3337,7 @@ inherit .return_or_yield ; scope flows from LHS into pattern then back to assignment edge @left.before_scope -> @right.after_scope edge @assignment_expr.after_scope -> @left.after_scope + } diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/array_assignment_interrupts_scope.js b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/array_assignment_interrupts_scope.js new file mode 100644 index 000000000..a71218475 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/array_assignment_interrupts_scope.js @@ -0,0 +1,10 @@ +let bar = {}; + +/**/ bar; +// ^ defined: 1 + +/**/ bar["one"] = 1; +// ^ defined: 1 + +/**/ bar; +// ^ defined: 1 From 1475444c7fad87ce56dfb5872316c688305ba5ff Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Mon, 16 Oct 2023 14:32:29 +0200 Subject: [PATCH 42/46] Add exponential blowup tests (but skipped) --- .../if_statement_path_blowup.js.skip | 37 +++++++++++++++++++ .../ternary_expression_path_blowup.js.skip | 37 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/if_statement_path_blowup.js.skip create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ternary_expression_path_blowup.js.skip diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/if_statement_path_blowup.js.skip b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/if_statement_path_blowup.js.skip new file mode 100644 index 000000000..98f54e4ab --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/if_statement_path_blowup.js.skip @@ -0,0 +1,37 @@ +let x = 42; + +if (true) { 1 } else { -1 } +if (true) { 1 } else { -1 } +if (true) { 1 } else { -1 } +if (true) { 1 } else { -1 } +if (true) { 1 } else { -1 } +if (true) { 1 } else { -1 } +if (true) { 1 } else { -1 } +if (true) { 1 } else { -1 } +if (true) { 1 } else { -1 } +if (true) { 1 } else { -1 } +if (true) { 1 } else { -1 } +if (true) { 1 } else { -1 } +if (true) { 1 } else { -1 } +if (true) { 1 } else { -1 } +if (true) { 1 } else { -1 } +if (true) { 1 } else { -1 } +if (true) { 1 } else { -1 } +if (true) { 1 } else { -1 } +if (true) { 1 } else { -1 } +if (true) { 1 } else { -1 } +if (true) { 1 } else { -1 } +if (true) { 1 } else { -1 } +if (true) { 1 } else { -1 } +if (true) { 1 } else { -1 } +if (true) { 1 } else { -1 } +if (true) { 1 } else { -1 } +if (true) { 1 } else { -1 } +if (true) { 1 } else { -1 } +if (true) { 1 } else { -1 } +if (true) { 1 } else { -1 } +if (true) { 1 } else { -1 } +if (true) { 1 } else { -1 } + +/**/ x; +// ^ defined: 1 diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ternary_expression_path_blowup.js.skip b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ternary_expression_path_blowup.js.skip new file mode 100644 index 000000000..b0185ce87 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ternary_expression_path_blowup.js.skip @@ -0,0 +1,37 @@ +let x = 42; + +true ? 1 : -1; +true ? 1 : -1; +true ? 1 : -1; +true ? 1 : -1; +true ? 1 : -1; +true ? 1 : -1; +true ? 1 : -1; +true ? 1 : -1; +true ? 1 : -1; +true ? 1 : -1; +true ? 1 : -1; +true ? 1 : -1; +true ? 1 : -1; +true ? 1 : -1; +true ? 1 : -1; +true ? 1 : -1; +true ? 1 : -1; +true ? 1 : -1; +true ? 1 : -1; +true ? 1 : -1; +true ? 1 : -1; +true ? 1 : -1; +true ? 1 : -1; +true ? 1 : -1; +true ? 1 : -1; +true ? 1 : -1; +true ? 1 : -1; +true ? 1 : -1; +true ? 1 : -1; +true ? 1 : -1; +true ? 1 : -1; +true ? 1 : -1; + +/**/ x; +// ^ defined: 1 From 88351419a8313ea1c56944a1ddd9d8b7a5f72d19 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Mon, 16 Oct 2023 20:28:24 +0200 Subject: [PATCH 43/46] Add reference for ES6/CommonJS interop. --- .../tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index ed789146e..d3d4c05c8 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -4262,6 +4262,11 @@ inherit .return_or_yield ;; - property default bound to the value of `export default`, and ;; - other properties bound to named exports (e.g., `foo` binds `export { foo }`). ;; - `require("es6_module")` is not supported. +;; +;; References: +;; +;; - https://nodejs.org/api/esm.html#interoperability-with-commonjs +;; From 2a22ad25dc3c160286dcd9f4875e66db6bb268a1 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Mon, 16 Oct 2023 20:51:27 +0200 Subject: [PATCH 44/46] Fix bug with string property keys --- .../src/stack-graphs.tsg | 10 +++++++++- .../string_property_interrupts_scope.js | 6 ++++++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/string_property_interrupts_scope.js diff --git a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg index d3d4c05c8..254445369 100644 --- a/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg +++ b/languages/tree-sitter-stack-graphs-javascript/src/stack-graphs.tsg @@ -2535,10 +2535,18 @@ inherit .return_or_yield } -(pair key:(string)@key) { +(pair + key:(string)@key + value:(_)@value)@pair +{ node @key.pop attr (@key.pop) pop_symbol = (replace (source-text @key) "\"" "") + + ; scopes flow into the value, then back to the pair + edge @value.before_scope -> @pair.before_scope + edge @pair.after_scope -> @value.after_scope + } (pair diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/string_property_interrupts_scope.js b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/string_property_interrupts_scope.js new file mode 100644 index 000000000..a64352e75 --- /dev/null +++ b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/string_property_interrupts_scope.js @@ -0,0 +1,6 @@ +let x = 42; + +let foo = { "strict": true }; + +/**/ x; +// ^ defined: 1 From a342c0d165444b390b396d26c01f0f4b1f2f9fd8 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Tue, 17 Oct 2023 17:30:28 +0200 Subject: [PATCH 45/46] Prefer higher-priority similar paths --- stack-graphs/src/cycles.rs | 12 +++++++----- stack-graphs/src/stitching.rs | 15 ++++++++++++++- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/stack-graphs/src/cycles.rs b/stack-graphs/src/cycles.rs index 51225a06a..eda31e171 100644 --- a/stack-graphs/src/cycles.rs +++ b/stack-graphs/src/cycles.rs @@ -31,6 +31,7 @@ use enumset::EnumSet; use smallvec::SmallVec; +use std::cmp::Ordering; use std::collections::HashMap; use crate::arena::Arena; @@ -97,22 +98,23 @@ where /// Determines whether we should process this path during the path-finding algorithm. If we have seen /// a path with the same start and end node, and the same pre- and postcondition, then we return false. /// Otherwise, we return true. - pub fn has_similar_path( + pub fn has_similar_path( &mut self, _graph: &StackGraph, arena: &mut P::Arena, path: &P, - eq: Eq, + cmp: Cmp, ) -> bool where - Eq: Fn(&mut P::Arena, &P, &P) -> bool, + Cmp: Fn(&mut P::Arena, &P, &P) -> Option, { let key = path.key(); let possibly_similar_paths = self.paths.entry(key).or_default(); for other_path in possibly_similar_paths.iter() { - if eq(arena, path, other_path) { - return true; + match cmp(arena, path, other_path) { + Some(ord) if ord != Ordering::Less => return true, + _ => continue, } } diff --git a/stack-graphs/src/stitching.rs b/stack-graphs/src/stitching.rs index 1a84db5ca..4872afe91 100644 --- a/stack-graphs/src/stitching.rs +++ b/stack-graphs/src/stitching.rs @@ -35,6 +35,7 @@ //! [`Database`]: struct.Database.html //! [`PathStitcher`]: struct.PathStitcher.html +use std::cmp::Ordering; use std::collections::HashMap; use std::collections::VecDeque; #[cfg(feature = "copious-debugging")] @@ -897,7 +898,19 @@ impl ForwardPartialPathStitcher { graph, partials, &new_partial_path, - |ps, left, right| left.equals(ps, right), + |ps, left, right| { + if !left.equals(ps, right) { + None + } else { + if left.shadows(ps, right) { + Some(Ordering::Less) + } else if right.shadows(ps, left) { + Some(Ordering::Greater) + } else { + Some(Ordering::Equal) + } + } + }, ) { copious_debugging!(" is rejected: too many similar"); continue; From 6fd2a98199ea14bf3cee2136a3ad49dc702dedc9 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Tue, 17 Oct 2023 17:32:31 +0200 Subject: [PATCH 46/46] Renable exponential blowup tests --- ..._statement_path_blowup.js.skip => if_statement_path_blowup.js} | 0 ...sion_path_blowup.js.skip => ternary_expression_path_blowup.js} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/{if_statement_path_blowup.js.skip => if_statement_path_blowup.js} (100%) rename languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/{ternary_expression_path_blowup.js.skip => ternary_expression_path_blowup.js} (100%) diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/if_statement_path_blowup.js.skip b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/if_statement_path_blowup.js similarity index 100% rename from languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/if_statement_path_blowup.js.skip rename to languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/if_statement_path_blowup.js diff --git a/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ternary_expression_path_blowup.js.skip b/languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ternary_expression_path_blowup.js similarity index 100% rename from languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ternary_expression_path_blowup.js.skip rename to languages/tree-sitter-stack-graphs-javascript/test/old/bug_regressions/ternary_expression_path_blowup.js