Fix reused nodes - part 1 (#7149)

This commit is contained in:
Mateusz Burzyński 2018-01-11 19:31:48 +01:00 committed by Nicolò Ribaudo
parent 63ae923987
commit 912bcc186d
30 changed files with 202 additions and 117 deletions

View File

@ -123,7 +123,7 @@ export default class File {
addHelper(name: string): Object {
const declar = this.declarations[name];
if (declar) return declar;
if (declar) return t.cloneNode(declar);
const generator = this.get("helperGenerator");
const runtime = this.get("helpersNamespace");

View File

@ -33,7 +33,7 @@ function getObjRef(node, nodes, file, scope) {
const temp = scope.generateUidIdentifierBasedOnNode(ref);
scope.push({ id: temp });
nodes.push(t.assignmentExpression("=", temp, ref));
nodes.push(t.assignmentExpression("=", t.cloneNode(temp), t.cloneNode(ref)));
return temp;
}
@ -44,7 +44,7 @@ function getPropRef(node, nodes, file, scope) {
const temp = scope.generateUidIdentifierBasedOnNode(prop);
scope.push({ id: temp });
nodes.push(t.assignmentExpression("=", temp, prop));
nodes.push(t.assignmentExpression("=", t.cloneNode(temp), t.cloneNode(prop)));
return temp;
}
@ -68,12 +68,13 @@ export default function(
let ref, uid;
if (t.isIdentifier(node)) {
ref = node;
ref = t.cloneNode(node);
uid = obj;
} else {
const prop = getPropRef(node, nodes, file, scope);
const computed = node.computed || t.isLiteral(prop);
uid = ref = t.memberExpression(obj, prop, computed);
uid = t.memberExpression(t.cloneNode(obj), t.cloneNode(prop), computed);
ref = t.memberExpression(t.cloneNode(obj), t.cloneNode(prop), computed);
}
return {

View File

@ -206,9 +206,12 @@ export default class ReplaceSupers {
return;
} else if (t.isMemberExpression(parent) && !methodNode.static) {
// super.test -> objectRef.prototype.test
return t.memberExpression(superRef, t.identifier("prototype"));
return t.memberExpression(
t.cloneNode(superRef),
t.identifier("prototype"),
);
} else {
return superRef;
return t.cloneNode(superRef);
}
}
@ -240,12 +243,18 @@ export default class ReplaceSupers {
// super.age += 2; -> let _ref = super.age; super.age = _ref + 2;
ref = ref || path.scope.generateUidIdentifier("ref");
return [
t.variableDeclaration("var", [t.variableDeclarator(ref, node.left)]),
t.variableDeclaration("var", [
t.variableDeclarator(t.cloneNode(ref), node.left),
]),
t.expressionStatement(
t.assignmentExpression(
"=",
node.left,
t.binaryExpression(node.operator.slice(0, -1), ref, node.right),
t.binaryExpression(
node.operator.slice(0, -1),
t.cloneNode(ref),
node.right,
),
),
),
];

View File

@ -54,7 +54,7 @@ export default function(api, options) {
value: VALUE
});
`({
REF: ref,
REF: t.cloneNode(ref),
KEY: t.isIdentifier(key) && !computed ? t.stringLiteral(key.name) : key,
VALUE: value || scope.buildUndefinedNode(),
});
@ -62,7 +62,11 @@ export default function(api, options) {
const buildClassPropertyLoose = (ref, { key, value, computed }, scope) => {
return template.statement`MEMBER = VALUE`({
MEMBER: t.memberExpression(ref, key, computed || t.isLiteral(key)),
MEMBER: t.memberExpression(
t.cloneNode(ref),
key,
computed || t.isLiteral(key),
),
VALUE: value || scope.buildUndefinedNode(),
});
};
@ -199,7 +203,10 @@ export default function(api, options) {
instanceBody = [
t.expressionStatement(
t.callExpression(
t.memberExpression(initialisePropsRef, t.identifier("call")),
t.memberExpression(
t.cloneNode(initialisePropsRef),
t.identifier("call"),
),
[t.thisExpression()],
),
),
@ -227,7 +234,9 @@ export default function(api, options) {
if (path.isClassExpression()) {
path.scope.push({ id: ref });
path.replaceWith(t.assignmentExpression("=", ref, path.node));
path.replaceWith(
t.assignmentExpression("=", t.cloneNode(ref), path.node),
);
} else if (!path.node.id) {
// Anonymous class declaration
path.node.id = ref;

View File

@ -75,8 +75,8 @@ export default function() {
.reverse()
.reduce(function(acc, decorator) {
return buildClassDecorator({
CLASS_REF: name,
DECORATOR: decorator,
CLASS_REF: t.cloneNode(name),
DECORATOR: t.cloneNode(decorator),
INNER: acc,
}).expression;
}, classPath.node);
@ -166,9 +166,11 @@ export default function() {
"=",
descriptor,
t.callExpression(state.addHelper("applyDecoratedDescriptor"), [
target,
property,
t.arrayExpression(decorators.map(dec => dec.expression)),
t.cloneNode(target),
t.cloneNode(property),
t.arrayExpression(
decorators.map(dec => t.cloneNode(dec.expression)),
),
t.objectExpression([
t.objectProperty(
t.identifier("enumerable"),
@ -182,21 +184,23 @@ export default function() {
} else {
acc = acc.concat(
t.callExpression(state.addHelper("applyDecoratedDescriptor"), [
target,
property,
t.arrayExpression(decorators.map(dec => dec.expression)),
t.cloneNode(target),
t.cloneNode(property),
t.arrayExpression(
decorators.map(dec => t.cloneNode(dec.expression)),
),
t.isObjectProperty(node) ||
t.isClassProperty(node, { static: true })
? buildGetObjectInitializer({
TEMP: path.scope.generateDeclaredUidIdentifier("init"),
TARGET: target,
PROPERTY: property,
TARGET: t.cloneNode(target),
PROPERTY: t.cloneNode(property),
}).expression
: buildGetDescriptor({
TARGET: target,
PROPERTY: property,
TARGET: t.cloneNode(target),
PROPERTY: t.cloneNode(property),
}).expression,
target,
t.cloneNode(target),
]),
);
}
@ -205,9 +209,9 @@ export default function() {
}, []);
return t.sequenceExpression([
t.assignmentExpression("=", name, path.node),
t.assignmentExpression("=", t.cloneNode(name), path.node),
t.sequenceExpression(exprs),
name,
t.cloneNode(name),
]);
}
@ -222,7 +226,9 @@ export default function() {
return;
}
const ref = node.id || path.scope.generateUidIdentifier("class");
const ref = node.id
? t.cloneNode(node.id)
: path.scope.generateUidIdentifier("class");
const letDeclaration = t.variableDeclaration("let", [
t.variableDeclarator(ref, t.toExpression(node)),
]);
@ -232,7 +238,7 @@ export default function() {
path.parentPath.replaceWithMultiple([
letDeclaration,
t.exportNamedDeclaration(null, [
t.exportSpecifier(ref, t.identifier("default")),
t.exportSpecifier(t.cloneNode(ref), t.identifier("default")),
]),
]);
} else {
@ -261,10 +267,10 @@ export default function() {
path.replaceWith(
t.callExpression(state.addHelper("initializerDefineProperty"), [
path.get("left.object").node,
t.cloneNode(path.get("left.object").node),
t.stringLiteral(path.get("left.property").node.name),
path.get("right.arguments")[0].node,
path.get("right.arguments")[1].node,
t.cloneNode(path.get("right.arguments")[0].node),
t.cloneNode(path.get("right.arguments")[1].node),
]),
);
},

View File

@ -16,8 +16,13 @@ export default function() {
const uid = scope.generateUidIdentifier(exported.name);
const nodes = [
t.importDeclaration([t.importDefaultSpecifier(uid)], node.source),
t.exportNamedDeclaration(null, [t.exportSpecifier(uid, exported)]),
t.importDeclaration(
[t.importDefaultSpecifier(uid)],
t.cloneNode(node.source),
),
t.exportNamedDeclaration(null, [
t.exportSpecifier(t.cloneNode(uid), exported),
]),
];
if (specifiers.length >= 1) {

View File

@ -26,8 +26,13 @@ export default function() {
const uid = scope.generateUidIdentifier(exported.name);
nodes.push(
t.importDeclaration([t.importNamespaceSpecifier(uid)], node.source),
t.exportNamedDeclaration(null, [t.exportSpecifier(uid, exported)]),
t.importDeclaration(
[t.importNamespaceSpecifier(uid)],
t.cloneNode(node.source),
),
t.exportNamedDeclaration(null, [
t.exportSpecifier(t.cloneNode(uid), exported),
]),
);
if (node.specifiers.length >= 1) {

View File

@ -95,7 +95,7 @@ export default function(api, opts) {
impureComputedPropertyDeclarators,
restElement.argument,
t.callExpression(file.addHelper("objectWithoutProperties"), [
objRef,
t.cloneNode(objRef),
keyExpression,
]),
];
@ -124,7 +124,7 @@ export default function(api, opts) {
parentPath.ensureBlock();
parentPath.get("body").unshiftContainer("body", declar);
paramPath.replaceWith(uid);
paramPath.replaceWith(t.cloneNode(uid));
}
}
@ -180,7 +180,10 @@ export default function(api, opts) {
);
// replace foo() with _foo
this.originalPath.replaceWith(
t.variableDeclarator(this.originalPath.node.id, initRef),
t.variableDeclarator(
this.originalPath.node.id,
t.cloneNode(initRef),
),
);
return;
@ -247,8 +250,9 @@ export default function(api, opts) {
const specifiers = [];
for (const name in path.getOuterBindingIdentifiers(path)) {
const id = t.identifier(name);
specifiers.push(t.exportSpecifier(id, id));
specifiers.push(
t.exportSpecifier(t.identifier(name), t.identifier(name)),
);
}
// Split the declaration and export list into two declarations so that the variable
@ -324,7 +328,9 @@ export default function(api, opts) {
path.ensureBlock();
node.body.body.unshift(
t.variableDeclaration("var", [t.variableDeclarator(left, temp)]),
t.variableDeclaration("var", [
t.variableDeclarator(left, t.cloneNode(temp)),
]),
);
return;
@ -344,7 +350,7 @@ export default function(api, opts) {
node.body.body.unshift(
t.variableDeclaration(node.left.kind, [
t.variableDeclarator(pattern, key),
t.variableDeclarator(pattern, t.cloneNode(key)),
]),
);
},

View File

@ -7,7 +7,6 @@ export default function(api, options) {
function optional(path, replacementPath) {
const { scope } = path;
const optionals = [];
const nil = scope.buildUndefinedNode();
let objectPath = path;
while (objectPath.isMemberExpression() || objectPath.isCallExpression()) {
@ -40,7 +39,11 @@ export default function(api, options) {
} else {
ref = scope.maybeGenerateMemoised(chain);
if (ref) {
check = t.assignmentExpression("=", ref, chain);
check = t.assignmentExpression(
"=",
t.cloneNode(ref),
t.cloneNode(chain),
);
node[replaceKey] = ref;
} else {
check = ref = chain;
@ -65,7 +68,7 @@ export default function(api, options) {
context = object;
}
node.arguments.unshift(context);
node.arguments.unshift(t.cloneNode(context));
node.callee = t.memberExpression(node.callee, t.identifier("call"));
}
}
@ -83,7 +86,7 @@ export default function(api, options) {
scope.buildUndefinedNode(),
),
),
nil,
scope.buildUndefinedNode(),
replacementPath.node,
),
);

View File

@ -1,12 +1,12 @@
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;
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;
(_foo = foo) === null || _foo === void 0 ? void 0 : _foo(foo);
(_foo2 = foo) === null || _foo2 === void 0 ? void 0 : _foo2.bar();
(_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;
(_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;

View File

@ -44,10 +44,10 @@ export default function() {
const call = optimizeArrow
? right.body
: t.callExpression(right, [placeholder]);
: t.callExpression(right, [t.cloneNode(placeholder)]);
path.replaceWith(
t.sequenceExpression([
t.assignmentExpression("=", placeholder, left),
t.assignmentExpression("=", t.cloneNode(placeholder), left),
call,
]),
);

View File

@ -10,11 +10,10 @@ export default function() {
const { operator, argument } = path.node;
if (operator !== "throw") return;
const arg = t.identifier("e");
const arrow = t.functionExpression(
null,
[arg],
t.blockStatement([t.throwStatement(arg)]),
[t.identifier("e")],
t.blockStatement([t.throwStatement(t.identifier("e"))]),
);
path.replaceWith(t.callExpression(arrow, [argument]));

View File

@ -34,7 +34,7 @@ export default function(api, options) {
path.replaceWith(node.declaration);
path.insertAfter(
t.exportNamedDeclaration(null, [
t.exportSpecifier(ref, t.identifier("default")),
t.exportSpecifier(t.cloneNode(ref), t.identifier("default")),
]),
);
},

View File

@ -34,7 +34,7 @@ export default class LooseClassTransformer extends VanillaTransformer {
classRef = this._protoAlias;
}
const methodName = t.memberExpression(
classRef,
t.cloneNode(classRef),
node.key,
node.computed || t.isLiteral(node.key),
);

View File

@ -387,12 +387,12 @@ export default class ClassTransformer {
// special case single arguments spread
bareSuperNode.arguments[1] = bareSuperNode.arguments[1].argument;
bareSuperNode.callee = t.memberExpression(
superRef,
t.cloneNode(superRef),
t.identifier("apply"),
);
} else {
bareSuperNode.callee = t.memberExpression(
superRef,
t.cloneNode(superRef),
t.identifier("call"),
);
}
@ -456,7 +456,7 @@ export default class ClassTransformer {
const superRef = this.superName || t.identifier("Function");
let thisRef = function() {
const ref = path.scope.generateDeclaredUidIdentifier("this");
thisRef = () => ref;
thisRef = () => t.cloneNode(ref);
return ref;
};

View File

@ -34,7 +34,7 @@ export default function(api, options) {
t.assignmentExpression(
"=",
t.memberExpression(
objId,
t.cloneNode(objId),
prop.key,
prop.computed || t.isLiteral(prop.key),
),
@ -62,7 +62,7 @@ export default function(api, options) {
body.push(
...buildMutatorMapAssign({
MUTATOR_MAP_REF: getMutatorId(),
KEY: key,
KEY: t.cloneNode(key),
VALUE: getValue(prop),
KIND: t.identifier(prop.kind),
}),
@ -74,7 +74,7 @@ export default function(api, options) {
if (prop.kind === "get" || prop.kind === "set") {
pushMutatorDefine(info, prop);
} else {
pushAssign(info.objId, prop, info.body);
pushAssign(t.cloneNode(info.objId), prop, info.body);
}
}
}
@ -100,7 +100,7 @@ export default function(api, options) {
body.push(
t.expressionStatement(
t.callExpression(state.addHelper("defineProperty"), [
objId,
t.cloneNode(objId),
key,
getValue(prop),
]),
@ -165,7 +165,7 @@ export default function(api, options) {
);
}
return mutatorRef;
return t.cloneNode(mutatorRef);
};
const single = pushComputedProps({
@ -183,7 +183,7 @@ export default function(api, options) {
t.expressionStatement(
t.callExpression(
state.addHelper("defineEnumerableProperties"),
[objId, mutatorRef],
[t.cloneNode(objId), t.cloneNode(mutatorRef)],
),
),
);
@ -192,7 +192,7 @@ export default function(api, options) {
if (single) {
path.replaceWith(single);
} else {
body.push(t.expressionStatement(objId));
body.push(t.expressionStatement(t.cloneNode(objId)));
path.replaceWithMultiple(body);
}
},

View File

@ -62,10 +62,12 @@ export default function(api, options) {
let node;
if (op) {
node = t.expressionStatement(t.assignmentExpression(op, id, init));
node = t.expressionStatement(
t.assignmentExpression(op, id, t.cloneNode(init)),
);
} else {
node = t.variableDeclaration(this.kind, [
t.variableDeclarator(id, init),
t.variableDeclarator(id, t.cloneNode(init)),
]);
}
@ -76,13 +78,14 @@ export default function(api, options) {
buildVariableDeclaration(id, init) {
const declar = t.variableDeclaration("var", [
t.variableDeclarator(id, init),
t.variableDeclarator(t.cloneNode(id), t.cloneNode(init)),
]);
declar._blockHoist = this.blockHoist;
return declar;
}
push(id, init) {
push(id, _init) {
const init = t.cloneNode(_init);
if (t.isObjectPattern(id)) {
this.pushObjectPattern(id, init);
} else if (t.isArrayPattern(id)) {
@ -164,7 +167,7 @@ export default function(api, options) {
if (t.isIdentifier(key) && !prop.computed) {
key = t.stringLiteral(prop.key.name);
}
keys.push(key);
keys.push(t.cloneNode(key));
}
keys = t.arrayExpression(keys);
@ -173,7 +176,7 @@ export default function(api, options) {
const value = t.callExpression(
this.addHelper("objectWithoutProperties"),
[objRef, keys],
[t.cloneNode(objRef), keys],
);
this.nodes.push(this.buildVariableAssignment(spreadProp.argument, value));
}
@ -182,7 +185,11 @@ export default function(api, options) {
if (t.isLiteral(prop.key)) prop.computed = true;
const pattern = prop.value;
const objRef = t.memberExpression(propRef, prop.key, prop.computed);
const objRef = t.memberExpression(
t.cloneNode(propRef),
prop.key,
prop.computed,
);
if (t.isPattern(pattern)) {
this.push(pattern, objRef);
@ -221,7 +228,7 @@ export default function(api, options) {
if (t.isRestElement(prop)) {
this.pushObjectRest(pattern, objRef, prop, i);
} else {
this.pushObjectProperty(prop, t.cloneNode(objRef));
this.pushObjectProperty(prop, objRef);
}
}
}
@ -344,7 +351,9 @@ export default function(api, options) {
if (!t.isArrayExpression(ref) && !t.isMemberExpression(ref)) {
const memo = this.scope.maybeGenerateMemoised(ref, true);
if (memo) {
this.nodes.push(this.buildVariableDeclaration(memo, ref));
this.nodes.push(
this.buildVariableDeclaration(memo, t.cloneNode(ref)),
);
ref = memo;
}
}
@ -367,8 +376,9 @@ export default function(api, options) {
const specifiers = [];
for (const name in path.getOuterBindingIdentifiers(path)) {
const id = t.identifier(name);
specifiers.push(t.exportSpecifier(id, id));
specifiers.push(
t.exportSpecifier(t.identifier(name), t.identifier(name)),
);
}
// Split the declaration and export list into two declarations so that the variable
@ -484,7 +494,7 @@ export default function(api, options) {
destructuring.init(node.left, ref || node.right);
if (ref) {
nodes.push(t.expressionStatement(ref));
nodes.push(t.expressionStatement(t.cloneNode(ref)));
}
path.replaceWithMultiple(nodes);
@ -526,7 +536,10 @@ export default function(api, options) {
} else {
nodes.push(
t.inherits(
destructuring.buildVariableAssignment(declar.id, declar.init),
destructuring.buildVariableAssignment(
declar.id,
t.cloneNode(declar.init),
),
declar,
),
);

View File

@ -54,7 +54,11 @@ export default function() {
path.replaceWith(
t.conditionalExpression(
t.binaryExpression("instanceof", t.thisExpression(), node.id),
t.binaryExpression(
"instanceof",
t.thisExpression(),
t.cloneNode(node.id),
),
constructor,
scope.buildUndefinedNode(),
),

View File

@ -39,8 +39,10 @@ export default function() {
});
if (objectRef) {
path.scope.push({ id: objectRef });
path.replaceWith(t.assignmentExpression("=", objectRef, path.node));
path.scope.push({ id: t.cloneNode(objectRef) });
path.replaceWith(
t.assignmentExpression("=", t.cloneNode(objectRef), path.node),
);
}
},
},

View File

@ -69,7 +69,7 @@ export default function convertFunctionParams(path, loose) {
if (left.isIdentifier()) {
body.push(
buildLooseDefaultParam({
ASSIGNMENT_IDENTIFIER: left.node,
ASSIGNMENT_IDENTIFIER: t.cloneNode(left.node),
DEFAULT_VALUE: right.node,
UNDEFINED: undefinedNode,
}),
@ -81,7 +81,7 @@ export default function convertFunctionParams(path, loose) {
buildLooseDestructuredDefaultParam({
ASSIGNMENT_IDENTIFIER: left.node,
DEFAULT_VALUE: right.node,
PARAMETER_NAME: paramName,
PARAMETER_NAME: t.cloneNode(paramName),
UNDEFINED: undefinedNode,
}),
);
@ -123,7 +123,7 @@ export default function convertFunctionParams(path, loose) {
]);
body.push(defNode);
param.replaceWith(uid);
param.replaceWith(t.cloneNode(uid));
}
if (!state.iife && !param.isIdentifier()) {

View File

@ -168,7 +168,11 @@ function optimiseIndexGetter(path, argsId, offset) {
// Avoid unnecessary '+ 0'
index = path.parent.property;
} else {
index = t.binaryExpression("+", path.parent.property, offsetLiteral);
index = t.binaryExpression(
"+",
path.parent.property,
t.cloneNode(offsetLiteral),
);
}
const { scope } = path;
@ -180,7 +184,7 @@ function optimiseIndexGetter(path, argsId, offset) {
ARGUMENTS: argsId,
OFFSET: offsetLiteral,
INDEX: index,
REF: temp,
REF: t.cloneNode(temp),
}),
);
} else {
@ -262,15 +266,16 @@ export default function convertFunctionRest(path) {
// There are only "shorthand" references
if (!state.deopted && !state.references.length) {
for (const { path, cause } of (state.candidates: Array)) {
const clonedArgsId = t.cloneNode(argsId);
switch (cause) {
case "indexGetter":
optimiseIndexGetter(path, argsId, state.offset);
optimiseIndexGetter(path, clonedArgsId, state.offset);
break;
case "lengthGetter":
optimiseLengthGetter(path, argsId, state.offset);
optimiseLengthGetter(path, clonedArgsId, state.offset);
break;
default:
path.replaceWith(argsId);
path.replaceWith(clonedArgsId);
}
}
return true;
@ -290,7 +295,7 @@ export default function convertFunctionRest(path) {
// this method has additional params, so we need to subtract
// the index of the current argument position from the
// position in the array that we want to populate
arrKey = t.binaryExpression("-", key, start);
arrKey = t.binaryExpression("-", t.cloneNode(key), t.cloneNode(start));
// we need to work out the size of the array that we're
// going to store all the rest parameters
@ -299,8 +304,8 @@ export default function convertFunctionRest(path) {
// with <0 if there are less arguments than params as it'll
// cause an error
arrLen = t.conditionalExpression(
t.binaryExpression(">", len, start),
t.binaryExpression("-", len, start),
t.binaryExpression(">", t.cloneNode(len), t.cloneNode(start)),
t.binaryExpression("-", t.cloneNode(len), t.cloneNode(start)),
t.numericLiteral(0),
);
}

View File

@ -34,8 +34,14 @@ export default function() {
t.expressionStatement(t.assignmentExpression("=", temp, left)),
);
}
nodes.push(buildDefaultsCallExpression(path.node, temp || left, file));
if (temp) nodes.push(temp);
nodes.push(
buildDefaultsCallExpression(
path.node,
t.cloneNode(temp || left),
file,
),
);
if (temp) nodes.push(t.cloneNode(temp));
path.replaceWithMultiple(nodes);
},

View File

@ -118,7 +118,7 @@ export default function(api, options) {
contextLiteral = t.thisExpression();
}
node.arguments.unshift(contextLiteral);
node.arguments.unshift(t.cloneNode(contextLiteral));
},
NewExpression(path, state) {

View File

@ -96,7 +96,10 @@ export default function(api, options) {
}
path.replaceWith(
t.callExpression(node.tag, [templateObject, ...quasi.expressions]),
t.callExpression(node.tag, [
t.cloneNode(templateObject),
...quasi.expressions,
]),
);
},

View File

@ -48,12 +48,11 @@ export default function() {
const call = t.callExpression(helper, [node.argument]);
const arg = path.get("argument");
if (arg.isIdentifier() && !path.scope.hasBinding(arg.node.name)) {
const undefLiteral = t.stringLiteral("undefined");
const unary = t.unaryExpression("typeof", node.argument);
const unary = t.unaryExpression("typeof", t.cloneNode(node.argument));
path.replaceWith(
t.conditionalExpression(
t.binaryExpression("===", unary, undefLiteral),
undefLiteral,
t.binaryExpression("===", unary, t.stringLiteral("undefined")),
t.stringLiteral("undefined"),
call,
),
);

View File

@ -222,6 +222,6 @@ export default class PathHoister {
uid = t.JSXExpressionContainer(uid);
}
this.path.replaceWith(uid);
this.path.replaceWith(t.cloneNode(uid));
}
}

View File

@ -110,9 +110,11 @@ export function insertAfter(nodes) {
if (this.node) {
const temp = this.scope.generateDeclaredUidIdentifier();
nodes.unshift(
t.expressionStatement(t.assignmentExpression("=", temp, this.node)),
t.expressionStatement(
t.assignmentExpression("=", t.cloneNode(temp), this.node),
),
);
nodes.push(t.expressionStatement(temp));
nodes.push(t.expressionStatement(t.cloneNode(temp)));
}
return this.replaceExpressionWithStatements(nodes);
} else if (Array.isArray(this.container)) {

View File

@ -237,7 +237,9 @@ export function replaceExpressionWithStatements(nodes: Array<Object>) {
if (!uid) {
const callee = this.get("callee");
uid = callee.scope.generateDeclaredUidIdentifier("ret");
callee.get("body").pushContainer("body", t.returnStatement(uid));
callee
.get("body")
.pushContainer("body", t.returnStatement(t.cloneNode(uid)));
loop.setData("expressionReplacementReturnUid", uid);
} else {
uid = t.identifier(uid.name);
@ -245,7 +247,9 @@ export function replaceExpressionWithStatements(nodes: Array<Object>) {
path
.get("expression")
.replaceWith(t.assignmentExpression("=", uid, path.node.expression));
.replaceWith(
t.assignmentExpression("=", t.cloneNode(uid), path.node.expression),
);
} else {
path.replaceWith(t.returnStatement(path.node.expression));
}

View File

@ -213,7 +213,7 @@ export default class Scope {
generateDeclaredUidIdentifier(name: string = "temp") {
const id = this.generateUidIdentifier(name);
this.push({ id });
return id;
return t.cloneNode(id);
}
/**
@ -326,7 +326,10 @@ export default class Scope {
return null;
} else {
const id = this.generateUidIdentifierBasedOnNode(node);
if (!dontPush) this.push({ id });
if (!dontPush) {
this.push({ id });
return t.cloneNode(id);
}
return id;
}
}

View File

@ -14,6 +14,7 @@ import {
assignmentExpression,
conditionalExpression,
} from "../builders/generated";
import cloneNode from "../clone/cloneNode";
export default function gatherSequenceExpressions(
nodes: Array<Object>,
@ -38,7 +39,7 @@ export default function gatherSequenceExpressions(
for (const key in bindings) {
declars.push({
kind: node.kind,
id: bindings[key],
id: cloneNode(bindings[key]),
});
}