Logical Assignment: ensure computed key isn't recomputed (#7604)

* Logical Assignment: ensure computed key isn't recomputed

* More tests
This commit is contained in:
Justin Ridgewell
2018-03-20 23:06:09 +00:00
committed by GitHub
parent f0d681a238
commit 55bf55398a
4 changed files with 110 additions and 12 deletions

View File

@@ -16,27 +16,33 @@ export default declare(api => {
return;
}
let ref;
const lhs = t.cloneNode(left);
if (t.isMemberExpression(left)) {
const { object } = left;
const { object, property, computed } = left;
const memo = scope.maybeGenerateMemoised(object);
if (memo) {
path
.get("left.object")
.replaceWith(
t.assignmentExpression("=", t.cloneNode(memo), object),
);
left.object = memo;
lhs.object = t.assignmentExpression("=", t.cloneNode(memo), object);
}
ref = t.cloneNode(left);
ref.object = t.cloneNode(memo);
if (computed) {
const memo = scope.maybeGenerateMemoised(property);
if (memo) {
left.property = memo;
lhs.property = t.assignmentExpression(
"=",
t.cloneNode(memo),
property,
);
}
}
}
path.replaceWith(
t.logicalExpression(
operator.slice(0, -1),
left,
t.assignmentExpression("=", ref || t.cloneNode(left), right),
lhs,
t.assignmentExpression("=", left, right),
),
);
},

View File

@@ -38,3 +38,35 @@ assert.equal(deep.obj.x &&= 0, 0);
assert.equal(gets, 3);
assert.equal(deep.obj.x &&= 3, 0);
assert.equal(gets, 4);
var key = 0;
assert.equal(obj[++key] ||= 1, 1);
assert.equal(key, 1);
key = 0;
assert.equal(obj[++key] ||= 2, 1);
assert.equal(key, 1);
key = 0;
assert.equal(obj[++key] &&= 0, 0);
assert.equal(key, 1);
key = 0;
assert.equal(obj[++key] &&= 3, 0);
assert.equal(key, 1);
key = 0;
assert.equal(deep.obj[++key] ||= 1, 1);
assert.equal(gets, 5);
assert.equal(key, 1);
key = 0;
assert.equal(deep.obj[++key] ||= 2, 1);
assert.equal(gets, 6);
assert.equal(key, 1);
key = 0;
assert.equal(deep.obj[++key] &&= 0, 0);
assert.equal(gets, 7);
assert.equal(key, 1);
key = 0;
assert.equal(deep.obj[++key] &&= 3, 0);
assert.equal(gets, 8);
assert.equal(key, 1);

View File

@@ -38,3 +38,35 @@ assert.equal(deep.obj.x &&= 0, 0);
assert.equal(gets, 3);
assert.equal(deep.obj.x &&= 3, 0);
assert.equal(gets, 4);
var key = 0;
assert.equal(obj[++key] ||= 1, 1);
assert.equal(key, 1);
key = 0;
assert.equal(obj[++key] ||= 2, 1);
assert.equal(key, 1);
key = 0;
assert.equal(obj[++key] &&= 0, 0);
assert.equal(key, 1);
key = 0;
assert.equal(obj[++key] &&= 3, 0);
assert.equal(key, 1);
key = 0;
assert.equal(deep.obj[++key] ||= 1, 1);
assert.equal(gets, 5);
assert.equal(key, 1);
key = 0;
assert.equal(deep.obj[++key] ||= 2, 1);
assert.equal(gets, 6);
assert.equal(key, 1);
key = 0;
assert.equal(deep.obj[++key] &&= 0, 0);
assert.equal(gets, 7);
assert.equal(key, 1);
key = 0;
assert.equal(deep.obj[++key] &&= 3, 0);
assert.equal(gets, 8);
assert.equal(key, 1);

View File

@@ -1,4 +1,4 @@
var _deep$obj, _deep$obj2, _deep$obj3, _deep$obj4;
var _deep$obj, _deep$obj2, _deep$obj3, _deep$obj4, _ref, _ref2, _ref3, _ref4, _deep$obj5, _ref5, _deep$obj6, _ref6, _deep$obj7, _ref7, _deep$obj8, _ref8;
var x = 0;
var sets = 0;
@@ -37,3 +37,31 @@ assert.equal((_deep$obj3 = deep.obj).x && (_deep$obj3.x = 0), 0);
assert.equal(gets, 3);
assert.equal((_deep$obj4 = deep.obj).x && (_deep$obj4.x = 3), 0);
assert.equal(gets, 4);
var key = 0;
assert.equal(obj[_ref = ++key] || (obj[_ref] = 1), 1);
assert.equal(key, 1);
key = 0;
assert.equal(obj[_ref2 = ++key] || (obj[_ref2] = 2), 1);
assert.equal(key, 1);
key = 0;
assert.equal(obj[_ref3 = ++key] && (obj[_ref3] = 0), 0);
assert.equal(key, 1);
key = 0;
assert.equal(obj[_ref4 = ++key] && (obj[_ref4] = 3), 0);
assert.equal(key, 1);
key = 0;
assert.equal((_deep$obj5 = deep.obj)[_ref5 = ++key] || (_deep$obj5[_ref5] = 1), 1);
assert.equal(gets, 5);
assert.equal(key, 1);
key = 0;
assert.equal((_deep$obj6 = deep.obj)[_ref6 = ++key] || (_deep$obj6[_ref6] = 2), 1);
assert.equal(gets, 6);
assert.equal(key, 1);
key = 0;
assert.equal((_deep$obj7 = deep.obj)[_ref7 = ++key] && (_deep$obj7[_ref7] = 0), 0);
assert.equal(gets, 7);
assert.equal(key, 1);
key = 0;
assert.equal((_deep$obj8 = deep.obj)[_ref8 = ++key] && (_deep$obj8[_ref8] = 3), 0);
assert.equal(gets, 8);
assert.equal(key, 1);