@@ -2,6 +2,8 @@ import assert from "node:assert/strict";
2
2
import { describe , it } from "node:test" ;
3
3
import astGrep from "@ast-grep/napi" ;
4
4
import dedent from "dedent" ;
5
+ import type Js from "@codemod.com/jssg-types/langs/javascript" ;
6
+ import type { SgNode } from "@codemod.com/jssg-types/main" ;
5
7
6
8
import { resolveBindingPath } from "./resolve-binding-path.ts" ;
7
9
@@ -12,7 +14,7 @@ describe("resolve-binding-path", () => {
12
14
` ;
13
15
14
16
const rootNode = astGrep . parse ( astGrep . Lang . JavaScript , code ) ;
15
- const importStatement = rootNode . root ( ) . find ( {
17
+ const importStatement = ( rootNode . root ( ) as SgNode < Js > ) . find ( {
16
18
rule : {
17
19
kind : "lexical_declaration" ,
18
20
} ,
@@ -23,13 +25,30 @@ describe("resolve-binding-path", () => {
23
25
assert . strictEqual ( bindingPath , "util.types.isNativeError" ) ;
24
26
} ) ;
25
27
28
+ it ( "should be able to resolve binding path from namespace ESM import" , ( ) => {
29
+ const code = dedent `
30
+ import foo from "node:foo"
31
+ ` ;
32
+
33
+ const rootNode = astGrep . parse ( astGrep . Lang . JavaScript , code ) ;
34
+ const importStatement = ( rootNode . root ( ) as SgNode < Js > ) . find ( {
35
+ rule : {
36
+ kind : "import_statement" ,
37
+ } ,
38
+ } ) ;
39
+
40
+ const bindingPath = resolveBindingPath ( importStatement ! , "$.bar" ) ;
41
+
42
+ assert . strictEqual ( bindingPath , "foo.bar" ) ;
43
+ } ) ;
44
+
26
45
it ( "should be able to solve binding path when destructuring happen" , ( ) => {
27
46
const code = dedent `
28
47
const { types } = require('node:util');
29
48
` ;
30
49
31
50
const rootNode = astGrep . parse ( astGrep . Lang . JavaScript , code ) ;
32
- const importStatement = rootNode . root ( ) . find ( {
51
+ const importStatement = ( rootNode . root ( ) as SgNode < Js > ) . find ( {
33
52
rule : {
34
53
kind : "variable_declarator" ,
35
54
} ,
@@ -46,7 +65,7 @@ describe("resolve-binding-path", () => {
46
65
` ;
47
66
48
67
const rootNode = astGrep . parse ( astGrep . Lang . JavaScript , code ) ;
49
- const requireStatement = rootNode . root ( ) . find ( {
68
+ const requireStatement = ( rootNode . root ( ) as SgNode < Js > ) . find ( {
50
69
rule : {
51
70
kind : "variable_declarator" ,
52
71
} ,
@@ -63,7 +82,7 @@ describe("resolve-binding-path", () => {
63
82
` ;
64
83
65
84
const rootNode = astGrep . parse ( astGrep . Lang . JavaScript , code ) ;
66
- const importStatement = rootNode . root ( ) . find ( {
85
+ const importStatement = ( rootNode . root ( ) as SgNode < Js > ) . find ( {
67
86
rule : {
68
87
kind : "variable_declarator" ,
69
88
} ,
@@ -80,7 +99,7 @@ describe("resolve-binding-path", () => {
80
99
` ;
81
100
82
101
const rootNode = astGrep . parse ( astGrep . Lang . JavaScript , code ) ;
83
- const functionDeclaration = rootNode . root ( ) . find ( {
102
+ const functionDeclaration = ( rootNode . root ( ) as SgNode < Js > ) . find ( {
84
103
rule : {
85
104
kind : "function_declaration" ,
86
105
} ,
@@ -95,7 +114,7 @@ describe("resolve-binding-path", () => {
95
114
` ;
96
115
97
116
const rootNode = astGrep . parse ( astGrep . Lang . JavaScript , code ) ;
98
- const importStatement = rootNode . root ( ) . find ( {
117
+ const importStatement = ( rootNode . root ( ) as SgNode < Js > ) . find ( {
99
118
rule : {
100
119
kind : "import_statement" ,
101
120
} ,
@@ -112,7 +131,7 @@ describe("resolve-binding-path", () => {
112
131
` ;
113
132
114
133
const rootNode = astGrep . parse ( astGrep . Lang . JavaScript , code ) ;
115
- const importStatement = rootNode . root ( ) . find ( {
134
+ const importStatement = ( rootNode . root ( ) as SgNode < Js > ) . find ( {
116
135
rule : {
117
136
kind : "import_statement" ,
118
137
} ,
@@ -129,7 +148,7 @@ describe("resolve-binding-path", () => {
129
148
` ;
130
149
131
150
const rootNode = astGrep . parse ( astGrep . Lang . JavaScript , code ) ;
132
- const importStatement = rootNode . root ( ) . find ( {
151
+ const importStatement = ( rootNode . root ( ) as SgNode < Js > ) . find ( {
133
152
rule : {
134
153
kind : "import_statement" ,
135
154
} ,
@@ -146,7 +165,7 @@ describe("resolve-binding-path", () => {
146
165
` ;
147
166
148
167
const rootNode = astGrep . parse ( astGrep . Lang . JavaScript , code ) ;
149
- const importStatement = rootNode . root ( ) . find ( {
168
+ const importStatement = ( rootNode . root ( ) as SgNode < Js > ) . find ( {
150
169
rule : {
151
170
kind : "import_statement" ,
152
171
} ,
@@ -163,7 +182,7 @@ describe("resolve-binding-path", () => {
163
182
` ;
164
183
165
184
const rootNode = astGrep . parse ( astGrep . Lang . JavaScript , code ) ;
166
- const requireStatement = rootNode . root ( ) . find ( {
185
+ const requireStatement = ( rootNode . root ( ) as SgNode < Js > ) . find ( {
167
186
rule : {
168
187
kind : "variable_declarator" ,
169
188
} ,
@@ -180,7 +199,7 @@ describe("resolve-binding-path", () => {
180
199
` ;
181
200
182
201
const rootNode = astGrep . parse ( astGrep . Lang . JavaScript , code ) ;
183
- const importStatement = rootNode . root ( ) . find ( {
202
+ const importStatement = ( rootNode . root ( ) as SgNode < Js > ) . find ( {
184
203
rule : {
185
204
kind : "lexical_declaration" ,
186
205
} ,
@@ -197,7 +216,7 @@ describe("resolve-binding-path", () => {
197
216
` ;
198
217
199
218
const rootNode = astGrep . parse ( astGrep . Lang . JavaScript , code ) ;
200
- const importStatement = rootNode . root ( ) . find ( {
219
+ const importStatement = ( rootNode . root ( ) as SgNode < Js > ) . find ( {
201
220
rule : {
202
221
kind : "import_statement" ,
203
222
} ,
@@ -214,7 +233,7 @@ describe("resolve-binding-path", () => {
214
233
` ;
215
234
216
235
const rootNode = astGrep . parse ( astGrep . Lang . JavaScript , code ) ;
217
- const requireStatement = rootNode . root ( ) . find ( {
236
+ const requireStatement = ( rootNode . root ( ) as SgNode < Js > ) . find ( {
218
237
rule : {
219
238
kind : "variable_declarator" ,
220
239
} ,
@@ -231,7 +250,7 @@ describe("resolve-binding-path", () => {
231
250
` ;
232
251
233
252
const rootNode = astGrep . parse ( astGrep . Lang . JavaScript , code ) ;
234
- const requireStatement = rootNode . root ( ) . find ( {
253
+ const requireStatement = ( rootNode . root ( ) as SgNode < Js > ) . find ( {
235
254
rule : {
236
255
kind : "variable_declarator" ,
237
256
} ,
@@ -248,7 +267,7 @@ describe("resolve-binding-path", () => {
248
267
` ;
249
268
250
269
const rootNode = astGrep . parse ( astGrep . Lang . JavaScript , code ) ;
251
- const requireStatement = rootNode . root ( ) . find ( {
270
+ const requireStatement = ( rootNode . root ( ) as SgNode < Js > ) . find ( {
252
271
rule : {
253
272
kind : "variable_declarator" ,
254
273
} ,
@@ -265,7 +284,8 @@ describe("resolve-binding-path", () => {
265
284
` ;
266
285
267
286
const rootNode = astGrep . parse ( astGrep . Lang . JavaScript , code ) ;
268
- const requireStatement = rootNode . root ( ) . find ( {
287
+
288
+ const requireStatement = ( rootNode . root ( ) as SgNode < Js > ) . find ( {
269
289
rule : {
270
290
kind : "variable_declarator" ,
271
291
} ,
@@ -275,4 +295,89 @@ describe("resolve-binding-path", () => {
275
295
276
296
assert . strictEqual ( bindingPath , "types.isNativeError" ) ;
277
297
} ) ;
298
+
299
+ it ( "should resolve correctly when have member-expression" , ( ) => {
300
+ const code = dedent `
301
+ const SlowBuffer = require('buffer').SlowBuffer;
302
+ ` ;
303
+
304
+ const rootNode = astGrep . parse ( astGrep . Lang . JavaScript , code ) ;
305
+ const requireStatement = ( rootNode . root ( ) as SgNode < Js > ) . find ( {
306
+ rule : {
307
+ kind : "variable_declarator" ,
308
+ } ,
309
+ } ) ;
310
+
311
+ const bindingPath = resolveBindingPath ( requireStatement ! , "$.SlowBuffer" ) ;
312
+
313
+ assert . strictEqual ( bindingPath , "SlowBuffer" ) ;
314
+ } ) ;
315
+
316
+ it ( "should resolve correctly when there are multiple property accesses" , ( ) => {
317
+ const code = dedent `
318
+ const variable = require('buffer').a.b;
319
+ ` ;
320
+
321
+ const rootNode = astGrep . parse ( astGrep . Lang . JavaScript , code ) ;
322
+ const requireStatement = ( rootNode . root ( ) as SgNode < Js > ) . find ( {
323
+ rule : {
324
+ kind : "variable_declarator" ,
325
+ } ,
326
+ } ) ;
327
+
328
+ const bindingPath = resolveBindingPath ( requireStatement ! , "$.a.b" ) ;
329
+
330
+ assert . strictEqual ( bindingPath , "variable" ) ;
331
+ } ) ;
332
+
333
+ it ( "should resolve correctly when there are multiple property accesses but not the entire path" , ( ) => {
334
+ const code = dedent `
335
+ const variable = require('buffer').a.b;
336
+ ` ;
337
+
338
+ const rootNode = astGrep . parse ( astGrep . Lang . JavaScript , code ) ;
339
+ const requireStatement = ( rootNode . root ( ) as SgNode < Js > ) . find ( {
340
+ rule : {
341
+ kind : "variable_declarator" ,
342
+ } ,
343
+ } ) ;
344
+
345
+ const bindingPath = resolveBindingPath ( requireStatement ! , "$.a.b.c.d.e" ) ;
346
+
347
+ assert . strictEqual ( bindingPath , "variable.c.d.e" ) ;
348
+ } ) ;
349
+
350
+ it ( "should resolve correctly when there are multiple property accesses and destructuring" , ( ) => {
351
+ const code = dedent `
352
+ const { c: { d } } = require('buffer').a.b;
353
+ ` ;
354
+
355
+ const rootNode = astGrep . parse ( astGrep . Lang . JavaScript , code ) ;
356
+ const requireStatement = ( rootNode . root ( ) as SgNode < Js > ) . find ( {
357
+ rule : {
358
+ kind : "variable_declarator" ,
359
+ } ,
360
+ } ) ;
361
+
362
+ const bindingPath = resolveBindingPath ( requireStatement ! , "$.a.b.c.d.e" ) ;
363
+
364
+ assert . strictEqual ( bindingPath , "d.e" ) ;
365
+ } ) ;
366
+
367
+ it ( "should resolve as undefined when property accesses is different than path to solve" , ( ) => {
368
+ const code = dedent `
369
+ const c = require('buffer').a.g.c;
370
+ ` ;
371
+
372
+ const rootNode = astGrep . parse ( astGrep . Lang . JavaScript , code ) ;
373
+ const requireStatement = ( rootNode . root ( ) as SgNode < Js > ) . find ( {
374
+ rule : {
375
+ kind : "variable_declarator" ,
376
+ } ,
377
+ } ) ;
378
+
379
+ const bindingPath = resolveBindingPath ( requireStatement ! , "$.a.b.c.d.e" ) ;
380
+
381
+ assert . strictEqual ( bindingPath , undefined ) ;
382
+ } ) ;
278
383
} ) ;
0 commit comments