Implement transform for nullish-coalescing operator (#6483)
* Implement transform for nullish-coalescing operator * Update example output * Switch from BinaryExpression to LogicalExpression * Address review comments - Use generateUidIdentifierBasedOnNode - Inline "??" - Clone ref node - Move "??" to LogicalExpression in babel-types * Fix reference to @babel/helper-plugin-test-runner * Fix reference to @babel/plugin-syntax-nullish-coalescing-operator * Don't use parent scope * Remove .vscode from .gitignore, change 'lib/index.js' to 'lib' * Ensure `document.all ?? 0 === document.all` * Fix note and copy to an inline comment
This commit is contained in:
parent
5c47929983
commit
99be60b53d
@ -0,0 +1,3 @@
|
||||
src
|
||||
test
|
||||
*.log
|
||||
@ -0,0 +1,35 @@
|
||||
# @babel/plugin-syntax-nullish-coalescing-operator
|
||||
|
||||
> Allow parsing of the nullish-coalescing operator.
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
npm install --save-dev @babel/plugin-syntax-nullish-coalescing-operator
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Via `.babelrc` (Recommended)
|
||||
|
||||
**.babelrc**
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": ["syntax-nullish-coalescing-operator"]
|
||||
}
|
||||
```
|
||||
|
||||
### Via CLI
|
||||
|
||||
```sh
|
||||
babel --plugins syntax-nullish-coalescing-operator script.js
|
||||
```
|
||||
|
||||
### Via Node API
|
||||
|
||||
```javascript
|
||||
require("babel-core").transform("code", {
|
||||
plugins: ["syntax-nullish-coalescing-operator"]
|
||||
});
|
||||
```
|
||||
@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "@babel/plugin-syntax-nullish-coalescing-operator",
|
||||
"version": "7.0.0-beta.3",
|
||||
"description": "Allow parsing of the nullish-coalescing operator",
|
||||
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-syntax-nullish-coalescing-operator",
|
||||
"license": "MIT",
|
||||
"main": "lib",
|
||||
"keywords": [
|
||||
"babel-plugin"
|
||||
],
|
||||
"dependencies": {},
|
||||
"devDependencies": {}
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
export default function() {
|
||||
return {
|
||||
manipulateOptions(opts, parserOpts) {
|
||||
parserOpts.plugins.push("nullishCoalescingOperator");
|
||||
},
|
||||
};
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
src
|
||||
test
|
||||
*.log
|
||||
@ -0,0 +1,54 @@
|
||||
# @babel/plugin-transform-nullish-coalescing-operator
|
||||
|
||||
> Replace `??` with an inline helper.
|
||||
|
||||
## Example
|
||||
|
||||
**In**
|
||||
|
||||
```javascript
|
||||
var foo = object.foo ?? "default";
|
||||
```
|
||||
|
||||
**Out**
|
||||
|
||||
```javascript
|
||||
var _object$foo;
|
||||
|
||||
var foo = (_object$foo = object.foo, _object$foo !== null && _object$foo !== void 0 ? _object$foo : "default");
|
||||
```
|
||||
|
||||
> **NOTE:** We cannot use `!= null` here because `document.all == null` and
|
||||
> `document.all` has been deemed not "nullish".
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
npm install --save-dev @babel/plugin-transform-nullish-coalescing-operator
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Via `.babelrc` (Recommended)
|
||||
|
||||
**.babelrc**
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": ["transform-nullish-coalescing-operator"]
|
||||
}
|
||||
```
|
||||
|
||||
### Via CLI
|
||||
|
||||
```sh
|
||||
babel --plugins transform-nullish-coalescing-operator script.js
|
||||
```
|
||||
|
||||
### Via Node API
|
||||
|
||||
```javascript
|
||||
require("babel-core").transform("code", {
|
||||
plugins: ["transform-nullish-coalescing-operator"]
|
||||
});
|
||||
```
|
||||
@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "@babel/plugin-transform-nullish-coalescing-operator",
|
||||
"version": "7.0.0-beta.3",
|
||||
"description": "Remove nullish coalescing operator",
|
||||
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-nullish-coalescing-opearator",
|
||||
"license": "MIT",
|
||||
"main": "lib",
|
||||
"keywords": [
|
||||
"babel-plugin"
|
||||
],
|
||||
"dependencies": {
|
||||
"@babel/plugin-syntax-nullish-coalescing-operator": "7.0.0-beta.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/helper-plugin-test-runner": "7.0.0-beta.3"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
import syntaxNullishCoalescingOperator from "@babel/plugin-syntax-nullish-coalescing-operator";
|
||||
|
||||
export default function({ types: t }) {
|
||||
return {
|
||||
inherits: syntaxNullishCoalescingOperator,
|
||||
|
||||
visitor: {
|
||||
LogicalExpression(path) {
|
||||
const { node, scope } = path;
|
||||
if (node.operator !== "??") {
|
||||
return;
|
||||
}
|
||||
|
||||
const ref = scope.generateUidIdentifierBasedOnNode(node.left);
|
||||
scope.push({ id: ref });
|
||||
|
||||
path.replaceWith(
|
||||
t.sequenceExpression([
|
||||
t.assignmentExpression("=", ref, node.left),
|
||||
t.conditionalExpression(
|
||||
// We cannot use `!= null` here because `document.all == null`
|
||||
// and `document.all` has been deemed not "nullish".
|
||||
t.logicalExpression(
|
||||
"&&",
|
||||
t.binaryExpression("!==", t.clone(ref), t.nullLiteral()),
|
||||
t.binaryExpression(
|
||||
"!==",
|
||||
t.clone(ref),
|
||||
scope.buildUndefinedNode(),
|
||||
),
|
||||
),
|
||||
t.clone(ref),
|
||||
node.right,
|
||||
),
|
||||
]),
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
assert.equal(null ?? undefined, undefined);
|
||||
assert.equal(undefined ?? null, null);
|
||||
assert.equal(false ?? true, false);
|
||||
assert.equal(0 ?? 1, 0);
|
||||
assert.equal("" ?? "foo", "");
|
||||
|
||||
var obj = { exists: true };
|
||||
assert.equal(obj.exists ?? false, true);
|
||||
assert.equal(obj.doesNotExist ?? "foo", "foo");
|
||||
|
||||
var counter = 0;
|
||||
function sideEffect() { return counter++; }
|
||||
assert.equal(sideEffect() ?? -1, 0);
|
||||
|
||||
var counter2 = 0;
|
||||
var obj2 = {
|
||||
get foo() { return counter2++; }
|
||||
};
|
||||
assert.equal(obj2.foo ?? -1, 0);
|
||||
@ -0,0 +1,3 @@
|
||||
{
|
||||
"plugins": ["transform-nullish-coalescing-operator"]
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
function foo(foo, bar = foo ?? "bar") {}
|
||||
@ -0,0 +1,3 @@
|
||||
function foo(foo, bar = (_foo = foo, _foo !== null && _foo !== void 0 ? _foo : "bar")) {
|
||||
var _foo;
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
{
|
||||
"plugins": ["transform-nullish-coalescing-operator"]
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
function foo(opts) {
|
||||
var foo = opts.foo ?? "default";
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
function foo(opts) {
|
||||
var _opts$foo;
|
||||
|
||||
var foo = (_opts$foo = opts.foo, _opts$foo !== null && _opts$foo !== void 0 ? _opts$foo : "default");
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
{
|
||||
"plugins": ["transform-nullish-coalescing-operator"]
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
import runner from "@babel/helper-plugin-test-runner";
|
||||
|
||||
runner(__dirname);
|
||||
@ -12,6 +12,7 @@
|
||||
"@babel/plugin-transform-export-default": "7.0.0-beta.3",
|
||||
"@babel/plugin-transform-optional-chaining": "7.0.0-beta.3",
|
||||
"@babel/plugin-transform-pipeline-operator": "7.0.0-beta.3",
|
||||
"@babel/plugin-transform-nullish-coalescing-operator": "7.0.0-beta.3",
|
||||
"@babel/preset-stage-2": "7.0.0-beta.3"
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import transformDecorators from "@babel/plugin-transform-decorators";
|
||||
import transformExportDefault from "@babel/plugin-transform-export-default";
|
||||
import transformOptionalChaining from "@babel/plugin-transform-optional-chaining";
|
||||
import transformPipelineOperator from "@babel/plugin-transform-pipeline-operator";
|
||||
import transformNullishCoalescingOperator from "@babel/plugin-transform-nullish-coalescing-operator";
|
||||
|
||||
export default function() {
|
||||
return {
|
||||
@ -13,6 +14,7 @@ export default function() {
|
||||
transformExportDefault,
|
||||
transformOptionalChaining,
|
||||
transformPipelineOperator,
|
||||
transformNullishCoalescingOperator,
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@ export const COMMENT_KEYS = [
|
||||
"innerComments",
|
||||
];
|
||||
|
||||
export const LOGICAL_OPERATORS = ["||", "&&"];
|
||||
export const LOGICAL_OPERATORS = ["||", "&&", "??"];
|
||||
export const UPDATE_OPERATORS = ["++", "--"];
|
||||
|
||||
export const BOOLEAN_NUMBER_BINARY_OPERATORS = [">", "<", ">=", "<="];
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user