Fixup builder-binary-assignment-operator-visitor (#5969)

Using a `SequenceExpression` instead, we avoid awkward
`AssignmentExpression`s as direct children of `BlockStatement`s.
This commit is contained in:
Justin Ridgewell
2017-07-20 11:47:47 -04:00
committed by Henry Zhu
parent 245c78dcdc
commit c60bf9a897
3 changed files with 29 additions and 49 deletions

View File

@@ -2,53 +2,30 @@ import explode from "babel-helper-explode-assignable-expression";
import * as t from "babel-types";
export default function(opts: { build: Function, operator: string }): Object {
const visitor = {};
const { build, operator } = opts;
function isAssignment(node) {
return node && node.operator === opts.operator + "=";
}
return {
AssignmentExpression(path) {
const { node, scope } = path;
if (node.operator !== operator + "=") return;
function buildAssignment(left, right) {
return t.assignmentExpression("=", left, right);
}
const nodes = [];
const exploded = explode(node.left, nodes, this, scope);
nodes.push(
t.assignmentExpression(
"=",
exploded.ref,
build(exploded.uid, node.right),
),
);
path.replaceWith(t.sequenceExpression(nodes));
},
visitor.ExpressionStatement = function(path, file) {
// hit the `AssignmentExpression` one below
if (path.isCompletionRecord()) return;
const expr = path.node.expression;
if (!isAssignment(expr)) return;
const nodes = [];
const exploded = explode(expr.left, nodes, file, path.scope, true);
nodes.push(
t.expressionStatement(
buildAssignment(exploded.ref, opts.build(exploded.uid, expr.right)),
),
);
path.replaceWithMultiple(nodes);
BinaryExpression(path) {
const { node } = path;
if (node.operator === operator) {
path.replaceWith(build(node.left, node.right));
}
},
};
visitor.AssignmentExpression = function(path, file) {
const { node, scope } = path;
if (!isAssignment(node)) return;
const nodes = [];
const exploded = explode(node.left, nodes, file, scope);
nodes.push(
buildAssignment(exploded.ref, opts.build(exploded.uid, node.right)),
);
path.replaceWithMultiple(nodes);
};
visitor.BinaryExpression = function(path) {
const { node } = path;
if (node.operator === opts.operator) {
path.replaceWith(opts.build(node.left, node.right));
}
};
return visitor;
}