diff --git a/packages/babel-plugin-proposal-logical-assignment-operators/src/index.js b/packages/babel-plugin-proposal-logical-assignment-operators/src/index.js index 8c3c2e15f0..2ecda96b8f 100644 --- a/packages/babel-plugin-proposal-logical-assignment-operators/src/index.js +++ b/packages/babel-plugin-proposal-logical-assignment-operators/src/index.js @@ -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), ), ); }, diff --git a/packages/babel-plugin-proposal-logical-assignment-operators/test/fixtures/logical-assignment/general-semantics/exec.js b/packages/babel-plugin-proposal-logical-assignment-operators/test/fixtures/logical-assignment/general-semantics/exec.js index 57865464cd..0aa88724b5 100644 --- a/packages/babel-plugin-proposal-logical-assignment-operators/test/fixtures/logical-assignment/general-semantics/exec.js +++ b/packages/babel-plugin-proposal-logical-assignment-operators/test/fixtures/logical-assignment/general-semantics/exec.js @@ -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); diff --git a/packages/babel-plugin-proposal-logical-assignment-operators/test/fixtures/logical-assignment/general-semantics/input.js b/packages/babel-plugin-proposal-logical-assignment-operators/test/fixtures/logical-assignment/general-semantics/input.js index 57865464cd..0aa88724b5 100644 --- a/packages/babel-plugin-proposal-logical-assignment-operators/test/fixtures/logical-assignment/general-semantics/input.js +++ b/packages/babel-plugin-proposal-logical-assignment-operators/test/fixtures/logical-assignment/general-semantics/input.js @@ -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); diff --git a/packages/babel-plugin-proposal-logical-assignment-operators/test/fixtures/logical-assignment/general-semantics/output.js b/packages/babel-plugin-proposal-logical-assignment-operators/test/fixtures/logical-assignment/general-semantics/output.js index fb5c9b38b4..520be3c258 100644 --- a/packages/babel-plugin-proposal-logical-assignment-operators/test/fixtures/logical-assignment/general-semantics/output.js +++ b/packages/babel-plugin-proposal-logical-assignment-operators/test/fixtures/logical-assignment/general-semantics/output.js @@ -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);