clean up conditional assignment operator transformers
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
var t = require("../../types");
|
||||
|
||||
module.exports = function (opts) {
|
||||
var getObjRef = function (node, nodes, file, scope) {
|
||||
var obj = node.object;
|
||||
var temp = scope.generateUidBasedOnNode(obj, file);
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(temp, obj)
|
||||
]));
|
||||
return temp;
|
||||
};
|
||||
|
||||
var getPropRef = function (node, nodes, file, scope) {
|
||||
var prop = node.property;
|
||||
var key = t.toComputedKey(node, prop);
|
||||
if (t.isLiteral(key)) return key;
|
||||
|
||||
var temp = scope.generateUidBasedOnNode(prop, file);
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(temp, prop)
|
||||
]));
|
||||
return temp;
|
||||
};
|
||||
|
||||
var buildAbsoluteRef = function (node, nodes, file, scope) {
|
||||
if (t.isIdentifier(node)) return node;
|
||||
|
||||
var obj = getObjRef(node, nodes, file, scope);
|
||||
var prop = getPropRef(node, nodes, file, scope);
|
||||
|
||||
var computed = node.computed || t.isLiteral(prop);
|
||||
return t.memberExpression(obj, prop, computed);
|
||||
};
|
||||
|
||||
var buildAssignment = function (left, right) {
|
||||
return t.assignmentExpression("=", left, right);
|
||||
};
|
||||
|
||||
var exports = {};
|
||||
|
||||
exports.ExpressionStatement = function (node, parent, scope, context, file) {
|
||||
var expr = node.expression;
|
||||
if (!opts.is(expr)) return;
|
||||
|
||||
var nodes = [];
|
||||
var left = buildAbsoluteRef(expr.left, nodes, file, scope);
|
||||
|
||||
nodes.push(t.ifStatement(
|
||||
opts.build(left, file),
|
||||
t.expressionStatement(buildAssignment(left, expr.right))
|
||||
));
|
||||
|
||||
return nodes;
|
||||
};
|
||||
|
||||
exports.AssignmentExpression = function (node, parent, scope, context, file) {
|
||||
if (t.isExpressionStatement(parent)) return;
|
||||
if (!opts.is(node)) return;
|
||||
|
||||
var nodes = [];
|
||||
var left = buildAbsoluteRef(node.left, nodes, file, scope);
|
||||
|
||||
nodes.push(t.logicalExpression(
|
||||
"&&",
|
||||
opts.build(left, file),
|
||||
buildAssignment(left, node.right)
|
||||
));
|
||||
|
||||
nodes.push(left);
|
||||
|
||||
return t.toSequenceExpression(nodes, scope);
|
||||
};
|
||||
|
||||
return exports;
|
||||
};
|
||||
0
lib/6to5/transformation/helpers/explode-unary.js
Normal file
0
lib/6to5/transformation/helpers/explode-unary.js
Normal file
@@ -1,86 +1,18 @@
|
||||
var t = require("../../types");
|
||||
|
||||
var isMallet = function (node) {
|
||||
var is = t.isAssignmentExpression(node) && node.operator === "||=";
|
||||
if (is) {
|
||||
var left = node.left;
|
||||
if (!t.isMemberExpression(left) && !t.isIdentifier(left)) {
|
||||
throw new Error("Expected type MemeberExpression or Identifier");
|
||||
module.exports = require("../helpers/build-conditional-assignment-operator-transformer")({
|
||||
is: function (node) {
|
||||
var is = t.isAssignmentExpression(node) && node.operator === "||=";
|
||||
if (is) {
|
||||
var left = node.left;
|
||||
if (!t.isMemberExpression(left) && !t.isIdentifier(left)) {
|
||||
throw new Error("Expected type MemeberExpression or Identifier");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
build: function (node) {
|
||||
return t.unaryExpression("!", node, true);
|
||||
}
|
||||
};
|
||||
|
||||
var getObjRef = function (node, nodes, file, scope) {
|
||||
var obj = node.object;
|
||||
if (t.isIdentifier(obj)) return obj;
|
||||
|
||||
var temp = scope.generateUidBasedOnNode(obj, file);
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(temp, obj)
|
||||
]));
|
||||
return temp;
|
||||
};
|
||||
|
||||
var getPropRef = function (node, nodes, file, scope) {
|
||||
var prop = node.property;
|
||||
var key = t.toComputedKey(node, prop);
|
||||
if (t.isLiteral(key)) return key;
|
||||
|
||||
var temp = scope.generateUidBasedOnNode(prop, file);
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(temp, prop)
|
||||
]));
|
||||
return temp;
|
||||
};
|
||||
|
||||
var buildAbsoluteRef = function (node, nodes, file, scope) {
|
||||
if (t.isIdentifier(node)) return node;
|
||||
|
||||
var obj = getObjRef(node, nodes, file, scope);
|
||||
var prop = getPropRef(node, nodes, file, scope);
|
||||
|
||||
var computed = node.computed || t.isLiteral(prop);
|
||||
return t.memberExpression(obj, prop, computed);
|
||||
};
|
||||
|
||||
var buildIsFalsey = function (node) {
|
||||
return t.unaryExpression("!", node, true);
|
||||
};
|
||||
|
||||
var buildAssignment = function (left, right) {
|
||||
return t.assignmentExpression("=", left, right);
|
||||
};
|
||||
|
||||
exports.ExpressionStatement = function (node, parent, file, scope) {
|
||||
var expr = node.expression;
|
||||
if (!isMallet(expr)) return;
|
||||
|
||||
var nodes = [];
|
||||
var left = buildAbsoluteRef(expr.left, nodes, file, scope);
|
||||
|
||||
nodes.push(t.ifStatement(
|
||||
buildIsFalsey(left),
|
||||
t.expressionStatement(buildAssignment(left, expr.right))
|
||||
));
|
||||
|
||||
return nodes;
|
||||
};
|
||||
|
||||
exports.AssignmentExpression = function (node, parent, file, scope) {
|
||||
if (t.isExpressionStatement(parent)) return;
|
||||
if (!isMallet(node)) return;
|
||||
|
||||
var nodes = [];
|
||||
var left = buildAbsoluteRef(node.left, nodes, file, scope);
|
||||
|
||||
nodes.push(t.logicalExpression(
|
||||
"&&",
|
||||
buildIsFalsey(left),
|
||||
buildAssignment(left, node.right)
|
||||
));
|
||||
|
||||
nodes.push(left);
|
||||
|
||||
return t.toSequenceExpression(nodes, scope);
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1,88 +1,20 @@
|
||||
var t = require("../../types");
|
||||
|
||||
var isMemo = function (node) {
|
||||
var is = t.isAssignmentExpression(node) && node.operator === "?=";
|
||||
if (is) t.assertMemberExpression(node.left);
|
||||
return is;
|
||||
};
|
||||
module.exports = require("../helpers/build-conditional-assignment-operator-transformer")({
|
||||
is: function (node) {
|
||||
var is = t.isAssignmentExpression(node) && node.operator === "?=";
|
||||
if (is) t.assertMemberExpression(node.left);
|
||||
return is;
|
||||
},
|
||||
|
||||
var getPropRef = function (nodes, member, file, scope) {
|
||||
var prop = member.property;
|
||||
var key = t.toComputedKey(member, member.property);
|
||||
if (t.isLiteral(key)) {
|
||||
return key;
|
||||
} else {
|
||||
var temp = scope.generateUidBasedOnNode(prop, file);
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(temp, prop)
|
||||
]));
|
||||
return temp;
|
||||
build: function (node, file) {
|
||||
return t.unaryExpression(
|
||||
"!",
|
||||
t.callExpression(
|
||||
t.memberExpression(file.addHelper("has-own"), t.identifier("call")),
|
||||
[node.object, node.property]
|
||||
),
|
||||
true
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
var getObjRef = function (nodes, obj, file, scope) {
|
||||
var temp = scope.generateUidBasedOnNode(obj, file);
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(temp, obj)
|
||||
]));
|
||||
return temp;
|
||||
};
|
||||
|
||||
var buildHasOwn = function (obj, prop, file) {
|
||||
return t.unaryExpression(
|
||||
"!",
|
||||
t.callExpression(
|
||||
t.memberExpression(file.addHelper("has-own"), t.identifier("call")),
|
||||
[obj, prop]
|
||||
),
|
||||
true
|
||||
);
|
||||
};
|
||||
|
||||
var buildAbsoluteRef = function (left, obj, prop) {
|
||||
var computed = left.computed || t.isLiteral(prop);
|
||||
return t.memberExpression(obj, prop, computed);
|
||||
};
|
||||
|
||||
var buildAssignment = function (expr, obj, prop) {
|
||||
return t.assignmentExpression("=", buildAbsoluteRef(expr.left, obj, prop), expr.right);
|
||||
};
|
||||
|
||||
exports.ExpressionStatement = function (node, parent, scope, context, file) {
|
||||
var expr = node.expression;
|
||||
if (!isMemo(expr)) return;
|
||||
|
||||
var nodes = [];
|
||||
|
||||
var left = expr.left;
|
||||
var obj = getObjRef(nodes, left.object, file, scope);
|
||||
var prop = getPropRef(nodes, left, file, scope);
|
||||
|
||||
nodes.push(t.ifStatement(
|
||||
buildHasOwn(obj, prop, file),
|
||||
t.expressionStatement(buildAssignment(expr, obj, prop))
|
||||
));
|
||||
|
||||
return nodes;
|
||||
};
|
||||
|
||||
exports.AssignmentExpression = function (node, parent, scope, context, file) {
|
||||
if (t.isExpressionStatement(parent)) return;
|
||||
if (!isMemo(node)) return;
|
||||
|
||||
var nodes = [];
|
||||
|
||||
var left = node.left;
|
||||
var obj = getObjRef(nodes, left.object, file, scope);
|
||||
var prop = getPropRef(nodes, left, file, scope);
|
||||
|
||||
nodes.push(t.logicalExpression(
|
||||
"&&",
|
||||
buildHasOwn(obj, prop, file),
|
||||
buildAssignment(node, obj, prop)
|
||||
));
|
||||
|
||||
nodes.push(buildAbsoluteRef(left, obj, prop));
|
||||
|
||||
return t.toSequenceExpression(nodes, scope);
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
obj ||= {};
|
||||
|
||||
obj.x ||= 2;
|
||||
|
||||
console.log(obj.x ||= 2);
|
||||
|
||||
obj.x.x ||= 2;
|
||||
|
||||
console.log(obj.x.x ||= 2);
|
||||
|
||||
obj[x()] ||= 2;
|
||||
|
||||
console.log(obj[x()] ||= 2);
|
||||
|
||||
obj[y()][x()] ||= 2;
|
||||
|
||||
console.log(obj[y()][x()] ||= 2);
|
||||
@@ -88,3 +88,19 @@ assert.equal(obj, 2);
|
||||
|
||||
obj = 0;
|
||||
assert.equal(obj ||= 2 , 2);
|
||||
|
||||
var calls = 0;
|
||||
var q = { q: 3 };
|
||||
var o = {
|
||||
get p() {
|
||||
calls++;
|
||||
return q;
|
||||
}
|
||||
};
|
||||
|
||||
o.p.q ||= 2;
|
||||
assert.equal(1, calls);
|
||||
o.p.f ||= 2;
|
||||
assert.equal(2, calls);
|
||||
assert.equal(3, o.p.q);
|
||||
assert.equal(2, o.p.f);
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
var _obj$x2, _x2, _obj$y2, _x4;
|
||||
if (!obj) obj = {};
|
||||
if (!obj.x) obj.x = 2;
|
||||
|
||||
|
||||
console.log((!obj.x && (obj.x = 2), obj.x));
|
||||
|
||||
var _obj$x = obj.x;
|
||||
if (!_obj$x.x) _obj$x.x = 2;
|
||||
|
||||
|
||||
console.log((_obj$x2 = obj.x, !_obj$x2.x && (_obj$x2.x = 2), _obj$x2.x));
|
||||
|
||||
var _x = x();
|
||||
|
||||
if (!obj[_x]) obj[_x] = 2;
|
||||
|
||||
|
||||
console.log((_x2 = x(), !obj[_x2] && (obj[_x2] = 2), obj[_x2]));
|
||||
|
||||
var _obj$y = obj[y()];
|
||||
var _x3 = x();
|
||||
|
||||
if (!_obj$y[_x3]) _obj$y[_x3] = 2;
|
||||
|
||||
|
||||
console.log((_obj$y2 = obj[y()], _x4 = x(), !_obj$y2[_x4] && (_obj$y2[_x4] = 2), _obj$y2[_x4]));
|
||||
@@ -1,13 +0,0 @@
|
||||
var obj = {};
|
||||
|
||||
obj.x ?= 2;
|
||||
|
||||
console.log(obj.x ?= 2);
|
||||
|
||||
obj[x()] ?= 2;
|
||||
|
||||
console.log(obj[x()] ?= 2);
|
||||
|
||||
obj[y()][x()] ?= 2;
|
||||
|
||||
console.log(obj[y()][x()] ?= 2);
|
||||
@@ -18,3 +18,19 @@ assert.equal(obj.x, undefined);
|
||||
|
||||
obj = { x: undefined }
|
||||
assert.equal(obj.x ?= 2, undefined);
|
||||
|
||||
var calls = 0;
|
||||
var q = { q: 3 };
|
||||
var o = {
|
||||
get p() {
|
||||
calls++;
|
||||
return q;
|
||||
}
|
||||
};
|
||||
|
||||
o.p.q ?= 2;
|
||||
assert.equal(1, calls);
|
||||
o.p.f ?= 2;
|
||||
assert.equal(2, calls);
|
||||
assert.equal(3, o.p.q);
|
||||
assert.equal(2, o.p.f);
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
var _obj2, _obj4, _x2, _obj$y2, _x4;
|
||||
var _hasOwn = Object.prototype.hasOwnProperty;
|
||||
var obj = {};
|
||||
|
||||
var _obj = obj;
|
||||
if (!_hasOwn.call(_obj, "x")) _obj.x = 2;
|
||||
|
||||
|
||||
console.log((_obj2 = obj, !_hasOwn.call(_obj2, "x") && (_obj2.x = 2), _obj2.x));
|
||||
|
||||
var _obj3 = obj;
|
||||
var _x = x();
|
||||
|
||||
if (!_hasOwn.call(_obj3, _x)) _obj3[_x] = 2;
|
||||
|
||||
|
||||
console.log((_obj4 = obj, _x2 = x(), !_hasOwn.call(_obj4, _x2) && (_obj4[_x2] = 2), _obj4[_x2]));
|
||||
|
||||
var _obj$y = obj[y()];
|
||||
var _x3 = x();
|
||||
|
||||
if (!_hasOwn.call(_obj$y, _x3)) _obj$y[_x3] = 2;
|
||||
|
||||
|
||||
console.log((_obj$y2 = obj[y()], _x4 = x(), !_hasOwn.call(_obj$y2, _x4) && (_obj$y2[_x4] = 2), _obj$y2[_x4]));
|
||||
Reference in New Issue
Block a user