Fix reused nodes - part 2 (#7149)
This commit is contained in:
parent
912bcc186d
commit
252ea5a966
@ -131,7 +131,7 @@ export default class File {
|
||||
const res = generator(name);
|
||||
if (res) return res;
|
||||
} else if (runtime) {
|
||||
return t.memberExpression(runtime, t.identifier(name));
|
||||
return t.memberExpression(t.cloneNode(runtime), t.identifier(name));
|
||||
}
|
||||
|
||||
const uid = (this.declarations[name] = this.scope.generateUidIdentifier(
|
||||
|
||||
@ -154,7 +154,7 @@ export default function({ node, parent, scope, id }, localBinding = false) {
|
||||
scope.getBinding(id.name) === binding
|
||||
) {
|
||||
// always going to reference this method
|
||||
node.id = id;
|
||||
node.id = t.cloneNode(id);
|
||||
node.id[t.NOT_LOCAL_BINDING] = true;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ const awaitVisitor = {
|
||||
path.replaceWith(
|
||||
t.yieldExpression(
|
||||
wrapAwait
|
||||
? t.callExpression(wrapAwait, [argument.node])
|
||||
? t.callExpression(t.cloneNode(wrapAwait), [argument.node])
|
||||
: argument.node,
|
||||
),
|
||||
);
|
||||
@ -73,7 +73,7 @@ export default function(path: NodePath, file: Object, helpers: Object) {
|
||||
path.node.async = false;
|
||||
path.node.generator = true;
|
||||
|
||||
wrapFunction(path, helpers.wrapAsync);
|
||||
wrapFunction(path, t.cloneNode(helpers.wrapAsync));
|
||||
|
||||
const isProperty =
|
||||
path.isObjectMethod() ||
|
||||
|
||||
@ -41,7 +41,7 @@ function getPrototypeOfExpression(objectRef, isStatic) {
|
||||
t.identifier("Object"),
|
||||
t.identifier("getPrototypeOf"),
|
||||
),
|
||||
[targetRef],
|
||||
[t.cloneNode(targetRef)],
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -141,7 +141,7 @@ export default class ReplaceSupers {
|
||||
};
|
||||
|
||||
getObjectRef() {
|
||||
return this.opts.objectRef || this.opts.getObjectRef();
|
||||
return t.cloneNode(this.opts.objectRef || this.opts.getObjectRef());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -244,7 +244,7 @@ export default class ReplaceSupers {
|
||||
ref = ref || path.scope.generateUidIdentifier("ref");
|
||||
return [
|
||||
t.variableDeclaration("var", [
|
||||
t.variableDeclarator(t.cloneNode(ref), node.left),
|
||||
t.variableDeclarator(t.cloneNode(ref), t.cloneNode(node.left)),
|
||||
]),
|
||||
t.expressionStatement(
|
||||
t.assignmentExpression(
|
||||
|
||||
@ -33,20 +33,20 @@ const simpleAssignmentVisitor = {
|
||||
t.assignmentExpression("+=", arg.node, t.numericLiteral(1)),
|
||||
);
|
||||
} else {
|
||||
const varName = path.scope.generateDeclaredUidIdentifier("old");
|
||||
const varName = path.scope.generateDeclaredUidIdentifier("old").name;
|
||||
|
||||
const assignment = t.binaryExpression(
|
||||
const binary = t.binaryExpression(
|
||||
path.node.operator.slice(0, 1),
|
||||
varName,
|
||||
t.identifier(varName),
|
||||
t.numericLiteral(1),
|
||||
);
|
||||
|
||||
// i++ => (_tmp = i, i = _tmp + 1, _tmp)
|
||||
path.replaceWith(
|
||||
t.sequenceExpression([
|
||||
t.assignmentExpression("=", varName, arg.node),
|
||||
t.assignmentExpression("=", arg.node, assignment),
|
||||
varName,
|
||||
t.assignmentExpression("=", t.identifier(varName), arg.node),
|
||||
t.assignmentExpression("=", t.cloneNode(arg.node), binary),
|
||||
t.identifier(varName),
|
||||
]),
|
||||
);
|
||||
}
|
||||
@ -78,7 +78,7 @@ const simpleAssignmentVisitor = {
|
||||
|
||||
path.node.right = t.binaryExpression(
|
||||
path.node.operator.slice(0, -1),
|
||||
path.node.left,
|
||||
t.cloneNode(path.node.left),
|
||||
path.node.right,
|
||||
);
|
||||
path.node.operator = "=";
|
||||
|
||||
@ -7,23 +7,26 @@ export default function() {
|
||||
t.isIdentifier(node.meta, { name: "function" }) &&
|
||||
t.isIdentifier(node.property, { name: "sent" });
|
||||
|
||||
const hasBeenReplaced = (node, sentId) =>
|
||||
t.isAssignmentExpression(node) &&
|
||||
t.isIdentifier(node.left, { name: sentId });
|
||||
|
||||
const yieldVisitor = {
|
||||
Function(path) {
|
||||
path.skip();
|
||||
},
|
||||
|
||||
YieldExpression(path) {
|
||||
const replaced = t.isAssignmentExpression(path.parent, {
|
||||
left: this.sentId,
|
||||
});
|
||||
if (!replaced) {
|
||||
path.replaceWith(t.assignmentExpression("=", this.sentId, path.node));
|
||||
if (!hasBeenReplaced(path.parent, this.sentId)) {
|
||||
path.replaceWith(
|
||||
t.assignmentExpression("=", t.identifier(this.sentId), path.node),
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
MetaProperty(path) {
|
||||
if (isFunctionSent(path.node)) {
|
||||
path.replaceWith(this.sentId);
|
||||
path.replaceWith(t.identifier(this.sentId));
|
||||
}
|
||||
},
|
||||
};
|
||||
@ -41,12 +44,12 @@ export default function() {
|
||||
throw new Error("Parent generator function not found");
|
||||
}
|
||||
|
||||
const sentId = path.scope.generateUidIdentifier("function.sent");
|
||||
const sentId = path.scope.generateUid("function.sent");
|
||||
|
||||
fnPath.traverse(yieldVisitor, { sentId });
|
||||
fnPath.node.body.body.unshift(
|
||||
t.variableDeclaration("let", [
|
||||
t.variableDeclarator(sentId, t.yieldExpression()),
|
||||
t.variableDeclarator(t.identifier(sentId), t.yieldExpression()),
|
||||
]),
|
||||
);
|
||||
|
||||
|
||||
@ -43,7 +43,7 @@ export default function(api, opts) {
|
||||
} else if (t.isLiteral(prop.key)) {
|
||||
keys.push(t.stringLiteral(String(prop.key.value)));
|
||||
} else {
|
||||
keys.push(prop.key);
|
||||
keys.push(t.cloneNode(prop.key));
|
||||
allLiteral = false;
|
||||
}
|
||||
}
|
||||
@ -58,12 +58,10 @@ export default function(api, opts) {
|
||||
for (const propPath of path.get("properties")) {
|
||||
const key = propPath.get("key");
|
||||
if (propPath.node.computed && !key.isPure()) {
|
||||
const identifier = path.scope.generateUidIdentifierBasedOnNode(
|
||||
key.node,
|
||||
);
|
||||
const declarator = t.variableDeclarator(identifier, key.node);
|
||||
const name = path.scope.generateUidBasedOnNode(key.node);
|
||||
const declarator = t.variableDeclarator(t.identifier(name), key.node);
|
||||
impureComputedPropertyDeclarators.push(declarator);
|
||||
key.replaceWith(identifier);
|
||||
key.replaceWith(t.identifier(name));
|
||||
}
|
||||
}
|
||||
return impureComputedPropertyDeclarators;
|
||||
@ -272,14 +270,14 @@ export default function(api, opts) {
|
||||
if (leftPath.isObjectPattern() && hasRestElement(leftPath)) {
|
||||
const nodes = [];
|
||||
|
||||
const ref = path.scope.generateUidIdentifierBasedOnNode(
|
||||
const refName = path.scope.generateUidBasedOnNode(
|
||||
path.node.right,
|
||||
"ref",
|
||||
);
|
||||
|
||||
nodes.push(
|
||||
t.variableDeclaration("var", [
|
||||
t.variableDeclarator(ref, path.node.right),
|
||||
t.variableDeclarator(t.identifier(refName), path.node.right),
|
||||
]),
|
||||
);
|
||||
|
||||
@ -287,7 +285,7 @@ export default function(api, opts) {
|
||||
impureComputedPropertyDeclarators,
|
||||
argument,
|
||||
callExpression,
|
||||
] = createObjectSpread(leftPath, file, ref);
|
||||
] = createObjectSpread(leftPath, file, t.identifier(refName));
|
||||
|
||||
if (impureComputedPropertyDeclarators.length > 0) {
|
||||
nodes.push(
|
||||
@ -296,17 +294,14 @@ export default function(api, opts) {
|
||||
}
|
||||
|
||||
const nodeWithoutSpread = t.cloneNode(path.node);
|
||||
nodeWithoutSpread.right = ref;
|
||||
nodeWithoutSpread.right = t.identifier(refName);
|
||||
nodes.push(t.expressionStatement(nodeWithoutSpread));
|
||||
nodes.push(
|
||||
t.toStatement(
|
||||
t.assignmentExpression("=", argument, callExpression),
|
||||
),
|
||||
);
|
||||
|
||||
if (ref) {
|
||||
nodes.push(t.expressionStatement(ref));
|
||||
}
|
||||
nodes.push(t.expressionStatement(t.identifier(refName)));
|
||||
|
||||
path.replaceWithMultiple(nodes);
|
||||
}
|
||||
|
||||
@ -42,7 +42,9 @@ export default function(api, options) {
|
||||
check = t.assignmentExpression(
|
||||
"=",
|
||||
t.cloneNode(ref),
|
||||
t.cloneNode(chain),
|
||||
// Here `chain` MUST NOT be cloned because it could be updated
|
||||
// when generating the memoised context of a call espression
|
||||
chain,
|
||||
);
|
||||
node[replaceKey] = ref;
|
||||
} else {
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
var _foo, _foo2, _foo$bar, _foo3, _foo3$bar, _foo4, _foo5, _foo6, _foo$bar2, _foo$bar3, _foo$bar3$call, _foo7, _foo7$bar, _foo8, _foo8$bar, _foo8$bar$call;
|
||||
var _foo, _foo2, _foo$bar, _foo3, _foo4, _foo4$bar, _foo5, _foo6, _foo7, _foo$bar2, _foo8, _foo$bar3, _foo9, _foo$bar3$call, _foo10, _foo10$bar, _foo11, _foo11$bar, _foo11$bar$call;
|
||||
|
||||
(_foo = foo) === null || _foo === void 0 ? void 0 : _foo(foo);
|
||||
(_foo2 = foo) === null || _foo2 === void 0 ? void 0 : _foo2.bar();
|
||||
(_foo$bar = foo.bar) === null || _foo$bar === void 0 ? void 0 : _foo$bar.call(foo, foo.bar, false);
|
||||
(_foo3 = foo) === null || _foo3 === void 0 ? void 0 : (_foo3$bar = _foo3.bar) === null || _foo3$bar === void 0 ? void 0 : _foo3$bar.call(_foo3, foo.bar, true);
|
||||
(_foo4 = foo) === null || _foo4 === void 0 ? void 0 : _foo4().bar;
|
||||
(_foo5 = foo) === null || _foo5 === void 0 ? void 0 : (_foo6 = _foo5()) === null || _foo6 === void 0 ? void 0 : _foo6.bar;
|
||||
(_foo$bar2 = foo.bar) === null || _foo$bar2 === void 0 ? void 0 : _foo$bar2.call(foo).baz;
|
||||
(_foo$bar3 = foo.bar) === null || _foo$bar3 === void 0 ? void 0 : (_foo$bar3$call = _foo$bar3.call(foo)) === null || _foo$bar3$call === void 0 ? void 0 : _foo$bar3$call.baz;
|
||||
(_foo7 = foo) === null || _foo7 === void 0 ? void 0 : (_foo7$bar = _foo7.bar) === null || _foo7$bar === void 0 ? void 0 : _foo7$bar.call(_foo7).baz;
|
||||
(_foo8 = foo) === null || _foo8 === void 0 ? void 0 : (_foo8$bar = _foo8.bar) === null || _foo8$bar === void 0 ? void 0 : (_foo8$bar$call = _foo8$bar.call(_foo8)) === null || _foo8$bar$call === void 0 ? void 0 : _foo8$bar$call.baz;
|
||||
(_foo$bar = (_foo3 = foo).bar) === null || _foo$bar === void 0 ? void 0 : _foo$bar.call(_foo3, foo.bar, false);
|
||||
(_foo4 = foo) === null || _foo4 === void 0 ? void 0 : (_foo4$bar = _foo4.bar) === null || _foo4$bar === void 0 ? void 0 : _foo4$bar.call(_foo4, foo.bar, true);
|
||||
(_foo5 = foo) === null || _foo5 === void 0 ? void 0 : _foo5().bar;
|
||||
(_foo6 = foo) === null || _foo6 === void 0 ? void 0 : (_foo7 = _foo6()) === null || _foo7 === void 0 ? void 0 : _foo7.bar;
|
||||
(_foo$bar2 = (_foo8 = foo).bar) === null || _foo$bar2 === void 0 ? void 0 : _foo$bar2.call(_foo8).baz;
|
||||
(_foo$bar3 = (_foo9 = foo).bar) === null || _foo$bar3 === void 0 ? void 0 : (_foo$bar3$call = _foo$bar3.call(_foo9)) === null || _foo$bar3$call === void 0 ? void 0 : _foo$bar3$call.baz;
|
||||
(_foo10 = foo) === null || _foo10 === void 0 ? void 0 : (_foo10$bar = _foo10.bar) === null || _foo10$bar === void 0 ? void 0 : _foo10$bar.call(_foo10).baz;
|
||||
(_foo11 = foo) === null || _foo11 === void 0 ? void 0 : (_foo11$bar = _foo11.bar) === null || _foo11$bar === void 0 ? void 0 : (_foo11$bar$call = _foo11$bar.call(_foo11)) === null || _foo11$bar$call === void 0 ? void 0 : _foo11$bar$call.baz;
|
||||
|
||||
@ -524,7 +524,7 @@ class BlockScoping {
|
||||
this.hoistVarDeclarations();
|
||||
|
||||
// turn outsideLetReferences into an array
|
||||
const args = values(outsideRefs);
|
||||
const args = values(outsideRefs).map(id => t.cloneNode(id));
|
||||
const params = args.map(id => t.cloneNode(id));
|
||||
|
||||
const isSwitch = this.blockPath.isSwitchStatement();
|
||||
@ -569,10 +569,12 @@ class BlockScoping {
|
||||
let placeholderPath;
|
||||
let index;
|
||||
if (this.has.hasReturn || this.has.hasBreakContinue) {
|
||||
const ret = this.scope.generateUidIdentifier("ret");
|
||||
const ret = this.scope.generateUid("ret");
|
||||
|
||||
this.body.push(
|
||||
t.variableDeclaration("var", [t.variableDeclarator(ret, call)]),
|
||||
t.variableDeclaration("var", [
|
||||
t.variableDeclarator(t.identifier(ret), call),
|
||||
]),
|
||||
);
|
||||
placeholderPath = "declarations.0.init" + basePath;
|
||||
index = this.body.length - 1;
|
||||
@ -600,12 +602,14 @@ class BlockScoping {
|
||||
|
||||
let fnPath;
|
||||
if (this.loop) {
|
||||
const ref = this.scope.generateUidIdentifier("loop");
|
||||
const loopId = this.scope.generateUid("loop");
|
||||
const p = this.loopPath.insertBefore(
|
||||
t.variableDeclaration("var", [t.variableDeclarator(ref, fn)]),
|
||||
t.variableDeclaration("var", [
|
||||
t.variableDeclarator(t.identifier(loopId), fn),
|
||||
]),
|
||||
);
|
||||
|
||||
placeholder.replaceWith(ref);
|
||||
placeholder.replaceWith(t.identifier(loopId));
|
||||
fnPath = p[0].get("declarations.0.init");
|
||||
} else {
|
||||
placeholder.replaceWith(fn);
|
||||
@ -637,20 +641,33 @@ class BlockScoping {
|
||||
const param = fn.params[i];
|
||||
if (!state.reassignments[param.name]) continue;
|
||||
|
||||
const newParam = this.scope.generateUidIdentifier(param.name);
|
||||
fn.params[i] = newParam;
|
||||
const paramName = param.name;
|
||||
const newParamName = this.scope.generateUid(param.name);
|
||||
fn.params[i] = t.identifier(newParamName);
|
||||
|
||||
this.scope.rename(param.name, newParam.name, fn);
|
||||
this.scope.rename(paramName, newParamName, fn);
|
||||
|
||||
state.returnStatements.forEach(returnStatement => {
|
||||
returnStatement.insertBefore(
|
||||
t.expressionStatement(t.assignmentExpression("=", param, newParam)),
|
||||
t.expressionStatement(
|
||||
t.assignmentExpression(
|
||||
"=",
|
||||
t.identifier(paramName),
|
||||
t.identifier(newParamName),
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
// assign outer reference as it's been modified internally and needs to be retained
|
||||
fn.body.body.push(
|
||||
t.expressionStatement(t.assignmentExpression("=", param, newParam)),
|
||||
t.expressionStatement(
|
||||
t.assignmentExpression(
|
||||
"=",
|
||||
t.identifier(paramName),
|
||||
t.identifier(newParamName),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -793,14 +810,18 @@ class BlockScoping {
|
||||
const declar = node.declarations[i];
|
||||
if (!declar.init) continue;
|
||||
|
||||
const expr = t.assignmentExpression("=", declar.id, declar.init);
|
||||
const expr = t.assignmentExpression(
|
||||
"=",
|
||||
t.cloneNode(declar.id),
|
||||
t.cloneNode(declar.init),
|
||||
);
|
||||
replace.push(t.inherits(expr, declar));
|
||||
}
|
||||
|
||||
return replace;
|
||||
}
|
||||
|
||||
buildHas(ret: { type: "Identifier" }) {
|
||||
buildHas(ret: string) {
|
||||
const body = this.body;
|
||||
|
||||
let retCheck;
|
||||
@ -810,7 +831,7 @@ class BlockScoping {
|
||||
if (has.hasReturn) {
|
||||
// typeof ret === "object"
|
||||
retCheck = buildRetCheck({
|
||||
RETURN: ret,
|
||||
RETURN: t.identifier(ret),
|
||||
});
|
||||
}
|
||||
|
||||
@ -827,7 +848,7 @@ class BlockScoping {
|
||||
const single = cases[0];
|
||||
body.push(
|
||||
t.ifStatement(
|
||||
t.binaryExpression("===", ret, single.test),
|
||||
t.binaryExpression("===", t.identifier(ret), single.test),
|
||||
single.consequent[0],
|
||||
),
|
||||
);
|
||||
@ -837,13 +858,15 @@ class BlockScoping {
|
||||
for (let i = 0; i < cases.length; i++) {
|
||||
const caseConsequent = cases[i].consequent[0];
|
||||
if (t.isBreakStatement(caseConsequent) && !caseConsequent.label) {
|
||||
caseConsequent.label = this.loopLabel =
|
||||
this.loopLabel || this.scope.generateUidIdentifier("loop");
|
||||
if (!this.loopLabel) {
|
||||
this.loopLabel = this.scope.generateUidIdentifier("loop");
|
||||
}
|
||||
caseConsequent.label = t.cloneNode(this.loopLabel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
body.push(t.switchStatement(ret, cases));
|
||||
body.push(t.switchStatement(t.identifier(ret), cases));
|
||||
}
|
||||
} else {
|
||||
if (has.hasReturn) {
|
||||
|
||||
@ -122,16 +122,18 @@ export default class ClassTransformer {
|
||||
if (this.isDerived) {
|
||||
if (this.extendsNative) {
|
||||
closureArgs.push(
|
||||
t.callExpression(this.file.addHelper("wrapNativeSuper"), [superName]),
|
||||
t.callExpression(this.file.addHelper("wrapNativeSuper"), [
|
||||
t.cloneNode(superName),
|
||||
]),
|
||||
);
|
||||
} else {
|
||||
closureArgs.push(superName);
|
||||
closureArgs.push(t.cloneNode(superName));
|
||||
}
|
||||
|
||||
superName = this.scope.generateUidIdentifierBasedOnNode(superName);
|
||||
closureParams.push(superName);
|
||||
|
||||
this.superName = superName;
|
||||
this.superName = t.cloneNode(superName);
|
||||
}
|
||||
|
||||
//
|
||||
@ -143,13 +145,15 @@ export default class ClassTransformer {
|
||||
t.expressionStatement(
|
||||
t.callExpression(file.addHelper("classCallCheck"), [
|
||||
t.thisExpression(),
|
||||
this.classRef,
|
||||
t.cloneNode(this.classRef),
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
body = body.concat(this.staticPropBody.map(fn => fn(this.classRef)));
|
||||
body = body.concat(
|
||||
this.staticPropBody.map(fn => fn(t.cloneNode(this.classRef))),
|
||||
);
|
||||
|
||||
if (this.classId) {
|
||||
// named class with only a constructor
|
||||
@ -157,7 +161,7 @@ export default class ClassTransformer {
|
||||
}
|
||||
|
||||
//
|
||||
body.push(t.returnStatement(this.classRef));
|
||||
body.push(t.returnStatement(t.cloneNode(this.classRef)));
|
||||
|
||||
const container = t.arrowFunctionExpression(
|
||||
closureParams,
|
||||
@ -167,7 +171,11 @@ export default class ClassTransformer {
|
||||
}
|
||||
|
||||
buildConstructor() {
|
||||
const func = t.functionDeclaration(this.classRef, [], this.constructorBody);
|
||||
const func = t.functionDeclaration(
|
||||
t.cloneNode(this.classRef),
|
||||
[],
|
||||
this.constructorBody,
|
||||
);
|
||||
t.inherits(func, this.node);
|
||||
return func;
|
||||
}
|
||||
@ -327,14 +335,12 @@ export default class ClassTransformer {
|
||||
staticProps = defineMap.toComputedObjectFromClass(staticProps);
|
||||
}
|
||||
|
||||
const nullNode = t.nullLiteral();
|
||||
|
||||
let args = [
|
||||
this.classRef, // Constructor
|
||||
nullNode, // instanceDescriptors
|
||||
nullNode, // staticDescriptors
|
||||
nullNode, // instanceInitializers
|
||||
nullNode, // staticInitializers
|
||||
t.cloneNode(this.classRef), // Constructor
|
||||
t.nullLiteral(), // instanceDescriptors
|
||||
t.nullLiteral(), // staticDescriptors
|
||||
t.nullLiteral(), // instanceInitializers
|
||||
t.nullLiteral(), // staticInitializers
|
||||
];
|
||||
|
||||
if (instanceProps) args[1] = instanceProps;
|
||||
@ -352,7 +358,7 @@ export default class ClassTransformer {
|
||||
|
||||
let lastNonNullIndex = 0;
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
if (args[i] !== nullNode) lastNonNullIndex = i;
|
||||
if (!t.isNullLiteral(args[i])) lastNonNullIndex = i;
|
||||
}
|
||||
args = args.slice(0, lastNonNullIndex + 1);
|
||||
|
||||
@ -400,13 +406,16 @@ export default class ClassTransformer {
|
||||
bareSuperNode = optimiseCall(
|
||||
t.logicalExpression(
|
||||
"||",
|
||||
t.memberExpression(this.classRef, t.identifier("__proto__")),
|
||||
t.memberExpression(
|
||||
t.cloneNode(this.classRef),
|
||||
t.identifier("__proto__"),
|
||||
),
|
||||
t.callExpression(
|
||||
t.memberExpression(
|
||||
t.identifier("Object"),
|
||||
t.identifier("getPrototypeOf"),
|
||||
),
|
||||
[this.classRef],
|
||||
[t.cloneNode(this.classRef)],
|
||||
),
|
||||
),
|
||||
t.thisExpression(),
|
||||
@ -607,7 +616,7 @@ export default class ClassTransformer {
|
||||
this.isLoose
|
||||
? this.file.addHelper("inheritsLoose")
|
||||
: this.file.addHelper("inherits"),
|
||||
[this.classRef, this.superName],
|
||||
[t.cloneNode(this.classRef), t.cloneNode(this.superName)],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@ -112,12 +112,10 @@ export default function(api, options) {
|
||||
// we need to assign the current value of the assignment to avoid evaluating
|
||||
// it more than once
|
||||
|
||||
const tempValueRef = this.scope.generateUidIdentifierBasedOnNode(
|
||||
valueRef,
|
||||
);
|
||||
const tempValueRef = this.scope.generateUidBasedOnNode(valueRef);
|
||||
|
||||
const declar = t.variableDeclaration("var", [
|
||||
t.variableDeclarator(tempValueRef, valueRef),
|
||||
t.variableDeclarator(t.identifier(tempValueRef), valueRef),
|
||||
]);
|
||||
declar._blockHoist = this.blockHoist;
|
||||
this.nodes.push(declar);
|
||||
@ -127,22 +125,26 @@ export default function(api, options) {
|
||||
const tempConditional = t.conditionalExpression(
|
||||
t.binaryExpression(
|
||||
"===",
|
||||
tempValueRef,
|
||||
t.identifier(tempValueRef),
|
||||
this.scope.buildUndefinedNode(),
|
||||
),
|
||||
pattern.right,
|
||||
tempValueRef,
|
||||
t.identifier(tempValueRef),
|
||||
);
|
||||
|
||||
const left = pattern.left;
|
||||
if (t.isPattern(left)) {
|
||||
const tempValueDefault = t.expressionStatement(
|
||||
t.assignmentExpression("=", tempValueRef, tempConditional),
|
||||
t.assignmentExpression(
|
||||
"=",
|
||||
t.identifier(tempValueRef),
|
||||
tempConditional,
|
||||
),
|
||||
);
|
||||
tempValueDefault._blockHoist = this.blockHoist;
|
||||
|
||||
this.nodes.push(tempValueDefault);
|
||||
this.push(left, tempValueRef);
|
||||
this.push(left, t.identifier(tempValueRef));
|
||||
} else {
|
||||
this.nodes.push(this.buildVariableAssignment(left, tempConditional));
|
||||
}
|
||||
|
||||
@ -25,7 +25,11 @@ export default function(api, options) {
|
||||
array = right;
|
||||
}
|
||||
|
||||
const item = t.memberExpression(array, t.cloneNode(i), true);
|
||||
const item = t.memberExpression(
|
||||
t.cloneNode(array),
|
||||
t.cloneNode(i),
|
||||
true,
|
||||
);
|
||||
let assignment;
|
||||
if (t.isVariableDeclaration(left)) {
|
||||
assignment = left;
|
||||
@ -112,11 +116,13 @@ export default function(api, options) {
|
||||
let right = node.right;
|
||||
|
||||
if (!t.isIdentifier(right) || !scope.hasBinding(right.name)) {
|
||||
const uid = scope.generateUidIdentifier("arr");
|
||||
const uid = scope.generateUid("arr");
|
||||
nodes.push(
|
||||
t.variableDeclaration("var", [t.variableDeclarator(uid, right)]),
|
||||
t.variableDeclaration("var", [
|
||||
t.variableDeclarator(t.identifier(uid), right),
|
||||
]),
|
||||
);
|
||||
right = uid;
|
||||
right = t.identifier(uid);
|
||||
}
|
||||
|
||||
const iterationKey = scope.generateUidIdentifier("i");
|
||||
@ -130,7 +136,11 @@ export default function(api, options) {
|
||||
t.inherits(loop, node);
|
||||
t.ensureBlock(loop);
|
||||
|
||||
const iterationValue = t.memberExpression(right, iterationKey, true);
|
||||
const iterationValue = t.memberExpression(
|
||||
t.cloneNode(right),
|
||||
t.cloneNode(iterationKey),
|
||||
true,
|
||||
);
|
||||
|
||||
const left = node.left;
|
||||
if (t.isVariableDeclaration(left)) {
|
||||
@ -221,9 +231,11 @@ export default function(api, options) {
|
||||
// for (let i of test)
|
||||
id = scope.generateUidIdentifier("ref");
|
||||
declar = t.variableDeclaration(left.kind, [
|
||||
t.variableDeclarator(left.declarations[0].id, id),
|
||||
t.variableDeclarator(left.declarations[0].id, t.identifier(id.name)),
|
||||
]);
|
||||
intermediate = t.variableDeclaration("var", [
|
||||
t.variableDeclarator(t.identifier(id.name)),
|
||||
]);
|
||||
intermediate = t.variableDeclaration("var", [t.variableDeclarator(id)]);
|
||||
} else {
|
||||
throw file.buildCodeFrameError(
|
||||
left,
|
||||
@ -264,8 +276,11 @@ export default function(api, options) {
|
||||
const left = node.left;
|
||||
let declar;
|
||||
|
||||
const stepKey = scope.generateUidIdentifier("step");
|
||||
const stepValue = t.memberExpression(stepKey, t.identifier("value"));
|
||||
const stepKey = scope.generateUid("step");
|
||||
const stepValue = t.memberExpression(
|
||||
t.identifier(stepKey),
|
||||
t.identifier("value"),
|
||||
);
|
||||
|
||||
if (
|
||||
t.isIdentifier(left) ||
|
||||
@ -288,18 +303,14 @@ export default function(api, options) {
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
const iteratorKey = scope.generateUidIdentifier("iterator");
|
||||
|
||||
const template = buildForOf({
|
||||
ITERATOR_HAD_ERROR_KEY: scope.generateUidIdentifier("didIteratorError"),
|
||||
ITERATOR_COMPLETION: scope.generateUidIdentifier(
|
||||
"iteratorNormalCompletion",
|
||||
),
|
||||
ITERATOR_ERROR_KEY: scope.generateUidIdentifier("iteratorError"),
|
||||
ITERATOR_KEY: iteratorKey,
|
||||
STEP_KEY: stepKey,
|
||||
ITERATOR_KEY: scope.generateUidIdentifier("iterator"),
|
||||
STEP_KEY: t.identifier(stepKey),
|
||||
OBJECT: node.right,
|
||||
});
|
||||
|
||||
|
||||
@ -15,7 +15,7 @@ export default function() {
|
||||
[],
|
||||
t.blockStatement([
|
||||
t.toStatement(node),
|
||||
t.returnStatement(node.id),
|
||||
t.returnStatement(t.cloneNode(node.id)),
|
||||
]),
|
||||
),
|
||||
[],
|
||||
|
||||
@ -50,9 +50,17 @@ export default function(api, options) {
|
||||
let isPostUpdateExpression = path.isUpdateExpression() && !node.prefix;
|
||||
if (isPostUpdateExpression) {
|
||||
if (node.operator === "++") {
|
||||
node = t.binaryExpression("+", node.argument, t.numericLiteral(1));
|
||||
node = t.binaryExpression(
|
||||
"+",
|
||||
t.cloneNode(node.argument),
|
||||
t.numericLiteral(1),
|
||||
);
|
||||
} else if (node.operator === "--") {
|
||||
node = t.binaryExpression("-", node.argument, t.numericLiteral(1));
|
||||
node = t.binaryExpression(
|
||||
"-",
|
||||
t.cloneNode(node.argument),
|
||||
t.numericLiteral(1),
|
||||
);
|
||||
} else {
|
||||
isPostUpdateExpression = false;
|
||||
}
|
||||
@ -74,10 +82,12 @@ export default function(api, options) {
|
||||
visitor: {
|
||||
CallExpression(path, state) {
|
||||
if (path.node.callee.type === TYPE_IMPORT) {
|
||||
const contextIdent = state.contextIdent;
|
||||
path.replaceWith(
|
||||
t.callExpression(
|
||||
t.memberExpression(contextIdent, t.identifier("import")),
|
||||
t.memberExpression(
|
||||
t.identifier(state.contextIdent),
|
||||
t.identifier("import"),
|
||||
),
|
||||
path.node.arguments,
|
||||
),
|
||||
);
|
||||
@ -90,17 +100,20 @@ export default function(api, options) {
|
||||
!path.scope.hasBinding("__moduleName")
|
||||
) {
|
||||
path.replaceWith(
|
||||
t.memberExpression(state.contextIdent, t.identifier("id")),
|
||||
t.memberExpression(
|
||||
t.identifier(state.contextIdent),
|
||||
t.identifier("id"),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
Program: {
|
||||
enter(path, state) {
|
||||
state.contextIdent = path.scope.generateUidIdentifier("context");
|
||||
state.contextIdent = path.scope.generateUid("context");
|
||||
},
|
||||
exit(path, state) {
|
||||
const exportIdent = path.scope.generateUidIdentifier("export");
|
||||
const exportIdent = path.scope.generateUid("export");
|
||||
const contextIdent = state.contextIdent;
|
||||
|
||||
const exportNames = Object.create(null);
|
||||
@ -134,7 +147,10 @@ export default function(api, options) {
|
||||
|
||||
function buildExportCall(name, val) {
|
||||
return t.expressionStatement(
|
||||
t.callExpression(exportIdent, [t.stringLiteral(name), val]),
|
||||
t.callExpression(t.identifier(exportIdent), [
|
||||
t.stringLiteral(name),
|
||||
val,
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
@ -175,7 +191,7 @@ export default function(api, options) {
|
||||
|
||||
if (id) {
|
||||
nodes.push(declar.node);
|
||||
nodes.push(buildExportCall("default", id));
|
||||
nodes.push(buildExportCall("default", t.cloneNode(id)));
|
||||
addExportName(id.name, "default");
|
||||
} else {
|
||||
nodes.push(
|
||||
@ -206,7 +222,9 @@ export default function(api, options) {
|
||||
if (canHoist) {
|
||||
addExportName(name, name);
|
||||
beforeBody.push(node);
|
||||
beforeBody.push(buildExportCall(name, node.id));
|
||||
beforeBody.push(
|
||||
buildExportCall(name, t.cloneNode(node.id)),
|
||||
);
|
||||
removedPaths.push(path);
|
||||
} else {
|
||||
bindingIdentifiers = { [name]: node.id };
|
||||
@ -250,13 +268,17 @@ export default function(api, options) {
|
||||
|
||||
modules.forEach(function(specifiers) {
|
||||
const setterBody = [];
|
||||
const target = path.scope.generateUidIdentifier(specifiers.key);
|
||||
const target = path.scope.generateUid(specifiers.key);
|
||||
|
||||
for (let specifier of specifiers.imports) {
|
||||
if (t.isImportNamespaceSpecifier(specifier)) {
|
||||
setterBody.push(
|
||||
t.expressionStatement(
|
||||
t.assignmentExpression("=", specifier.local, target),
|
||||
t.assignmentExpression(
|
||||
"=",
|
||||
specifier.local,
|
||||
t.identifier(target),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else if (t.isImportDefaultSpecifier(specifier)) {
|
||||
@ -272,7 +294,10 @@ export default function(api, options) {
|
||||
t.assignmentExpression(
|
||||
"=",
|
||||
specifier.local,
|
||||
t.memberExpression(target, specifier.imported),
|
||||
t.memberExpression(
|
||||
t.identifier(target),
|
||||
specifier.imported,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
@ -280,13 +305,14 @@ export default function(api, options) {
|
||||
}
|
||||
|
||||
if (specifiers.exports.length) {
|
||||
const exportObjRef = path.scope.generateUidIdentifier(
|
||||
"exportObj",
|
||||
);
|
||||
const exportObj = path.scope.generateUid("exportObj");
|
||||
|
||||
setterBody.push(
|
||||
t.variableDeclaration("var", [
|
||||
t.variableDeclarator(exportObjRef, t.objectExpression([])),
|
||||
t.variableDeclarator(
|
||||
t.identifier(exportObj),
|
||||
t.objectExpression([]),
|
||||
),
|
||||
]),
|
||||
);
|
||||
|
||||
@ -295,8 +321,8 @@ export default function(api, options) {
|
||||
setterBody.push(
|
||||
buildExportAll({
|
||||
KEY: path.scope.generateUidIdentifier("key"),
|
||||
EXPORT_OBJ: exportObjRef,
|
||||
TARGET: target,
|
||||
EXPORT_OBJ: t.identifier(exportObj),
|
||||
TARGET: t.identifier(target),
|
||||
}),
|
||||
);
|
||||
} else if (t.isExportSpecifier(node)) {
|
||||
@ -304,8 +330,11 @@ export default function(api, options) {
|
||||
t.expressionStatement(
|
||||
t.assignmentExpression(
|
||||
"=",
|
||||
t.memberExpression(exportObjRef, node.exported),
|
||||
t.memberExpression(target, node.local),
|
||||
t.memberExpression(
|
||||
t.identifier(exportObj),
|
||||
node.exported,
|
||||
),
|
||||
t.memberExpression(t.identifier(target), node.local),
|
||||
),
|
||||
),
|
||||
);
|
||||
@ -316,7 +345,9 @@ export default function(api, options) {
|
||||
|
||||
setterBody.push(
|
||||
t.expressionStatement(
|
||||
t.callExpression(exportIdent, [exportObjRef]),
|
||||
t.callExpression(t.identifier(exportIdent), [
|
||||
t.identifier(exportObj),
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -325,7 +356,7 @@ export default function(api, options) {
|
||||
setters.push(
|
||||
t.functionExpression(
|
||||
null,
|
||||
[target],
|
||||
[t.identifier(target)],
|
||||
t.blockStatement(setterBody),
|
||||
),
|
||||
);
|
||||
@ -368,8 +399,8 @@ export default function(api, options) {
|
||||
SETTERS: t.arrayExpression(setters),
|
||||
SOURCES: t.arrayExpression(sources),
|
||||
BODY: path.node.body,
|
||||
EXPORT_IDENTIFIER: exportIdent,
|
||||
CONTEXT_IDENTIFIER: contextIdent,
|
||||
EXPORT_IDENTIFIER: t.identifier(exportIdent),
|
||||
CONTEXT_IDENTIFIER: t.identifier(contextIdent),
|
||||
}),
|
||||
];
|
||||
},
|
||||
|
||||
@ -68,7 +68,9 @@ export default function(api, options) {
|
||||
const members = globalName.split(".");
|
||||
globalToAssign = members.slice(1).reduce((accum, curr) => {
|
||||
initAssignments.push(
|
||||
buildPrerequisiteAssignment({ GLOBAL_REFERENCE: accum }),
|
||||
buildPrerequisiteAssignment({
|
||||
GLOBAL_REFERENCE: t.cloneNode(accum),
|
||||
}),
|
||||
);
|
||||
return t.memberExpression(accum, t.identifier(curr));
|
||||
}, t.memberExpression(t.identifier("global"), t.identifier(members[0])));
|
||||
|
||||
@ -289,8 +289,7 @@ export default function convertFunctionRest(path) {
|
||||
const key = scope.generateUidIdentifier("key");
|
||||
const len = scope.generateUidIdentifier("len");
|
||||
|
||||
let arrKey = key;
|
||||
let arrLen = len;
|
||||
let arrKey, arrLen;
|
||||
if (node.params.length) {
|
||||
// this method has additional params, so we need to subtract
|
||||
// the index of the current argument position from the
|
||||
@ -308,6 +307,9 @@ export default function convertFunctionRest(path) {
|
||||
t.binaryExpression("-", t.cloneNode(len), t.cloneNode(start)),
|
||||
t.numericLiteral(0),
|
||||
);
|
||||
} else {
|
||||
arrKey = t.identifier(key.name);
|
||||
arrLen = t.identifier(len.name);
|
||||
}
|
||||
|
||||
const loop = buildRest({
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import assert from "assert";
|
||||
import { template } from "@babel/core";
|
||||
|
||||
export default function transpileEnum(path, t) {
|
||||
const { node } = path;
|
||||
@ -50,37 +51,41 @@ function makeVar(id, t, kind): VariableDeclaration {
|
||||
return t.variableDeclaration(kind, [t.variableDeclarator(id)]);
|
||||
}
|
||||
|
||||
const buildEnumWrapper = template(`
|
||||
(function (ID) {
|
||||
ASSIGNMENTS;
|
||||
})(ID || (ID = {}));
|
||||
`);
|
||||
|
||||
const buildStringAssignment = template(`
|
||||
ENUM["NAME"] = VALUE;
|
||||
`);
|
||||
|
||||
const buildNumericAssignment = template(`
|
||||
ENUM[ENUM["NAME"] = VALUE] = "NAME";
|
||||
`);
|
||||
|
||||
const buildEnumMember = (isString, options) =>
|
||||
(isString ? buildStringAssignment : buildNumericAssignment)(options);
|
||||
|
||||
/**
|
||||
* Generates the statement that fills in the variable declared by the enum.
|
||||
* `(function (E) { ... assignments ... })(E || (E = {}));`
|
||||
*/
|
||||
function enumFill(path, t, id) {
|
||||
const x = translateEnumValues(path, t);
|
||||
const assignments = x.map(([memberName, memberValue]) => {
|
||||
const inner = t.assignmentExpression(
|
||||
"=",
|
||||
t.memberExpression(id, t.stringLiteral(memberName), /*computed*/ true),
|
||||
memberValue,
|
||||
const assignments = x.map(([memberName, memberValue]) =>
|
||||
buildEnumMember(t.isStringLiteral(memberValue), {
|
||||
ENUM: t.cloneNode(id),
|
||||
NAME: memberName,
|
||||
VALUE: memberValue,
|
||||
}),
|
||||
);
|
||||
const outer = t.isStringLiteral(memberValue)
|
||||
? inner
|
||||
: t.assignmentExpression(
|
||||
"=",
|
||||
t.memberExpression(id, inner, /*computed*/ true),
|
||||
t.stringLiteral(memberName),
|
||||
);
|
||||
return t.expressionStatement(outer);
|
||||
});
|
||||
|
||||
// E || (E = {})
|
||||
const callArg = t.logicalExpression(
|
||||
"||",
|
||||
id,
|
||||
t.assignmentExpression("=", id, t.objectExpression([])),
|
||||
);
|
||||
const body = t.blockStatement(assignments);
|
||||
const callee = t.functionExpression(null, [id], body);
|
||||
return t.expressionStatement(t.callExpression(callee, [callArg]));
|
||||
return buildEnumWrapper({
|
||||
ID: t.cloneNode(id),
|
||||
ASSIGNMENTS: assignments,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -114,9 +114,11 @@ export default function() {
|
||||
);
|
||||
}
|
||||
|
||||
const id = t.identifier(name);
|
||||
const thisDotName = t.memberExpression(t.thisExpression(), id);
|
||||
const assign = t.assignmentExpression("=", thisDotName, id);
|
||||
const assign = t.assignmentExpression(
|
||||
"=",
|
||||
t.memberExpression(t.thisExpression(), t.identifier(name)),
|
||||
t.identifier(name),
|
||||
);
|
||||
return t.expressionStatement(assign);
|
||||
});
|
||||
|
||||
|
||||
@ -263,14 +263,7 @@ export default class Scope {
|
||||
return `_${id}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a unique identifier based on a node.
|
||||
*/
|
||||
|
||||
generateUidIdentifierBasedOnNode(
|
||||
parent: Object,
|
||||
defaultName?: String,
|
||||
): Object {
|
||||
generateUidBasedOnNode(parent: Object, defaultName?: String) {
|
||||
let node = parent;
|
||||
|
||||
if (t.isAssignmentExpression(parent)) {
|
||||
@ -287,7 +280,18 @@ export default class Scope {
|
||||
let id = parts.join("$");
|
||||
id = id.replace(/^_/, "") || defaultName || "ref";
|
||||
|
||||
return this.generateUidIdentifier(id.slice(0, 20));
|
||||
return this.generateUid(id.slice(0, 20));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a unique identifier based on a node.
|
||||
*/
|
||||
|
||||
generateUidIdentifierBasedOnNode(
|
||||
parent: Object,
|
||||
defaultName?: String,
|
||||
): Object {
|
||||
return t.identifier(this.generateUidBasedOnNode(parent, defaultName));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user