Disambiguate unary expr in instanceof and in (#15468)
Co-authored-by: fisker Cheung <lionkay@gmail.com>
This commit is contained in:
1 parent
fa8cb85434
commit
b78d7c7d2d
5 files changed
+270
-2
No files matched your search
@@ -0,0 +1,24 @@
|
||||
#### Disambiguate unary expressions on left hand side of instanceof and in (#15468 by @lucacasonato)
|
||||
|
||||
Parentheses are now added around unary expression on the left hand side of
|
||||
`instanceof` and `in` expressions, to disambiguate the unary on the left hand
|
||||
side with a unary applying to the entire binary expression.
|
||||
|
||||
This helps catch a common mistake where a user intends to write `!("x" in y)`
|
||||
but instead writes `!"x" in y`, which is really parsed as the nonsensical
|
||||
`(!"x") in y`.
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```js
|
||||
// Input
|
||||
!"x" in y;
|
||||
!("x" in y);
|
||||
|
||||
// Prettier stable
|
||||
!"x" in y;
|
||||
!("x" in y);
|
||||
|
||||
// Prettier main
|
||||
(!"x") in y;
|
||||
!("x" in y);
|
||||
```
|
||||
@@ -241,6 +241,19 @@ function needsParens(path, options) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
// A user typing `!foo instanceof Bar` probably intended
|
||||
// `!(foo instanceof Bar)`, so format to `(!foo) instance Bar` to what is
|
||||
// really happening
|
||||
case "BinaryExpression":
|
||||
if (
|
||||
key === "left" &&
|
||||
(parent.operator === "in" || parent.operator === "instanceof") &&
|
||||
node.type === "UnaryExpression"
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch (node.type) {
|
||||
|
||||
@@ -97,7 +97,7 @@ let tests = [
|
||||
// bogus stuff on LHS
|
||||
function () {
|
||||
null in {}; // error
|
||||
void 0 in {}; // error
|
||||
(void 0) in {}; // error
|
||||
({}) in {}; // error
|
||||
[] in {}; // error
|
||||
false in []; // error
|
||||
@@ -107,7 +107,7 @@ let tests = [
|
||||
function () {
|
||||
if ("foo" in 123) {
|
||||
} // error
|
||||
if (!"foo" in {}) {
|
||||
if ((!"foo") in {}) {
|
||||
} // error, !'foo' is a boolean
|
||||
if (!("foo" in {})) {
|
||||
}
|
||||
|
||||
@@ -424,6 +424,164 @@ if (
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`in_instanceof.js format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["babel", "flow", "typescript"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
!foo in bar;
|
||||
(!foo in bar);
|
||||
!(foo in bar);
|
||||
(!foo) in bar;
|
||||
|
||||
!foo instanceof Bar;
|
||||
(!foo instanceof Bar);
|
||||
!(foo instanceof Bar);
|
||||
(!foo) instanceof Bar;
|
||||
|
||||
~foo in bar;
|
||||
(~foo in bar);
|
||||
~(foo in bar);
|
||||
(~foo) in bar;
|
||||
|
||||
~foo instanceof Bar;
|
||||
(~foo instanceof Bar);
|
||||
~(foo instanceof Bar);
|
||||
(~foo) instanceof Bar;
|
||||
|
||||
+foo in bar;
|
||||
(+foo in bar);
|
||||
+(foo in bar);
|
||||
(+foo) in bar;
|
||||
|
||||
+foo instanceof Bar;
|
||||
(+foo instanceof Bar);
|
||||
+(foo instanceof Bar);
|
||||
(+foo) instanceof Bar;
|
||||
|
||||
-foo in bar;
|
||||
(-foo in bar);
|
||||
-(foo in bar);
|
||||
(-foo) in bar;
|
||||
|
||||
-foo instanceof Bar;
|
||||
(-foo instanceof Bar);
|
||||
-(foo instanceof Bar);
|
||||
(-foo) instanceof Bar;
|
||||
|
||||
void 0 in bar;
|
||||
(void 0 in bar);
|
||||
void (0 in bar);
|
||||
(void 0) in bar;
|
||||
|
||||
void 0 instanceof bar;
|
||||
(void 0 instanceof bar);
|
||||
void (0 instanceof bar);
|
||||
(void 0) instanceof bar;
|
||||
|
||||
delete 0 in bar;
|
||||
(delete 0 in bar);
|
||||
delete (0 in bar);
|
||||
(delete 0) in bar;
|
||||
|
||||
delete 0 instanceof bar;
|
||||
(delete 0 instanceof bar);
|
||||
delete (0 instanceof bar);
|
||||
(delete 0) instanceof bar;
|
||||
|
||||
typeof 0 in bar;
|
||||
(typeof 0 in bar);
|
||||
typeof (0 in bar);
|
||||
(typeof 0) in bar;
|
||||
|
||||
typeof 0 instanceof bar;
|
||||
(typeof 0 instanceof bar);
|
||||
typeof (0 instanceof bar);
|
||||
(typeof 0) instanceof bar;
|
||||
|
||||
++x instanceof bar; // not ambiguous, because ++(x instanceof bar) is obviously invalid
|
||||
|
||||
!!foo instanceof Bar;
|
||||
|
||||
=====================================output=====================================
|
||||
(!foo) in bar;
|
||||
(!foo) in bar;
|
||||
!(foo in bar);
|
||||
(!foo) in bar;
|
||||
|
||||
(!foo) instanceof Bar;
|
||||
(!foo) instanceof Bar;
|
||||
!(foo instanceof Bar);
|
||||
(!foo) instanceof Bar;
|
||||
|
||||
(~foo) in bar;
|
||||
(~foo) in bar;
|
||||
~(foo in bar);
|
||||
(~foo) in bar;
|
||||
|
||||
(~foo) instanceof Bar;
|
||||
(~foo) instanceof Bar;
|
||||
~(foo instanceof Bar);
|
||||
(~foo) instanceof Bar;
|
||||
|
||||
(+foo) in bar;
|
||||
(+foo) in bar;
|
||||
+(foo in bar);
|
||||
(+foo) in bar;
|
||||
|
||||
(+foo) instanceof Bar;
|
||||
(+foo) instanceof Bar;
|
||||
+(foo instanceof Bar);
|
||||
(+foo) instanceof Bar;
|
||||
|
||||
(-foo) in bar;
|
||||
(-foo) in bar;
|
||||
-(foo in bar);
|
||||
(-foo) in bar;
|
||||
|
||||
(-foo) instanceof Bar;
|
||||
(-foo) instanceof Bar;
|
||||
-(foo instanceof Bar);
|
||||
(-foo) instanceof Bar;
|
||||
|
||||
(void 0) in bar;
|
||||
(void 0) in bar;
|
||||
void (0 in bar);
|
||||
(void 0) in bar;
|
||||
|
||||
(void 0) instanceof bar;
|
||||
(void 0) instanceof bar;
|
||||
void (0 instanceof bar);
|
||||
(void 0) instanceof bar;
|
||||
|
||||
(delete 0) in bar;
|
||||
(delete 0) in bar;
|
||||
delete (0 in bar);
|
||||
(delete 0) in bar;
|
||||
|
||||
(delete 0) instanceof bar;
|
||||
(delete 0) instanceof bar;
|
||||
delete (0 instanceof bar);
|
||||
(delete 0) instanceof bar;
|
||||
|
||||
(typeof 0) in bar;
|
||||
(typeof 0) in bar;
|
||||
typeof (0 in bar);
|
||||
(typeof 0) in bar;
|
||||
|
||||
(typeof 0) instanceof bar;
|
||||
(typeof 0) instanceof bar;
|
||||
typeof (0 instanceof bar);
|
||||
(typeof 0) instanceof bar;
|
||||
|
||||
++x instanceof bar; // not ambiguous, because ++(x instanceof bar) is obviously invalid
|
||||
|
||||
(!!foo) instanceof Bar;
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`inline-jsx.js format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["babel", "flow", "typescript"]
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
!foo in bar;
|
||||
(!foo in bar);
|
||||
!(foo in bar);
|
||||
(!foo) in bar;
|
||||
|
||||
!foo instanceof Bar;
|
||||
(!foo instanceof Bar);
|
||||
!(foo instanceof Bar);
|
||||
(!foo) instanceof Bar;
|
||||
|
||||
~foo in bar;
|
||||
(~foo in bar);
|
||||
~(foo in bar);
|
||||
(~foo) in bar;
|
||||
|
||||
~foo instanceof Bar;
|
||||
(~foo instanceof Bar);
|
||||
~(foo instanceof Bar);
|
||||
(~foo) instanceof Bar;
|
||||
|
||||
+foo in bar;
|
||||
(+foo in bar);
|
||||
+(foo in bar);
|
||||
(+foo) in bar;
|
||||
|
||||
+foo instanceof Bar;
|
||||
(+foo instanceof Bar);
|
||||
+(foo instanceof Bar);
|
||||
(+foo) instanceof Bar;
|
||||
|
||||
-foo in bar;
|
||||
(-foo in bar);
|
||||
-(foo in bar);
|
||||
(-foo) in bar;
|
||||
|
||||
-foo instanceof Bar;
|
||||
(-foo instanceof Bar);
|
||||
-(foo instanceof Bar);
|
||||
(-foo) instanceof Bar;
|
||||
|
||||
void 0 in bar;
|
||||
(void 0 in bar);
|
||||
void (0 in bar);
|
||||
(void 0) in bar;
|
||||
|
||||
void 0 instanceof bar;
|
||||
(void 0 instanceof bar);
|
||||
void (0 instanceof bar);
|
||||
(void 0) instanceof bar;
|
||||
|
||||
delete 0 in bar;
|
||||
(delete 0 in bar);
|
||||
delete (0 in bar);
|
||||
(delete 0) in bar;
|
||||
|
||||
delete 0 instanceof bar;
|
||||
(delete 0 instanceof bar);
|
||||
delete (0 instanceof bar);
|
||||
(delete 0) instanceof bar;
|
||||
|
||||
typeof 0 in bar;
|
||||
(typeof 0 in bar);
|
||||
typeof (0 in bar);
|
||||
(typeof 0) in bar;
|
||||
|
||||
typeof 0 instanceof bar;
|
||||
(typeof 0 instanceof bar);
|
||||
typeof (0 instanceof bar);
|
||||
(typeof 0) instanceof bar;
|
||||
|
||||
++x instanceof bar; // not ambiguous, because ++(x instanceof bar) is obviously invalid
|
||||
|
||||
!!foo instanceof Bar;
|
||||
Reference in new issue
Block a user