Add loose mode for nullish coalescing operator (#6531)
* Add loose mode for nullish-coalescing * Remove unneeded SequenceExpression
This commit is contained in:
committed by
Mateusz Burzyński
parent
9e0f5235b1
commit
cd4f0ae393
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
),
|
||||
);
|
||||
},
|
||||
},
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
@@ -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) != null ? _opts$foo : "default";
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"plugins": [["transform-nullish-coalescing-operator", {"loose":true}]]
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user