Logical Assignment: ensure computed key isn't recomputed (#7604)
* Logical Assignment: ensure computed key isn't recomputed * More tests
This commit is contained in:
@@ -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),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user