1
+ /* globals BigInt */
2
+
1
3
import { findVariable } from "./find-variable"
2
4
3
5
const builtinNames = Object . freeze (
@@ -14,9 +16,7 @@ const builtinNames = Object.freeze(
14
16
"decodeURIComponent" ,
15
17
"encodeURI" ,
16
18
"encodeURIComponent" ,
17
- "Error" ,
18
19
"escape" ,
19
- "EvalError" ,
20
20
"Float32Array" ,
21
21
"Float64Array" ,
22
22
"Function" ,
@@ -37,26 +37,97 @@ const builtinNames = Object.freeze(
37
37
"parseInt" ,
38
38
"Promise" ,
39
39
"Proxy" ,
40
- "RangeError" ,
41
- "ReferenceError" ,
42
40
"Reflect" ,
43
41
"RegExp" ,
44
42
"Set" ,
45
43
"String" ,
46
44
"Symbol" ,
47
- "SyntaxError" ,
48
- "TypeError" ,
49
45
"Uint16Array" ,
50
46
"Uint32Array" ,
51
47
"Uint8Array" ,
52
48
"Uint8ClampedArray" ,
53
49
"undefined" ,
54
50
"unescape" ,
55
- "URIError" ,
56
51
"WeakMap" ,
57
52
"WeakSet" ,
58
53
] )
59
54
)
55
+ const callAllowed = new Set (
56
+ [
57
+ Array . isArray ,
58
+ typeof BigInt === "function" ? BigInt : undefined ,
59
+ Boolean ,
60
+ Date ,
61
+ Date . parse ,
62
+ decodeURI ,
63
+ decodeURIComponent ,
64
+ encodeURI ,
65
+ encodeURIComponent ,
66
+ escape ,
67
+ isFinite ,
68
+ isNaN ,
69
+ isPrototypeOf ,
70
+ ...Object . getOwnPropertyNames ( Math )
71
+ . map ( k => Math [ k ] )
72
+ . filter ( f => typeof f === "function" ) ,
73
+ Number ,
74
+ Number . isFinite ,
75
+ Number . isNaN ,
76
+ Number . parseFloat ,
77
+ Number . parseInt ,
78
+ Object ,
79
+ Object . entries , //eslint-disable-line @mysticatea/node/no-unsupported-features/es-builtins
80
+ Object . is ,
81
+ Object . isExtensible ,
82
+ Object . isFrozen ,
83
+ Object . isSealed ,
84
+ Object . keys ,
85
+ Object . values , //eslint-disable-line @mysticatea/node/no-unsupported-features/es-builtins
86
+ parseFloat ,
87
+ parseInt ,
88
+ RegExp ,
89
+ String ,
90
+ String . fromCharCode ,
91
+ String . fromCodePoint ,
92
+ String . raw ,
93
+ Symbol ,
94
+ Symbol . for ,
95
+ Symbol . keyFor ,
96
+ unescape ,
97
+ ] . filter ( f => typeof f === "function" )
98
+ )
99
+ const callPassThrough = new Set ( [
100
+ Object . freeze ,
101
+ Object . preventExtensions ,
102
+ Object . seal ,
103
+ ] )
104
+
105
+ /**
106
+ * Get the property descriptor.
107
+ * @param {object } object The object to get.
108
+ * @param {string|number|symbol } name The property name to get.
109
+ */
110
+ function getPropertyDescriptor ( object , name ) {
111
+ let x = object
112
+ while ( ( typeof x === "object" || typeof x === "function" ) && x !== null ) {
113
+ const d = Object . getOwnPropertyDescriptor ( x , name )
114
+ if ( d ) {
115
+ return d
116
+ }
117
+ x = Object . getPrototypeOf ( x )
118
+ }
119
+ return null
120
+ }
121
+
122
+ /**
123
+ * Check if a property is getter or not.
124
+ * @param {object } object The object to check.
125
+ * @param {string|number|symbol } name The property name to check.
126
+ */
127
+ function isGetter ( object , name ) {
128
+ const d = getPropertyDescriptor ( object , name )
129
+ return d != null && d . get != null
130
+ }
60
131
61
132
/**
62
133
* Get the element values of a given node list.
@@ -176,13 +247,23 @@ const operations = Object.freeze({
176
247
if ( object != null && property != null ) {
177
248
const receiver = object . value
178
249
const methodName = property . value
179
- return { value : receiver [ methodName ] ( ...args ) }
250
+ if ( callAllowed . has ( receiver [ methodName ] ) ) {
251
+ return { value : receiver [ methodName ] ( ...args ) }
252
+ }
253
+ if ( callPassThrough . has ( receiver [ methodName ] ) ) {
254
+ return { value : args [ 0 ] }
255
+ }
180
256
}
181
257
} else {
182
258
const callee = getStaticValueR ( calleeNode , initialScope )
183
259
if ( callee != null ) {
184
260
const func = callee . value
185
- return { value : func ( ...args ) }
261
+ if ( callAllowed . has ( func ) ) {
262
+ return { value : func ( ...args ) }
263
+ }
264
+ if ( callPassThrough . has ( func ) ) {
265
+ return { value : args [ 0 ] }
266
+ }
186
267
}
187
268
}
188
269
}
@@ -240,7 +321,7 @@ const operations = Object.freeze({
240
321
// It was a RegExp/BigInt literal, but Node.js didn't support it.
241
322
return null
242
323
}
243
- return node
324
+ return { value : node . value }
244
325
} ,
245
326
246
327
LogicalExpression ( node , initialScope ) {
@@ -268,7 +349,11 @@ const operations = Object.freeze({
268
349
? getStaticValueR ( node . property , initialScope )
269
350
: { value : node . property . name }
270
351
271
- if ( object != null && property != null ) {
352
+ if (
353
+ object != null &&
354
+ property != null &&
355
+ ! isGetter ( object . value , property . value )
356
+ ) {
272
357
return { value : object . value [ property . value ] }
273
358
}
274
359
return null
@@ -280,7 +365,9 @@ const operations = Object.freeze({
280
365
281
366
if ( callee != null && args != null ) {
282
367
const Func = callee . value
283
- return { value : new Func ( ...args ) }
368
+ if ( callAllowed . has ( Func ) ) {
369
+ return { value : new Func ( ...args ) }
370
+ }
284
371
}
285
372
286
373
return null
@@ -339,7 +426,9 @@ const operations = Object.freeze({
339
426
const strings = node . quasi . quasis . map ( q => q . value . cooked )
340
427
strings . raw = node . quasi . quasis . map ( q => q . value . raw )
341
428
342
- return { value : func ( strings , ...expressions ) }
429
+ if ( func === String . raw ) {
430
+ return { value : func ( strings , ...expressions ) }
431
+ }
343
432
}
344
433
345
434
return null
0 commit comments