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 { addHelper(name: string): Object {
const declar = this.declarations[name]; const declar = this.declarations[name];
if (declar) return declar; if (declar) return t.cloneNode(declar);
const generator = this.get("helperGenerator"); const generator = this.get("helperGenerator");
const runtime = this.get("helpersNamespace"); const runtime = this.get("helpersNamespace");

View File

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

View File

@ -206,9 +206,12 @@ export default class ReplaceSupers {
return; return;
} else if (t.isMemberExpression(parent) && !methodNode.static) { } else if (t.isMemberExpression(parent) && !methodNode.static) {
// super.test -> objectRef.prototype.test // super.test -> objectRef.prototype.test
return t.memberExpression(superRef, t.identifier("prototype")); return t.memberExpression(
t.cloneNode(superRef),
t.identifier("prototype"),
);
} else { } 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; // super.age += 2; -> let _ref = super.age; super.age = _ref + 2;
ref = ref || path.scope.generateUidIdentifier("ref"); ref = ref || path.scope.generateUidIdentifier("ref");
return [ return [
t.variableDeclaration("var", [t.variableDeclarator(ref, node.left)]), t.variableDeclaration("var", [
t.variableDeclarator(t.cloneNode(ref), node.left),
]),
t.expressionStatement( t.expressionStatement(
t.assignmentExpression( t.assignmentExpression(
"=", "=",
node.left, 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 value: VALUE
}); });
`({ `({
REF: ref, REF: t.cloneNode(ref),
KEY: t.isIdentifier(key) && !computed ? t.stringLiteral(key.name) : key, KEY: t.isIdentifier(key) && !computed ? t.stringLiteral(key.name) : key,
VALUE: value || scope.buildUndefinedNode(), VALUE: value || scope.buildUndefinedNode(),
}); });
@ -62,7 +62,11 @@ export default function(api, options) {
const buildClassPropertyLoose = (ref, { key, value, computed }, scope) => { const buildClassPropertyLoose = (ref, { key, value, computed }, scope) => {
return template.statement`MEMBER = VALUE`({ 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(), VALUE: value || scope.buildUndefinedNode(),
}); });
}; };
@ -199,7 +203,10 @@ export default function(api, options) {
instanceBody = [ instanceBody = [
t.expressionStatement( t.expressionStatement(
t.callExpression( t.callExpression(
t.memberExpression(initialisePropsRef, t.identifier("call")), t.memberExpression(
t.cloneNode(initialisePropsRef),
t.identifier("call"),
),
[t.thisExpression()], [t.thisExpression()],
), ),
), ),
@ -227,7 +234,9 @@ export default function(api, options) {
if (path.isClassExpression()) { if (path.isClassExpression()) {
path.scope.push({ id: ref }); 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) { } else if (!path.node.id) {
// Anonymous class declaration // Anonymous class declaration
path.node.id = ref; path.node.id = ref;

View File

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

View File

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

View File

@ -95,7 +95,7 @@ export default function(api, opts) {
impureComputedPropertyDeclarators, impureComputedPropertyDeclarators,
restElement.argument, restElement.argument,
t.callExpression(file.addHelper("objectWithoutProperties"), [ t.callExpression(file.addHelper("objectWithoutProperties"), [
objRef, t.cloneNode(objRef),
keyExpression, keyExpression,
]), ]),
]; ];
@ -124,7 +124,7 @@ export default function(api, opts) {
parentPath.ensureBlock(); parentPath.ensureBlock();
parentPath.get("body").unshiftContainer("body", declar); 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 // replace foo() with _foo
this.originalPath.replaceWith( this.originalPath.replaceWith(
t.variableDeclarator(this.originalPath.node.id, initRef), t.variableDeclarator(
this.originalPath.node.id,
t.cloneNode(initRef),
),
); );
return; return;
@ -247,8 +250,9 @@ export default function(api, opts) {
const specifiers = []; const specifiers = [];
for (const name in path.getOuterBindingIdentifiers(path)) { for (const name in path.getOuterBindingIdentifiers(path)) {
const id = t.identifier(name); specifiers.push(
specifiers.push(t.exportSpecifier(id, id)); t.exportSpecifier(t.identifier(name), t.identifier(name)),
);
} }
// Split the declaration and export list into two declarations so that the variable // Split the declaration and export list into two declarations so that the variable
@ -324,7 +328,9 @@ export default function(api, opts) {
path.ensureBlock(); path.ensureBlock();
node.body.body.unshift( node.body.body.unshift(
t.variableDeclaration("var", [t.variableDeclarator(left, temp)]), t.variableDeclaration("var", [
t.variableDeclarator(left, t.cloneNode(temp)),
]),
); );
return; return;
@ -344,7 +350,7 @@ export default function(api, opts) {
node.body.body.unshift( node.body.body.unshift(
t.variableDeclaration(node.left.kind, [ 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) { function optional(path, replacementPath) {
const { scope } = path; const { scope } = path;
const optionals = []; const optionals = [];
const nil = scope.buildUndefinedNode();
let objectPath = path; let objectPath = path;
while (objectPath.isMemberExpression() || objectPath.isCallExpression()) { while (objectPath.isMemberExpression() || objectPath.isCallExpression()) {
@ -40,7 +39,11 @@ export default function(api, options) {
} else { } else {
ref = scope.maybeGenerateMemoised(chain); ref = scope.maybeGenerateMemoised(chain);
if (ref) { if (ref) {
check = t.assignmentExpression("=", ref, chain); check = t.assignmentExpression(
"=",
t.cloneNode(ref),
t.cloneNode(chain),
);
node[replaceKey] = ref; node[replaceKey] = ref;
} else { } else {
check = ref = chain; check = ref = chain;
@ -65,7 +68,7 @@ export default function(api, options) {
context = object; context = object;
} }
node.arguments.unshift(context); node.arguments.unshift(t.cloneNode(context));
node.callee = t.memberExpression(node.callee, t.identifier("call")); node.callee = t.memberExpression(node.callee, t.identifier("call"));
} }
} }
@ -83,7 +86,7 @@ export default function(api, options) {
scope.buildUndefinedNode(), scope.buildUndefinedNode(),
), ),
), ),
nil, scope.buildUndefinedNode(),
replacementPath.node, 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); (_foo = foo) === null || _foo === void 0 ? void 0 : _foo(foo);
(_foo2 = foo) === null || _foo2 === void 0 ? void 0 : _foo2.bar(); (_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); (_foo$bar = foo.bar) === null || _foo$bar === void 0 ? void 0 : _foo$bar.call(foo, 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); (_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);
(_foo5 = foo) === null || _foo5 === void 0 ? void 0 : _foo5().bar; (_foo4 = foo) === null || _foo4 === void 0 ? void 0 : _foo4().bar;
(_foo6 = foo) === null || _foo6 === void 0 ? void 0 : (_foo7 = _foo6()) === null || _foo7 === void 0 ? void 0 : _foo7.bar; (_foo5 = foo) === null || _foo5 === void 0 ? void 0 : (_foo6 = _foo5()) === null || _foo6 === void 0 ? void 0 : _foo6.bar;
(_foo$bar2 = (_foo8 = foo).bar) === null || _foo$bar2 === void 0 ? void 0 : _foo$bar2.call(_foo8).baz; (_foo$bar2 = foo.bar) === null || _foo$bar2 === void 0 ? void 0 : _foo$bar2.call(foo).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; (_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;
(_foo10 = foo) === null || _foo10 === void 0 ? void 0 : (_foo10$bar = _foo10.bar) === null || _foo10$bar === void 0 ? void 0 : _foo10$bar.call(_foo10).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;
(_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; (_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 const call = optimizeArrow
? right.body ? right.body
: t.callExpression(right, [placeholder]); : t.callExpression(right, [t.cloneNode(placeholder)]);
path.replaceWith( path.replaceWith(
t.sequenceExpression([ t.sequenceExpression([
t.assignmentExpression("=", placeholder, left), t.assignmentExpression("=", t.cloneNode(placeholder), left),
call, call,
]), ]),
); );

View File

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

View File

@ -34,7 +34,7 @@ export default function(api, options) {
path.replaceWith(node.declaration); path.replaceWith(node.declaration);
path.insertAfter( path.insertAfter(
t.exportNamedDeclaration(null, [ 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; classRef = this._protoAlias;
} }
const methodName = t.memberExpression( const methodName = t.memberExpression(
classRef, t.cloneNode(classRef),
node.key, node.key,
node.computed || t.isLiteral(node.key), node.computed || t.isLiteral(node.key),
); );

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -96,7 +96,10 @@ export default function(api, options) {
} }
path.replaceWith( 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 call = t.callExpression(helper, [node.argument]);
const arg = path.get("argument"); const arg = path.get("argument");
if (arg.isIdentifier() && !path.scope.hasBinding(arg.node.name)) { if (arg.isIdentifier() && !path.scope.hasBinding(arg.node.name)) {
const undefLiteral = t.stringLiteral("undefined"); const unary = t.unaryExpression("typeof", t.cloneNode(node.argument));
const unary = t.unaryExpression("typeof", node.argument);
path.replaceWith( path.replaceWith(
t.conditionalExpression( t.conditionalExpression(
t.binaryExpression("===", unary, undefLiteral), t.binaryExpression("===", unary, t.stringLiteral("undefined")),
undefLiteral, t.stringLiteral("undefined"),
call, call,
), ),
); );

View File

@ -222,6 +222,6 @@ export default class PathHoister {
uid = t.JSXExpressionContainer(uid); 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) { if (this.node) {
const temp = this.scope.generateDeclaredUidIdentifier(); const temp = this.scope.generateDeclaredUidIdentifier();
nodes.unshift( 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); return this.replaceExpressionWithStatements(nodes);
} else if (Array.isArray(this.container)) { } else if (Array.isArray(this.container)) {

View File

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

View File

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

View File

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