Add loose mode for nullish coalescing operator (#6531)

* Add loose mode for nullish-coalescing

* Remove unneeded SequenceExpression
This commit is contained in:
Lucas Azzola
2017-10-22 22:25:29 +11:00
committed by Mateusz Burzyński
parent 9e0f5235b1
commit cd4f0ae393
8 changed files with 93 additions and 21 deletions

View File

@@ -15,7 +15,7 @@ var foo = object.foo ?? "default";
```javascript
var _object$foo;
var foo = (_object$foo = object.foo, _object$foo !== null && _object$foo !== void 0 ? _object$foo : "default");
var foo = (_object$foo = object.foo) !== null && _object$foo !== void 0 ? _object$foo : "default";
```
> **NOTE:** We cannot use `!= null` here because `document.all == null` and
@@ -52,3 +52,33 @@ require("@babel/core").transform("code", {
plugins: ["transform-nullish-coalescing-operator"]
});
```
## Options
### `loose`
`boolean`, defaults to `false`.
When `true`, this transform will pretend `document.all` does not exist,
and perform loose equality checks with `null` instead of string equality checks
against both `null` and `undefined`.
#### Example
**In**
```javascript
var foo = object.foo ?? "default";
```
**Out**
```javascript
var _object$foo;
var foo = (_object$foo = object.foo) != null ? _object$foo : "default";
```
## References
* [Proposal: Nullish Coalescing](https://github.com/tc39-transfer/proposal-nullish-coalescing)

View File

@@ -1,6 +1,6 @@
import syntaxNullishCoalescingOperator from "@babel/plugin-syntax-nullish-coalescing-operator";
export default function({ types: t }) {
export default function({ types: t }, { loose = false }) {
return {
inherits: syntaxNullishCoalescingOperator,
@@ -14,25 +14,26 @@ export default function({ types: t }) {
const ref = scope.generateUidIdentifierBasedOnNode(node.left);
scope.push({ id: ref });
const assignment = t.assignmentExpression("=", t.clone(ref), node.left);
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.conditionalExpression(
// We cannot use `!= null` in spec mode because
// `document.all == null` and `document.all` is not "nullish".
loose
? t.binaryExpression("!=", assignment, t.nullLiteral())
: t.logicalExpression(
"&&",
t.binaryExpression("!==", assignment, t.nullLiteral()),
t.binaryExpression(
"!==",
t.clone(ref),
scope.buildUndefinedNode(),
),
),
),
t.clone(ref),
node.right,
),
]),
t.clone(ref),
node.right,
),
);
},
},

View File

@@ -1,3 +1,3 @@
function foo(foo, bar = (_foo = foo, _foo !== null && _foo !== void 0 ? _foo : "bar")) {
function foo(foo, bar = (_foo = foo) !== null && _foo !== void 0 ? _foo : "bar") {
var _foo;
}

View File

@@ -1,5 +1,5 @@
function foo(opts) {
var _opts$foo;
var foo = (_opts$foo = opts.foo, _opts$foo !== null && _opts$foo !== void 0 ? _opts$foo : "default");
var foo = (_opts$foo = opts.foo) !== null && _opts$foo !== void 0 ? _opts$foo : "default";
}

View File

@@ -0,0 +1,3 @@
function foo(opts) {
var foo = opts.foo ?? "default";
}

View File

@@ -0,0 +1,5 @@
function foo(opts) {
var _opts$foo;
var foo = (_opts$foo = opts.foo) != null ? _opts$foo : "default";
}

View File

@@ -0,0 +1,3 @@
{
"plugins": [["transform-nullish-coalescing-operator", {"loose":true}]]
}

View File

@@ -113,6 +113,36 @@ require("@babel/core").transform("code", {
});
```
## Options
### `loose`
`boolean`, defaults to `false`.
When `true`, this transform will pretend `document.all` does not exist,
and perform loose equality checks with `null` instead of string equality checks
against both `null` and `undefined`.
#### Example
In
```javascript
foo?.bar;
```
Out (`loose === true`)
```javascript
foo == null ? void 0 : foo.bar;
```
Out (`loose === false`)
```javascript
foo === null || foo === void 0 ? void 0 : foo.bar;
```
## References
* [Proposal: Optional Chaining](https://github.com/tc39/proposal-optional-chaining)