5
5
;; Global Variables
6
6
;; ^^^^^^^^^^^^^^^^
7
7
8
- global FILE_PATH
9
8
global ROOT_NODE
10
9
global JUMP_TO_SCOPE_NODE
11
10
11
+ global FILE_PATH
12
+ global PROJECT_NAME = ""
13
+
12
14
13
15
;; Attribute Shorthands
14
16
;; ^^^^^^^^^^^^^^^^^^^^
@@ -232,7 +234,8 @@ attribute node_symbol = node => symbol = (source-text node), source_n
232
234
;; - `GUARD:RETURN` - used for the AST nodes for values returned by a function
233
235
;; in the function body
234
236
;; - `GUARD:THIS` - used for the implicit `this` argument of a function inside
235
- ;; its body
237
+ ;; - `GUARD:PKG_INTERNAL` - used for the package internal structure that should not
238
+ ;; be accessible directly from the root
236
239
237
240
; ## Inherited
238
241
@@ -244,10 +247,12 @@ inherit .builtins_null
244
247
inherit .builtins_number
245
248
inherit .builtins_string
246
249
inherit .builtins_undefined
247
- inherit .exports
248
- inherit .return_or_yield
249
250
inherit .class_value
250
251
inherit .constructor
252
+ inherit .exports
253
+ inherit .pkg_pop
254
+ inherit .pkg_push
255
+ inherit .return_or_yield
251
256
252
257
253
258
@@ -281,21 +286,50 @@ inherit .constructor
281
286
node prog_module_pop
282
287
node prog_module_scope
283
288
node prog_exports_pop
289
+ node prog_pkg_pop_guard
290
+ node prog_pkg_push_guard
291
+ node prog_legacy_qname_guard
284
292
node @prog.exports
285
-
286
- scan FILE_PATH {
287
- "([^/]+)\.js$" {
288
- attr (prog_module_pop) symbol_definition = $1, source_node = @prog
289
- }
293
+ node @prog.pkg_pop
294
+ node @prog.pkg_push
295
+
296
+ attr (prog_pkg_pop_guard) pop_symbol = "GUARD:PKG_INTERNAL"
297
+ attr (@prog.pkg_pop) pop_symbol = PROJECT_NAME
298
+ edge ROOT_NODE -> prog_pkg_pop_guard
299
+ edge prog_pkg_pop_guard -> @prog.pkg_pop
300
+
301
+ attr (@prog.pkg_push) push_symbol = PROJECT_NAME
302
+ attr (prog_pkg_push_guard) push_symbol = "GUARD:PKG_INTERNAL"
303
+ edge @prog.pkg_push -> prog_pkg_push_guard
304
+ edge prog_pkg_push_guard -> ROOT_NODE
305
+
306
+ node prog_module_pop_start
307
+ var module_pop_end = prog_module_pop_start
308
+ let module_name = (replace FILE_PATH "\.js$" "")
309
+ scan module_name {
310
+ "([^/]+)/" {
311
+ attr (module_pop_end) pop_symbol = $1
312
+ node module_pop_end_next
313
+ edge module_pop_end -> module_pop_end_next
314
+ set module_pop_end = module_pop_end_next
315
+ }
316
+ "([^/]+)$" {
317
+ attr (module_pop_end) symbol_definition = $1, source_node = @prog
318
+ attr (module_pop_end) empty_source_span
319
+ }
290
320
}
291
321
292
- edge @prog.before_scope -> ROOT_NODE
322
+ edge @prog.before_scope -> @prog.pkg_push
293
323
294
324
attr (prog_module_scope) pop_symbol = "GUARD:MODULE"
295
- edge ROOT_NODE -> prog_module_pop
325
+ edge @prog.pkg_pop -> prog_module_pop_start
296
326
edge prog_module_pop -> prog_module_scope
297
327
edge prog_module_scope -> @prog.after_scope
298
328
329
+ attr (prog_legacy_qname_guard) push_symbol = "GUARD:LEGACY_QNAME"
330
+ edge @prog.before_scope -> prog_legacy_qname_guard
331
+ edge prog_legacy_qname_guard -> ROOT_NODE
332
+
299
333
attr (prog_module_pop) empty_source_span
300
334
attr (prog_module_scope) empty_source_span
301
335
attr (@prog.exports) empty_source_span
@@ -307,6 +341,10 @@ inherit .constructor
307
341
edge prog_module_pop -> prog_exports_pop
308
342
edge prog_exports_pop -> @prog.exports
309
343
344
+ ; allow direct access from the package to the modules exports
345
+ ; this is used from package.json
346
+ edge @prog.pkg_pop -> prog_exports_pop
347
+
310
348
;; builtin types
311
349
node @prog.builtins_number
312
350
node @prog.builtins_string
@@ -895,7 +933,7 @@ inherit .constructor
895
933
; attr (@mod_name.push) symbol_reference = $1, source_node = @mod_name
896
934
; }
897
935
; }
898
- ; edge @mod_name.push -> ROOT_NODE
936
+ ; edge @mod_name.push -> @import_stmt.pkg_push
899
937
;
900
938
; attr (@name) node_reference = @name
901
939
; attr (name_push_dot) push_symbol = "GUARD:MEMBER"
@@ -3746,6 +3784,26 @@ inherit .constructor
3746
3784
3747
3785
}
3748
3786
3787
+ ;; ## ES6-style Imports
3788
+
3789
+ ;; ES6 modules can also be imported using an import function. In general,
3790
+ ;; these look like `require(expr)`, but in practice the expression is a string
3791
+ ;; constant, which is the only case we handle.
3792
+
3793
+ (
3794
+ (call_expression
3795
+ function:(_)@_import
3796
+ arguments:(arguments (string)@source))@call_expr
3797
+ (#eq? @_import "import")
3798
+ ) {
3799
+
3800
+ node call_expr_pop_dot
3801
+
3802
+ attr (call_expr_pop_dot) pop_symbol = "GUARD:MEMBER"
3803
+ edge @call_expr.value -> call_expr_pop_dot
3804
+ edge call_expr_pop_dot -> @source.exports
3805
+ }
3806
+
3749
3807
;; ### CommonJS-style Exports
3750
3808
3751
3809
;; CommonJS introduced an export style for pre-ES6 JavaScript that permitted
@@ -3803,25 +3861,10 @@ inherit .constructor
3803
3861
(
3804
3862
(call_expression
3805
3863
function:(_)@_require
3806
- arguments:(arguments (string)@mod_name ))@call_expr
3864
+ arguments:(arguments (string)@source ))@call_expr
3807
3865
(#eq? @_require "require")
3808
3866
) {
3809
-
3810
- node mod_name_module_guard
3811
- node mod_name_push
3812
-
3813
- scan (source-text @mod_name) {
3814
- "\"([^/\"]+)\.js\"$" {
3815
- attr (mod_name_push) push_symbol = $1
3816
- }
3817
- }
3818
-
3819
-
3820
- attr (mod_name_module_guard) push_symbol = "GUARD:EXPORTS"
3821
- edge @call_expr.value -> mod_name_module_guard
3822
- edge mod_name_module_guard -> mod_name_push
3823
- edge mod_name_push -> ROOT_NODE
3824
-
3867
+ edge @call_expr.value -> @source.exports
3825
3868
}
3826
3869
3827
3870
0 commit comments