1+ /* globals BigInt */
2+
13import { findVariable } from "./find-variable"
24
35const builtinNames = Object . freeze (
@@ -14,9 +16,7 @@ const builtinNames = Object.freeze(
1416 "decodeURIComponent" ,
1517 "encodeURI" ,
1618 "encodeURIComponent" ,
17- "Error" ,
1819 "escape" ,
19- "EvalError" ,
2020 "Float32Array" ,
2121 "Float64Array" ,
2222 "Function" ,
@@ -37,26 +37,97 @@ const builtinNames = Object.freeze(
3737 "parseInt" ,
3838 "Promise" ,
3939 "Proxy" ,
40- "RangeError" ,
41- "ReferenceError" ,
4240 "Reflect" ,
4341 "RegExp" ,
4442 "Set" ,
4543 "String" ,
4644 "Symbol" ,
47- "SyntaxError" ,
48- "TypeError" ,
4945 "Uint16Array" ,
5046 "Uint32Array" ,
5147 "Uint8Array" ,
5248 "Uint8ClampedArray" ,
5349 "undefined" ,
5450 "unescape" ,
55- "URIError" ,
5651 "WeakMap" ,
5752 "WeakSet" ,
5853 ] )
5954)
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+ }
60131
61132/**
62133 * Get the element values of a given node list.
@@ -176,13 +247,23 @@ const operations = Object.freeze({
176247 if ( object != null && property != null ) {
177248 const receiver = object . value
178249 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+ }
180256 }
181257 } else {
182258 const callee = getStaticValueR ( calleeNode , initialScope )
183259 if ( callee != null ) {
184260 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+ }
186267 }
187268 }
188269 }
@@ -240,7 +321,7 @@ const operations = Object.freeze({
240321 // It was a RegExp/BigInt literal, but Node.js didn't support it.
241322 return null
242323 }
243- return node
324+ return { value : node . value }
244325 } ,
245326
246327 LogicalExpression ( node , initialScope ) {
@@ -268,7 +349,11 @@ const operations = Object.freeze({
268349 ? getStaticValueR ( node . property , initialScope )
269350 : { value : node . property . name }
270351
271- if ( object != null && property != null ) {
352+ if (
353+ object != null &&
354+ property != null &&
355+ ! isGetter ( object . value , property . value )
356+ ) {
272357 return { value : object . value [ property . value ] }
273358 }
274359 return null
@@ -280,7 +365,9 @@ const operations = Object.freeze({
280365
281366 if ( callee != null && args != null ) {
282367 const Func = callee . value
283- return { value : new Func ( ...args ) }
368+ if ( callAllowed . has ( Func ) ) {
369+ return { value : new Func ( ...args ) }
370+ }
284371 }
285372
286373 return null
@@ -339,7 +426,9 @@ const operations = Object.freeze({
339426 const strings = node . quasi . quasis . map ( q => q . value . cooked )
340427 strings . raw = node . quasi . quasis . map ( q => q . value . raw )
341428
342- return { value : func ( strings , ...expressions ) }
429+ if ( func === String . raw ) {
430+ return { value : func ( strings , ...expressions ) }
431+ }
343432 }
344433
345434 return null
0 commit comments