handle "static" contexts in es7.functionBind - #1518
This commit is contained in:
@@ -10,11 +10,23 @@ export var metadata = {
|
||||
function getTempId(scope) {
|
||||
var id = scope.path.getData("functionBind");
|
||||
if (id) return id;
|
||||
|
||||
id = scope.generateTemp("context");
|
||||
return scope.path.setData("functionBind", id);
|
||||
}
|
||||
|
||||
function getStaticContext(bind, scope) {
|
||||
if (bind.object) {
|
||||
return scope.isStatic(bind.object) && bind.object;
|
||||
} else {
|
||||
return scope.isStatic(bind.callee.object) && bind.callee.object;
|
||||
}
|
||||
}
|
||||
|
||||
function inferBindContext(bind, scope) {
|
||||
var staticContext = getStaticContext(bind, scope);
|
||||
if (staticContext) return staticContext;
|
||||
|
||||
var tempId = getTempId(scope);
|
||||
if (bind.object) {
|
||||
bind.callee = t.sequenceExpression([
|
||||
@@ -30,6 +42,7 @@ function inferBindContext(bind, scope) {
|
||||
export function CallExpression(node, parent, scope, file) {
|
||||
var bind = node.callee;
|
||||
if (!t.isBindExpression(bind)) return;
|
||||
|
||||
var context = inferBindContext(bind, scope);
|
||||
node.callee = t.memberExpression(bind.callee, t.identifier("call"));
|
||||
node.arguments.unshift(context);
|
||||
|
||||
@@ -263,18 +263,34 @@ export default class Scope {
|
||||
return this.generateUidIdentifier(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether evaluating the specific input `node` is a consequenceless reference. ie.
|
||||
* evaluating it wont result in potentially arbitrary code from being ran. The following are
|
||||
* whitelisted and determined not cause side effects:
|
||||
*
|
||||
* - `this` expressions
|
||||
* - `super` expressions
|
||||
* - Bound identifiers
|
||||
*/
|
||||
|
||||
isStatic(node: Object): boolean {
|
||||
if (t.isThisExpression(node) || t.isSuper(node)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t.isIdentifier(node) && this.hasBinding(node.name)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
|
||||
generateMemoisedReference(node: Object, dontPush?: boolean): ?Object {
|
||||
if (t.isThisExpression(node) || t.isSuper(node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (t.isIdentifier(node) && this.hasBinding(node.name)) {
|
||||
return null;
|
||||
}
|
||||
if (this.isStatic(node)) return null;
|
||||
|
||||
var id = this.generateUidBasedOnNode(node);
|
||||
if (!dontPush) this.push({ id });
|
||||
|
||||
Reference in New Issue
Block a user