15
15
16
16
import { traverse , Visitor , Visitors } from 'estree-toolkit'
17
17
18
+ enum PolyfillType {
19
+ CallWithArguments ,
20
+ StaticMember ,
21
+ GenericMethod ,
22
+ GenericProperty ,
23
+ Global
24
+ }
25
+
26
+ const PT = PolyfillType
27
+ type ModuleName = string
28
+ type Arguments = any [ ]
29
+ type ModuleEntry = [ ModuleName , PolyfillType , string , ...Arguments ]
30
+
18
31
/**
19
32
* Core-Js 3.x contains some alias which will be removed with version 4.
20
33
* This maps those aliases to the correct modules
@@ -23,6 +36,9 @@ const aliasModules = {
23
36
'es.aggregate-error' : [
24
37
'es.aggregate-error.constructor'
25
38
] ,
39
+ 'es.data-view' : [
40
+ 'es.data-view.constructor'
41
+ ] ,
26
42
'es.map' : [
27
43
'es.map.constructor'
28
44
] ,
@@ -51,19 +67,8 @@ const aliasModules = {
51
67
'es.weak-map.constructor'
52
68
]
53
69
}
54
- enum PolyfillType {
55
- StaticMember ,
56
- GenericMethod ,
57
- GenericProperty ,
58
- Global
59
- }
60
-
61
- const PT = PolyfillType
62
- type ModuleName = string
63
- type Arguments = string [ ]
64
- type ModuleEntry = [ ModuleName , PolyfillType , ...Arguments ]
65
70
66
- const detectableModules : ModuleEntry [ ] = [
71
+ export const detectableModules : ModuleEntry [ ] = [
67
72
[ 'es.aggregate-error.cause' , PT . Global , 'AggregateError' ] ,
68
73
[ 'es.aggregate-error.constructor' , PT . Global , 'AggregateError' ] ,
69
74
// array buffer
@@ -88,6 +93,9 @@ const detectableModules: ModuleEntry[] = [
88
93
[ 'es.array.includes' , PT . GenericMethod , 'includes' ] ,
89
94
[ 'es.array.index-of' , PT . GenericMethod , 'indexOf' ] ,
90
95
[ 'es.array.is-array' , PT . StaticMember , 'Array' , 'isArray' ] ,
96
+ [ 'es.array.iterator' , PT . GenericMethod , 'entries' ] ,
97
+ [ 'es.array.iterator' , PT . GenericMethod , 'keys' ] ,
98
+ [ 'es.array.iterator' , PT . GenericMethod , 'values' ] ,
91
99
[ 'es.array.join' , PT . GenericMethod , 'join' ] ,
92
100
[ 'es.array.last-index-of' , PT . GenericMethod , 'lastIndexOf' ] ,
93
101
[ 'es.array.map' , PT . GenericMethod , 'map' ] ,
@@ -99,6 +107,7 @@ const detectableModules: ModuleEntry[] = [
99
107
[ 'es.array.slice' , PT . GenericMethod , 'slice' ] ,
100
108
[ 'es.array.some' , PT . GenericMethod , 'some' ] ,
101
109
[ 'es.array.sort' , PT . GenericMethod , 'sort' ] ,
110
+ [ 'es.array.splice' , PT . GenericMethod , 'splice' ] ,
102
111
[ 'es.array.to-reversed' , PT . GenericMethod , 'toReversed' ] ,
103
112
[ 'es.array.to-sorted' , PT . GenericMethod , 'toSorted' ] ,
104
113
[ 'es.array.to-spliced' , PT . GenericMethod , 'toSpliced' ] ,
@@ -107,6 +116,17 @@ const detectableModules: ModuleEntry[] = [
107
116
[ 'es.array.species' , PT . StaticMember , 'Symbol' , 'species' ] ,
108
117
// TODO: es.array.unscopables.flat-map
109
118
// TODO: es.array.unscopables.flat
119
+ // data-view
120
+ [ 'es.data-view.constructor' , PT . Global , 'DataView' ] ,
121
+ // error
122
+ // Not possible because toString might be called implicitly (template string):
123
+ // es.error.to-string
124
+ // function
125
+ [ 'es.function.bind' , PT . GenericMethod , 'bind' ] ,
126
+ [ 'es.function.has-instance' , PT . StaticMember , 'Symbol' , 'hasInstance' ] ,
127
+ [ 'es.function.name' , PT . GenericProperty , 'name' ] ,
128
+ // globalThis
129
+ [ 'es.global-this' , PT . Global , 'globalThis' ] ,
110
130
// json
111
131
[ 'es.json.stringify' , PT . StaticMember , 'JSON' , 'stringify' ] ,
112
132
// map
@@ -126,12 +146,12 @@ const detectableModules: ModuleEntry[] = [
126
146
[ 'es.promise.all' , PT . StaticMember , 'Promise' , 'all' ] ,
127
147
[ 'es.promise.all-settled' , PT . StaticMember , 'Promise' , 'allSettled' ] ,
128
148
[ 'es.promise.any' , PT . StaticMember , 'Promise' , 'any' , 'es.promise.any' ] ,
149
+ [ 'es.promise.catch' , PT . GenericMethod , 'catch' ] ,
129
150
[ 'es.promise.constructor' , PT . Global , 'Promise' ] ,
130
151
[ 'es.promise.race' , PT . StaticMember , 'Promise' , 'race' ] ,
131
152
[ 'es.promise.reject' , PT . StaticMember , 'Promise' , 'reject' ] ,
132
153
[ 'es.promise.resolve' , PT . StaticMember , 'Promise' , 'resolve' ] ,
133
154
[ 'es.promise.finally' , PT . GenericMethod , 'finally' ] ,
134
- // TODO: 'es.promise.catch',
135
155
// RegExp
136
156
[ 'es.regexp.constructor' , PT . Global , 'RegExp' ] ,
137
157
// TODO "es.regexp.dot-all"
@@ -184,6 +204,9 @@ const detectableModules: ModuleEntry[] = [
184
204
[ 'es.typed-array.to-sorted' , PT . GenericMethod , 'toSorted' ] ,
185
205
[ 'es.typed-array.to-string' , PT . GenericMethod , 'toString' ] ,
186
206
[ 'es.typed-array.with' , PT . GenericMethod , 'with' ] ,
207
+ // un-/escape
208
+ [ 'es.escape' , PT . Global , 'escape' ] ,
209
+ [ 'es.unescape' , PT . Global , 'unescape' ] ,
187
210
// Weak
188
211
[ 'es.weak-map.constructor' , PT . Global , 'WeakMap' ] ,
189
212
[ 'es.weak-set.constructor' , PT . Global , 'WeakSet' ] ,
@@ -222,6 +245,7 @@ const detectableModules: ModuleEntry[] = [
222
245
'es.math.expm1' ,
223
246
'es.math.fround' ,
224
247
'es.math.hypot' ,
248
+ 'es.math.imul' ,
225
249
'es.math.log10' ,
226
250
'es.math.log1p' ,
227
251
'es.math.log2' ,
@@ -233,11 +257,29 @@ const detectableModules: ModuleEntry[] = [
233
257
detectableModules . push ( [ m , PT . StaticMember , 'Math' , m . split ( '.' ) . at ( - 1 ) ] )
234
258
} ) ) ( ) ;
235
259
260
+ /**
261
+ * Init detection of error
262
+ */
263
+ ( ( ) => [
264
+ 'Error' ,
265
+ 'EvalError' ,
266
+ 'RangeError' ,
267
+ 'ReferenceError' ,
268
+ 'SyntaxError' ,
269
+ 'TypeError' ,
270
+ 'URIError' ,
271
+ 'CompileError' ,
272
+ 'LinkError' ,
273
+ 'RuntimeError'
274
+ ] . forEach ( error => {
275
+ detectableModules . push ( [ 'es.error.cause' , PT . CallWithArguments , error , ( args : Array < unknown > ) => args . length === 2 ] )
276
+ } ) ) ( ) ;
277
+
236
278
/**
237
279
* Init detection of static Number functions
238
280
*/
239
281
( ( ) => [
240
- [ 'es.number.is- epsilon' , 'EPSILON' ] ,
282
+ [ 'es.number.epsilon' , 'EPSILON' ] ,
241
283
[ 'es.number.is-finite' , 'isFinite' ] ,
242
284
[ 'es.number.is-integer' , 'isInteger' ] ,
243
285
[ 'es.number.is-nan' , 'isNaN' ] ,
@@ -252,15 +294,16 @@ const detectableModules: ModuleEntry[] = [
252
294
// TODO: es.number.to-precision
253
295
254
296
] . forEach ( ( [ mod , fn ] ) => {
255
- detectableModules . push ( [ mod [ 0 ] , PT . StaticMember , 'Number' , mod [ 1 ] ] )
256
- } ) ) ( ) ;
297
+ detectableModules . push ( [ mod , PT . StaticMember , 'Number' , fn ] )
298
+ } ) ) ( ) ;
257
299
258
300
class Walker {
259
301
_modules : string [ ] = [ ]
260
302
_globals = new Map < string , string > ( )
261
303
_methods = new Map < string , Array < string > >
262
304
_members = new Map < string , readonly string [ ] >
263
305
_properties = new Map < string , Array < string > >
306
+ _calls = new Map < string , Array < any > >
264
307
265
308
registerModules ( modules : ModuleEntry [ ] , filterModules : string [ ] ) {
266
309
const usedModules : string [ ] = [ ]
@@ -279,6 +322,9 @@ class Walker {
279
322
case PolyfillType . StaticMember :
280
323
this . registerMember ( name , rest [ 0 ] , rest [ 1 ] )
281
324
break
325
+ case PolyfillType . CallWithArguments :
326
+ this . registerCall ( name , rest [ 0 ] , rest [ 1 ] )
327
+ break
282
328
}
283
329
usedModules . push ( name )
284
330
}
@@ -308,6 +354,13 @@ class Walker {
308
354
this . _methods . get ( method ) . push ( module )
309
355
}
310
356
357
+ registerCall ( module : string , object : string , validator : ( args : Array < unknown > ) => boolean ) {
358
+ if ( ! this . _calls . has ( object ) ) {
359
+ this . _calls . set ( object , [ ] )
360
+ }
361
+ this . _calls . get ( object ) . push ( { module, validator } )
362
+ }
363
+
311
364
getVisitors ( ) : Visitors < any > {
312
365
return {
313
366
Program ( path , state : Walker ) {
@@ -318,6 +371,26 @@ class Walker {
318
371
} )
319
372
} ,
320
373
374
+ CallExpression ( path , state : Walker ) {
375
+ if ( path . node . callee . type === 'Identifier' ) {
376
+ if ( state . _calls . has ( path . node . callee . name ) ) {
377
+ state . _calls . get ( path . node . callee . name ) . forEach ( v => {
378
+ if ( v . validator ( path . node . arguments ) ) state . _modules . push ( v . module )
379
+ } )
380
+ }
381
+ }
382
+ } ,
383
+
384
+ NewExpression ( path , state : Walker ) {
385
+ if ( path . node . callee . type === 'Identifier' ) {
386
+ if ( state . _calls . has ( path . node . callee . name ) ) {
387
+ state . _calls . get ( path . node . callee . name ) . forEach ( v => {
388
+ if ( v . validator ( path . node . arguments ) ) state . _modules . push ( v . module )
389
+ } )
390
+ }
391
+ }
392
+ } ,
393
+
321
394
MemberExpression ( path , state : Walker ) {
322
395
if ( path . node . object . type === 'Identifier' ) {
323
396
const property = path . node . property . type === 'Identifier' ? path . node . property . name : ( path . node . property . type === 'Literal' && typeof path . node . property . value === 'string' ? path . node . property . value : undefined )
@@ -346,7 +419,7 @@ class Walker {
346
419
}
347
420
}
348
421
349
- export function filterModules ( modules : string [ ] , ast : any ) {
422
+ export function filterModules ( modules : readonly string [ ] , ast : any ) {
350
423
const realModules : string [ ] = [ ]
351
424
modules . forEach ( m => {
352
425
if ( m in aliasModules ) realModules . push ( ...aliasModules [ m ] )
@@ -361,144 +434,3 @@ export function filterModules(modules: string[], ast: any) {
361
434
} } ) , walker )
362
435
return [ ...( new Set ( walker . _modules ) ) ]
363
436
}
364
-
365
- /*
366
- "es.error.cause";
367
- "es.error.to-string";
368
- "es.aggregate-error";
369
- "es.aggregate-error.cause";
370
- "es.array.at";
371
- "es.array.concat";
372
- "es.array.copy-within";
373
- "es.array.fill";
374
- "es.array.filter";
375
- "es.array.find";
376
- "es.array.find-index";
377
- "es.array.find-last";
378
- "es.array.find-last-index";
379
- "es.array.flat";
380
- "es.array.flat-map";
381
- "es.array.from";
382
- "es.array.includes";
383
- "es.array.index-of";
384
- "es.array.iterator";
385
- "es.array.last-index-of";
386
- "es.array.map";
387
- "es.array.of";
388
- "es.array.push";
389
- "es.array.reduce";
390
- "es.array.reduce-right";
391
- "es.array.slice";
392
- "es.array.sort";
393
- "es.array.species";
394
- "es.array.splice";
395
- "es.array.to-reversed";
396
- "es.array.to-sorted";
397
- "es.array.to-spliced";
398
- "es.array.unscopables.flat";
399
- "es.array.unscopables.flat-map";
400
- "es.array.unshift";
401
- "es.array.with";
402
- "es.array-buffer.is-view";
403
- "es.array-buffer.slice";
404
- "es.date.to-primitive";
405
- "es.function.has-instance";
406
- "es.global-this";
407
- "eson.stringify";
408
- "eson.to-string-tag";
409
- "es.math.to-string-tag";
410
- "es.object.define-getter";
411
- "es.object.define-properties";
412
- "es.object.define-property";
413
- "es.object.define-setter";
414
- "es.object.entries";
415
- "es.object.freeze";
416
- "es.object.from-entries";
417
- "es.object.get-own-property-descriptor";
418
- "es.object.get-own-property-descriptors";
419
- "es.object.get-own-property-names";
420
- "es.object.get-prototype-of";
421
- "es.object.has-own";
422
- "es.object.is-extensible";
423
- "es.object.is-frozen";
424
- "es.object.is-sealed";
425
- "es.object.lookup-getter";
426
- "es.object.lookup-setter";
427
- "es.object.prevent-extensions";
428
- "es.object.seal";
429
- "es.object.set-prototype-of";
430
- "es.object.to-string";
431
- "es.reflect.apply";
432
- "es.reflect.construct";
433
- "es.reflect.define-property";
434
- "es.reflect.delete-property";
435
- "es.reflect.get";
436
- "es.reflect.get-own-property-descriptor";
437
- "es.reflect.get-prototype-of";
438
- "es.reflect.has";
439
- "es.reflect.is-extensible";
440
- "es.reflect.own-keys";
441
- "es.reflect.prevent-extensions";
442
- "es.reflect.set";
443
- "es.reflect.set-prototype-of";
444
- "es.reflect.to-string-tag";
445
- "es.string.at-alternative";
446
- "es.string.code-point-at";
447
- "es.string.ends-with";
448
- "es.string.from-code-point";
449
- "es.string.includes";
450
- "es.string.iterator";
451
- "es.string.match";
452
- "es.string.match-all";
453
- "es.string.pad-end";
454
- "es.string.pad-start";
455
- "es.string.raw";
456
- "es.string.repeat";
457
- "es.string.replace";
458
- "es.string.replace-all";
459
- "es.string.search";
460
- "es.string.split";
461
- "es.string.starts-with";
462
- "es.string.trim";
463
- "es.string.trim-end";
464
- "es.string.trim-start";
465
- "es.typed-array.float32-array";
466
- "es.typed-array.float64-array";
467
- "es.typed-array.int8-array";
468
- "es.typed-array.int16-array";
469
- "es.typed-array.int32-array";
470
- "es.typed-array.uint8-array";
471
- "es.typed-array.uint8-clamped-array";
472
- "es.typed-array.uint16-array";
473
- "es.typed-array.uint32-array";
474
- "es.typed-array.at";
475
- "es.typed-array.copy-within";
476
- "es.typed-array.every";
477
- "es.typed-array.fill";
478
- "es.typed-array.filter";
479
- "es.typed-array.find";
480
- "es.typed-array.find-index";
481
- "es.typed-array.find-last";
482
- "es.typed-array.find-last-index";
483
- "es.typed-array.for-each";
484
- "es.typed-array.from";
485
- "es.typed-array.includes";
486
- "es.typed-array.index-of";
487
- "es.typed-array.iterator";
488
- "es.typed-array.join";
489
- "es.typed-array.last-index-of";
490
- "es.typed-array.map";
491
- "es.typed-array.of";
492
- "es.typed-array.reduce";
493
- "es.typed-array.reduce-right";
494
- "es.typed-array.reverse";
495
- "es.typed-array.set";
496
- "es.typed-array.slice";
497
- "es.typed-array.some";
498
- "es.typed-array.sort";
499
- "es.typed-array.to-locale-string";
500
- "es.typed-array.to-reversed";
501
- "es.typed-array.to-sorted";
502
- "es.typed-array.to-string";
503
- "es.typed-array.with.js";
504
- */
0 commit comments