From 7e90d56024e0f6a3387647fcd1dafbeedc2348c2 Mon Sep 17 00:00:00 2001 From: Justin Ridgewell Date: Sun, 18 Feb 2018 13:56:29 -0500 Subject: [PATCH] Proposal: Logical Assignment Operators (#7385) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Proposal: Logical Assignment Operators https://github.com/jridgewell/proposal-logical-assignment I'm bringing it [back](https://github.com/babel/babel/pull/516). 😉 * Use expectPlugin * Add to stage 0 preset * Add logicalAssignment missing plugin log stuff --- .../util/missing-plugin-helper.js | 10 + .../.npmignore | 3 + .../README.md | 63 ++++++ .../package.json | 21 ++ .../src/index.js | 42 ++++ .../general-semantics/exec.js | 40 ++++ .../general-semantics/input.js | 40 ++++ .../general-semantics/options.json | 3 + .../general-semantics/output.js | 39 ++++ .../test/index.js | 3 + .../.npmignore | 3 + .../README.md | 35 ++++ .../package.json | 17 ++ .../src/index.js | 7 + packages/babel-preset-stage-0/package.json | 1 + packages/babel-preset-stage-0/src/index.js | 3 +- packages/babylon/src/tokenizer/index.js | 11 +- .../and-and-equals-no-plugin/input.js | 2 + .../and-and-equals-no-plugin/options.json | 4 + .../and-and-equals/input.js | 2 + .../and-and-equals/options.json | 3 + .../and-and-equals/output.json | 197 ++++++++++++++++++ .../mallet-no-plugin/input.js | 1 + .../mallet-no-plugin/options.json | 4 + .../mallet/input.js | 2 + .../mallet/options.json | 3 + .../mallet/output.json | 197 ++++++++++++++++++ 27 files changed, 753 insertions(+), 3 deletions(-) create mode 100644 packages/babel-plugin-proposal-logical-assignment-operators/.npmignore create mode 100644 packages/babel-plugin-proposal-logical-assignment-operators/README.md create mode 100644 packages/babel-plugin-proposal-logical-assignment-operators/package.json create mode 100644 packages/babel-plugin-proposal-logical-assignment-operators/src/index.js create mode 100644 packages/babel-plugin-proposal-logical-assignment-operators/test/fixtures/logical-assignment/general-semantics/exec.js create mode 100644 packages/babel-plugin-proposal-logical-assignment-operators/test/fixtures/logical-assignment/general-semantics/input.js create mode 100644 packages/babel-plugin-proposal-logical-assignment-operators/test/fixtures/logical-assignment/general-semantics/options.json create mode 100644 packages/babel-plugin-proposal-logical-assignment-operators/test/fixtures/logical-assignment/general-semantics/output.js create mode 100644 packages/babel-plugin-proposal-logical-assignment-operators/test/index.js create mode 100644 packages/babel-plugin-syntax-logical-assignment-operators/.npmignore create mode 100644 packages/babel-plugin-syntax-logical-assignment-operators/README.md create mode 100644 packages/babel-plugin-syntax-logical-assignment-operators/package.json create mode 100644 packages/babel-plugin-syntax-logical-assignment-operators/src/index.js create mode 100644 packages/babylon/test/fixtures/experimental/logical-assignment-operator/and-and-equals-no-plugin/input.js create mode 100644 packages/babylon/test/fixtures/experimental/logical-assignment-operator/and-and-equals-no-plugin/options.json create mode 100644 packages/babylon/test/fixtures/experimental/logical-assignment-operator/and-and-equals/input.js create mode 100644 packages/babylon/test/fixtures/experimental/logical-assignment-operator/and-and-equals/options.json create mode 100644 packages/babylon/test/fixtures/experimental/logical-assignment-operator/and-and-equals/output.json create mode 100644 packages/babylon/test/fixtures/experimental/logical-assignment-operator/mallet-no-plugin/input.js create mode 100644 packages/babylon/test/fixtures/experimental/logical-assignment-operator/mallet-no-plugin/options.json create mode 100644 packages/babylon/test/fixtures/experimental/logical-assignment-operator/mallet/input.js create mode 100644 packages/babylon/test/fixtures/experimental/logical-assignment-operator/mallet/options.json create mode 100644 packages/babylon/test/fixtures/experimental/logical-assignment-operator/mallet/output.json diff --git a/packages/babel-core/src/transformation/util/missing-plugin-helper.js b/packages/babel-core/src/transformation/util/missing-plugin-helper.js index 0d029e71eb..c595e178a1 100644 --- a/packages/babel-core/src/transformation/util/missing-plugin-helper.js +++ b/packages/babel-core/src/transformation/util/missing-plugin-helper.js @@ -113,6 +113,16 @@ const pluginNameMap = { url: "https://git.io/vb4yd", }, }, + logicalAssignment: { + syntax: { + name: "@babel/plugin-syntax-logical-assignment-operators", + url: "https://git.io/vAlBp", + }, + transform: { + name: "@babel/plugin-proposal-logical-assignment-operators", + url: "https://git.io/vAlRe", + }, + }, nullishCoalescingOperator: { syntax: { name: "@babel/plugin-syntax-nullish-coalescing-operator", diff --git a/packages/babel-plugin-proposal-logical-assignment-operators/.npmignore b/packages/babel-plugin-proposal-logical-assignment-operators/.npmignore new file mode 100644 index 0000000000..f980694583 --- /dev/null +++ b/packages/babel-plugin-proposal-logical-assignment-operators/.npmignore @@ -0,0 +1,3 @@ +src +test +*.log diff --git a/packages/babel-plugin-proposal-logical-assignment-operators/README.md b/packages/babel-plugin-proposal-logical-assignment-operators/README.md new file mode 100644 index 0000000000..26fbaddfb7 --- /dev/null +++ b/packages/babel-plugin-proposal-logical-assignment-operators/README.md @@ -0,0 +1,63 @@ +# @babel/plugin-proposal-logical-assignment-operator + +> Transforms logical assignment operators into short-circuited assignments + +## Example + +**In** + +```javascript +a ||= b; +obj.a.b ||= c; + +a &&= b; +obj.a.b &&= c; +``` + +**Out** + +```javascript +var _obj$a, _obj$a2; + +a || (a = b); +(_obj$a = obj.a).b || (_obj$a.b = c); + +a && (a = b); +(_obj$a2 = obj.a).b && (_obj$a2.b = c); +``` + +## Installation + +```sh +npm install --save-dev @babel/plugin-proposal-logical-assignment-operators +``` + +## Usage + +### Via `.babelrc` (Recommended) + +**.babelrc** + +```json +{ + "plugins": ["@babel/plugin-proposal-logical-assignment-operators"] +} +``` + +### Via CLI + +```sh +babel --plugins @babel/plugin-proposal-logical-assignment-operators script.js +``` + +### Via Node API + +```javascript +require("@babel/core").transform("code", { + plugins: ["@babel/plugin-proposal-logical-assignment-operators"] +}); +``` + +## References + +* [Proposal: Logical Assignment Operators](https://github.com/jridgewell/proposal-logical-assignment-operators) diff --git a/packages/babel-plugin-proposal-logical-assignment-operators/package.json b/packages/babel-plugin-proposal-logical-assignment-operators/package.json new file mode 100644 index 0000000000..94f116ae96 --- /dev/null +++ b/packages/babel-plugin-proposal-logical-assignment-operators/package.json @@ -0,0 +1,21 @@ +{ + "name": "@babel/plugin-proposal-logical-assignment-operators", + "version": "7.0.0-beta.40", + "description": "Transforms logical assignment operators into short-circuited assignments", + "repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-proposal-logical-assignment-operators", + "license": "MIT", + "main": "lib", + "keywords": [ + "babel-plugin" + ], + "dependencies": { + "@babel/plugin-syntax-logical-assignment-operators": "7.0.0-beta.40" + }, + "peerDependencies": { + "@babel/core": "7.0.0-beta.40" + }, + "devDependencies": { + "@babel/core": "7.0.0-beta.40", + "@babel/helper-plugin-test-runner": "7.0.0-beta.40" + } +} diff --git a/packages/babel-plugin-proposal-logical-assignment-operators/src/index.js b/packages/babel-plugin-proposal-logical-assignment-operators/src/index.js new file mode 100644 index 0000000000..bba8a28c37 --- /dev/null +++ b/packages/babel-plugin-proposal-logical-assignment-operators/src/index.js @@ -0,0 +1,42 @@ +import syntaxLogicalAssignmentOperators from "@babel/plugin-syntax-logical-assignment-operators"; +import { types as t } from "@babel/core"; + +export default function() { + return { + inherits: syntaxLogicalAssignmentOperators, + + visitor: { + AssignmentExpression(path) { + const { node, scope } = path; + const { operator, left, right } = node; + if (operator !== "||=" && operator !== "&&=") { + return; + } + + let ref; + if (t.isMemberExpression(left)) { + const { object } = left; + const memo = scope.maybeGenerateMemoised(object); + if (memo) { + path + .get("left.object") + .replaceWith( + t.assignmentExpression("=", t.cloneNode(memo), object), + ); + + ref = t.cloneNode(left); + ref.object = t.cloneNode(memo); + } + } + + path.replaceWith( + t.logicalExpression( + operator.slice(0, -1), + left, + t.assignmentExpression("=", ref || t.cloneNode(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 new file mode 100644 index 0000000000..57865464cd --- /dev/null +++ b/packages/babel-plugin-proposal-logical-assignment-operators/test/fixtures/logical-assignment/general-semantics/exec.js @@ -0,0 +1,40 @@ +var x = 0; +var sets = 0; +var obj = { + get x() { + return x; + }, + + set x(value) { + sets++; + x = value; + }, +}; + +assert.equal(obj.x ||= 1, 1); +assert.equal(sets, 1); +assert.equal(obj.x ||= 2, 1); +assert.equal(sets, 1); + +assert.equal(obj.x &&= 0, 0); +assert.equal(sets, 2); +assert.equal(obj.x &&= 3, 0); +assert.equal(sets, 2); + +var gets = 0; +var deep = { + get obj() { + gets++; + return obj; + }, +}; + +assert.equal(deep.obj.x ||= 1, 1); +assert.equal(gets, 1); +assert.equal(deep.obj.x ||= 2, 1); +assert.equal(gets, 2); + +assert.equal(deep.obj.x &&= 0, 0); +assert.equal(gets, 3); +assert.equal(deep.obj.x &&= 3, 0); +assert.equal(gets, 4); 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 new file mode 100644 index 0000000000..57865464cd --- /dev/null +++ b/packages/babel-plugin-proposal-logical-assignment-operators/test/fixtures/logical-assignment/general-semantics/input.js @@ -0,0 +1,40 @@ +var x = 0; +var sets = 0; +var obj = { + get x() { + return x; + }, + + set x(value) { + sets++; + x = value; + }, +}; + +assert.equal(obj.x ||= 1, 1); +assert.equal(sets, 1); +assert.equal(obj.x ||= 2, 1); +assert.equal(sets, 1); + +assert.equal(obj.x &&= 0, 0); +assert.equal(sets, 2); +assert.equal(obj.x &&= 3, 0); +assert.equal(sets, 2); + +var gets = 0; +var deep = { + get obj() { + gets++; + return obj; + }, +}; + +assert.equal(deep.obj.x ||= 1, 1); +assert.equal(gets, 1); +assert.equal(deep.obj.x ||= 2, 1); +assert.equal(gets, 2); + +assert.equal(deep.obj.x &&= 0, 0); +assert.equal(gets, 3); +assert.equal(deep.obj.x &&= 3, 0); +assert.equal(gets, 4); diff --git a/packages/babel-plugin-proposal-logical-assignment-operators/test/fixtures/logical-assignment/general-semantics/options.json b/packages/babel-plugin-proposal-logical-assignment-operators/test/fixtures/logical-assignment/general-semantics/options.json new file mode 100644 index 0000000000..259c77d8e4 --- /dev/null +++ b/packages/babel-plugin-proposal-logical-assignment-operators/test/fixtures/logical-assignment/general-semantics/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["proposal-logical-assignment-operators"] +} 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 new file mode 100644 index 0000000000..fb5c9b38b4 --- /dev/null +++ b/packages/babel-plugin-proposal-logical-assignment-operators/test/fixtures/logical-assignment/general-semantics/output.js @@ -0,0 +1,39 @@ +var _deep$obj, _deep$obj2, _deep$obj3, _deep$obj4; + +var x = 0; +var sets = 0; +var obj = { + get x() { + return x; + }, + + set x(value) { + sets++; + x = value; + } + +}; +assert.equal(obj.x || (obj.x = 1), 1); +assert.equal(sets, 1); +assert.equal(obj.x || (obj.x = 2), 1); +assert.equal(sets, 1); +assert.equal(obj.x && (obj.x = 0), 0); +assert.equal(sets, 2); +assert.equal(obj.x && (obj.x = 3), 0); +assert.equal(sets, 2); +var gets = 0; +var deep = { + get obj() { + gets++; + return obj; + } + +}; +assert.equal((_deep$obj = deep.obj).x || (_deep$obj.x = 1), 1); +assert.equal(gets, 1); +assert.equal((_deep$obj2 = deep.obj).x || (_deep$obj2.x = 2), 1); +assert.equal(gets, 2); +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); diff --git a/packages/babel-plugin-proposal-logical-assignment-operators/test/index.js b/packages/babel-plugin-proposal-logical-assignment-operators/test/index.js new file mode 100644 index 0000000000..1b534b8fc6 --- /dev/null +++ b/packages/babel-plugin-proposal-logical-assignment-operators/test/index.js @@ -0,0 +1,3 @@ +import runner from "@babel/helper-plugin-test-runner"; + +runner(__dirname); diff --git a/packages/babel-plugin-syntax-logical-assignment-operators/.npmignore b/packages/babel-plugin-syntax-logical-assignment-operators/.npmignore new file mode 100644 index 0000000000..f980694583 --- /dev/null +++ b/packages/babel-plugin-syntax-logical-assignment-operators/.npmignore @@ -0,0 +1,3 @@ +src +test +*.log diff --git a/packages/babel-plugin-syntax-logical-assignment-operators/README.md b/packages/babel-plugin-syntax-logical-assignment-operators/README.md new file mode 100644 index 0000000000..07c5371cc3 --- /dev/null +++ b/packages/babel-plugin-syntax-logical-assignment-operators/README.md @@ -0,0 +1,35 @@ +# @babel/plugin-syntax-logical-assignment-operators + +> Allow parsing of the logical assignment operators. + +## Installation + +```sh +npm install --save-dev @babel/plugin-syntax-logical-assignment-operators +``` + +## Usage + +### Via `.babelrc` (Recommended) + +**.babelrc** + +```json +{ + "plugins": ["@babel/plugin-syntax-logical-assignment-operators"] +} +``` + +### Via CLI + +```sh +babel --plugins @babel/plugin-syntax-logical-assignment-operators script.js +``` + +### Via Node API + +```javascript +require("@babel/core").transform("code", { + plugins: ["@babel/plugin-syntax-logical-assignment-operators"] +}); +``` diff --git a/packages/babel-plugin-syntax-logical-assignment-operators/package.json b/packages/babel-plugin-syntax-logical-assignment-operators/package.json new file mode 100644 index 0000000000..a638697e4c --- /dev/null +++ b/packages/babel-plugin-syntax-logical-assignment-operators/package.json @@ -0,0 +1,17 @@ +{ + "name": "@babel/plugin-syntax-logical-assignment-operators", + "version": "7.0.0-beta.40", + "description": "Allow parsing of the logical assignment operators", + "repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-syntax-logical-assignment-operators", + "license": "MIT", + "main": "lib", + "keywords": [ + "babel-plugin" + ], + "peerDependencies": { + "@babel/core": "7.0.0-beta.40" + }, + "devDependencies": { + "@babel/core": "7.0.0-beta.40" + } +} diff --git a/packages/babel-plugin-syntax-logical-assignment-operators/src/index.js b/packages/babel-plugin-syntax-logical-assignment-operators/src/index.js new file mode 100644 index 0000000000..20f6ab064a --- /dev/null +++ b/packages/babel-plugin-syntax-logical-assignment-operators/src/index.js @@ -0,0 +1,7 @@ +export default function() { + return { + manipulateOptions(opts, parserOpts) { + parserOpts.plugins.push("logicalAssignment"); + }, + }; +} diff --git a/packages/babel-preset-stage-0/package.json b/packages/babel-preset-stage-0/package.json index c6f44f5fb4..97ec9b160a 100644 --- a/packages/babel-preset-stage-0/package.json +++ b/packages/babel-preset-stage-0/package.json @@ -9,6 +9,7 @@ "main": "lib/index.js", "dependencies": { "@babel/plugin-proposal-function-bind": "7.0.0-beta.40", + "@babel/plugin-proposal-logical-assignment-operators": "7.0.0-beta.40", "@babel/preset-stage-1": "7.0.0-beta.40" }, "peerDependencies": { diff --git a/packages/babel-preset-stage-0/src/index.js b/packages/babel-preset-stage-0/src/index.js index 2d97b1f23b..6f886fbce5 100644 --- a/packages/babel-preset-stage-0/src/index.js +++ b/packages/babel-preset-stage-0/src/index.js @@ -1,6 +1,7 @@ import presetStage1 from "@babel/preset-stage-1"; import transformFunctionBind from "@babel/plugin-proposal-function-bind"; +import transformLogicalAssignmentOperators from "@babel/plugin-proposal-logical-assignment-operators"; export default function(context, opts = {}) { let loose = false; @@ -22,6 +23,6 @@ export default function(context, opts = {}) { return { presets: [[presetStage1, { loose, useBuiltIns }]], - plugins: [transformFunctionBind], + plugins: [transformFunctionBind, transformLogicalAssignmentOperators], }; } diff --git a/packages/babylon/src/tokenizer/index.js b/packages/babylon/src/tokenizer/index.js index 3fce132907..45d551b755 100644 --- a/packages/babylon/src/tokenizer/index.js +++ b/packages/babylon/src/tokenizer/index.js @@ -464,9 +464,16 @@ export default class Tokenizer extends LocationParser { const next = this.input.charCodeAt(this.state.pos + 1); if (next === code) { + const assign = + this.input.charCodeAt(this.state.pos + 2) === charCodes.equalsTo; + if (assign) { + this.expectPlugin("logicalAssignment"); + } this.finishOp( - code === charCodes.verticalBar ? tt.logicalOR : tt.logicalAND, - 2, + assign + ? tt.assign + : code === charCodes.verticalBar ? tt.logicalOR : tt.logicalAND, + assign ? 3 : 2, ); return; } diff --git a/packages/babylon/test/fixtures/experimental/logical-assignment-operator/and-and-equals-no-plugin/input.js b/packages/babylon/test/fixtures/experimental/logical-assignment-operator/and-and-equals-no-plugin/input.js new file mode 100644 index 0000000000..740f1fa926 --- /dev/null +++ b/packages/babylon/test/fixtures/experimental/logical-assignment-operator/and-and-equals-no-plugin/input.js @@ -0,0 +1,2 @@ +a &&= b; +obj.a &&= b; diff --git a/packages/babylon/test/fixtures/experimental/logical-assignment-operator/and-and-equals-no-plugin/options.json b/packages/babylon/test/fixtures/experimental/logical-assignment-operator/and-and-equals-no-plugin/options.json new file mode 100644 index 0000000000..5b674fdee4 --- /dev/null +++ b/packages/babylon/test/fixtures/experimental/logical-assignment-operator/and-and-equals-no-plugin/options.json @@ -0,0 +1,4 @@ +{ + "plugins": [], + "throws": "This experimental syntax requires enabling the parser plugin: 'logicalAssignment' (1:2)" +} diff --git a/packages/babylon/test/fixtures/experimental/logical-assignment-operator/and-and-equals/input.js b/packages/babylon/test/fixtures/experimental/logical-assignment-operator/and-and-equals/input.js new file mode 100644 index 0000000000..740f1fa926 --- /dev/null +++ b/packages/babylon/test/fixtures/experimental/logical-assignment-operator/and-and-equals/input.js @@ -0,0 +1,2 @@ +a &&= b; +obj.a &&= b; diff --git a/packages/babylon/test/fixtures/experimental/logical-assignment-operator/and-and-equals/options.json b/packages/babylon/test/fixtures/experimental/logical-assignment-operator/and-and-equals/options.json new file mode 100644 index 0000000000..5041dbb19f --- /dev/null +++ b/packages/babylon/test/fixtures/experimental/logical-assignment-operator/and-and-equals/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["logicalAssignment"] +} diff --git a/packages/babylon/test/fixtures/experimental/logical-assignment-operator/and-and-equals/output.json b/packages/babylon/test/fixtures/experimental/logical-assignment-operator/and-and-equals/output.json new file mode 100644 index 0000000000..a8cf00f410 --- /dev/null +++ b/packages/babylon/test/fixtures/experimental/logical-assignment-operator/and-and-equals/output.json @@ -0,0 +1,197 @@ +{ + "type": "File", + "start": 0, + "end": 21, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 2, + "column": 12 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 21, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 2, + "column": 12 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 8, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 8 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 0, + "end": 7, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 7 + } + }, + "operator": "&&=", + "left": { + "type": "Identifier", + "start": 0, + "end": 1, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 1 + }, + "identifierName": "a" + }, + "name": "a" + }, + "right": { + "type": "Identifier", + "start": 6, + "end": 7, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 7 + }, + "identifierName": "b" + }, + "name": "b" + } + } + }, + { + "type": "ExpressionStatement", + "start": 9, + "end": 21, + "loc": { + "start": { + "line": 2, + "column": 0 + }, + "end": { + "line": 2, + "column": 12 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 9, + "end": 20, + "loc": { + "start": { + "line": 2, + "column": 0 + }, + "end": { + "line": 2, + "column": 11 + } + }, + "operator": "&&=", + "left": { + "type": "MemberExpression", + "start": 9, + "end": 14, + "loc": { + "start": { + "line": 2, + "column": 0 + }, + "end": { + "line": 2, + "column": 5 + } + }, + "object": { + "type": "Identifier", + "start": 9, + "end": 12, + "loc": { + "start": { + "line": 2, + "column": 0 + }, + "end": { + "line": 2, + "column": 3 + }, + "identifierName": "obj" + }, + "name": "obj" + }, + "property": { + "type": "Identifier", + "start": 13, + "end": 14, + "loc": { + "start": { + "line": 2, + "column": 4 + }, + "end": { + "line": 2, + "column": 5 + }, + "identifierName": "a" + }, + "name": "a" + }, + "computed": false + }, + "right": { + "type": "Identifier", + "start": 19, + "end": 20, + "loc": { + "start": { + "line": 2, + "column": 10 + }, + "end": { + "line": 2, + "column": 11 + }, + "identifierName": "b" + }, + "name": "b" + } + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babylon/test/fixtures/experimental/logical-assignment-operator/mallet-no-plugin/input.js b/packages/babylon/test/fixtures/experimental/logical-assignment-operator/mallet-no-plugin/input.js new file mode 100644 index 0000000000..53c87792bb --- /dev/null +++ b/packages/babylon/test/fixtures/experimental/logical-assignment-operator/mallet-no-plugin/input.js @@ -0,0 +1 @@ +a ||= b; diff --git a/packages/babylon/test/fixtures/experimental/logical-assignment-operator/mallet-no-plugin/options.json b/packages/babylon/test/fixtures/experimental/logical-assignment-operator/mallet-no-plugin/options.json new file mode 100644 index 0000000000..5b674fdee4 --- /dev/null +++ b/packages/babylon/test/fixtures/experimental/logical-assignment-operator/mallet-no-plugin/options.json @@ -0,0 +1,4 @@ +{ + "plugins": [], + "throws": "This experimental syntax requires enabling the parser plugin: 'logicalAssignment' (1:2)" +} diff --git a/packages/babylon/test/fixtures/experimental/logical-assignment-operator/mallet/input.js b/packages/babylon/test/fixtures/experimental/logical-assignment-operator/mallet/input.js new file mode 100644 index 0000000000..cb4961f49b --- /dev/null +++ b/packages/babylon/test/fixtures/experimental/logical-assignment-operator/mallet/input.js @@ -0,0 +1,2 @@ +a ||= b; +obj.a ||= b; diff --git a/packages/babylon/test/fixtures/experimental/logical-assignment-operator/mallet/options.json b/packages/babylon/test/fixtures/experimental/logical-assignment-operator/mallet/options.json new file mode 100644 index 0000000000..5041dbb19f --- /dev/null +++ b/packages/babylon/test/fixtures/experimental/logical-assignment-operator/mallet/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["logicalAssignment"] +} diff --git a/packages/babylon/test/fixtures/experimental/logical-assignment-operator/mallet/output.json b/packages/babylon/test/fixtures/experimental/logical-assignment-operator/mallet/output.json new file mode 100644 index 0000000000..857dd9538e --- /dev/null +++ b/packages/babylon/test/fixtures/experimental/logical-assignment-operator/mallet/output.json @@ -0,0 +1,197 @@ +{ + "type": "File", + "start": 0, + "end": 21, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 2, + "column": 12 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 21, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 2, + "column": 12 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 8, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 8 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 0, + "end": 7, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 7 + } + }, + "operator": "||=", + "left": { + "type": "Identifier", + "start": 0, + "end": 1, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 1 + }, + "identifierName": "a" + }, + "name": "a" + }, + "right": { + "type": "Identifier", + "start": 6, + "end": 7, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 7 + }, + "identifierName": "b" + }, + "name": "b" + } + } + }, + { + "type": "ExpressionStatement", + "start": 9, + "end": 21, + "loc": { + "start": { + "line": 2, + "column": 0 + }, + "end": { + "line": 2, + "column": 12 + } + }, + "expression": { + "type": "AssignmentExpression", + "start": 9, + "end": 20, + "loc": { + "start": { + "line": 2, + "column": 0 + }, + "end": { + "line": 2, + "column": 11 + } + }, + "operator": "||=", + "left": { + "type": "MemberExpression", + "start": 9, + "end": 14, + "loc": { + "start": { + "line": 2, + "column": 0 + }, + "end": { + "line": 2, + "column": 5 + } + }, + "object": { + "type": "Identifier", + "start": 9, + "end": 12, + "loc": { + "start": { + "line": 2, + "column": 0 + }, + "end": { + "line": 2, + "column": 3 + }, + "identifierName": "obj" + }, + "name": "obj" + }, + "property": { + "type": "Identifier", + "start": 13, + "end": 14, + "loc": { + "start": { + "line": 2, + "column": 4 + }, + "end": { + "line": 2, + "column": 5 + }, + "identifierName": "a" + }, + "name": "a" + }, + "computed": false + }, + "right": { + "type": "Identifier", + "start": 19, + "end": 20, + "loc": { + "start": { + "line": 2, + "column": 10 + }, + "end": { + "line": 2, + "column": 11 + }, + "identifierName": "b" + }, + "name": "b" + } + } + } + ], + "directives": [] + } +} \ No newline at end of file