-
-
Save suyanhanx/59ea1bf1cb233d2f824df16e723b4452 to your computer and use it in GitHub Desktop.
js get free variables hack
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* some insane hack, just want to avoid using expensive parser. | |
*/ | |
export function getFreeVariables(expr:string, knownSymbols:Record<string,unknown>){ | |
const freeVariables = new Set<string>(); | |
//eslint-disable-next-line | |
const anyThingPrimitive = ()=>{}; | |
Object.defineProperties(anyThingPrimitive, { | |
[Symbol.toPrimitive]:{ | |
value: ()=>{ | |
return 1 | |
}, | |
}, | |
[Symbol.toStringTag]:{ | |
value: ()=>{ | |
return "" | |
} | |
} | |
}) | |
const anyThing2:unknown = new Proxy(anyThingPrimitive,{ | |
get(target, prop){ | |
if(prop === Symbol.unscopables){ | |
return undefined | |
} | |
if(prop in target){ | |
return (target as unknown as Record<string,unknown>)[prop as string] | |
} | |
return anyThing2 | |
}, | |
apply(target, thisArg, args){ | |
return anyThing2 | |
} | |
}) | |
const anyThing = new Proxy(anyThingPrimitive,{ | |
has(target, prop){ | |
if(prop === 'unsafe___THIS____func'){ | |
return false | |
} | |
if(prop === 'arguments'){ | |
return false | |
} | |
if(prop in knownSymbols){ | |
return false | |
} | |
return true; | |
}, | |
get(target, prop){ | |
if(prop === Symbol.unscopables){ | |
return undefined | |
} | |
if(prop in target){ | |
return (target as unknown as Record<string,unknown>)[prop as string] | |
} | |
freeVariables.add(prop as string) | |
return anyThing2 | |
}, | |
apply(target, thisArg, args){ | |
return anyThing2 | |
} | |
}) | |
{ | |
const unsafe___THIS____func = new Function(`with (arguments[0]) { with (arguments[1]) { return ${expr} } }`); | |
unsafe___THIS____func(anyThing, knownSymbols); | |
} | |
return [...freeVariables]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment