Keep ChainExpression AST unchanged (#18661)
This commit is contained in:
1 parent
9ebc4a7142
commit
29c3f97dec
14 files changed
+163
-237
No files matched your search
@@ -0,0 +1,19 @@
|
||||
#### Preserve non-null assertion around optional chaining (#18661 by @fisker)
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```tsx
|
||||
// Input
|
||||
(a?.b!).c;
|
||||
(a?.b)!.c;
|
||||
(a?.b!)!.c;
|
||||
|
||||
// Prettier stable
|
||||
(a?.b)!.c;
|
||||
(a?.b)!.c;
|
||||
a?.b!!.c;
|
||||
|
||||
// Prettier main
|
||||
(a?.b!).c;
|
||||
(a?.b)!.c;
|
||||
(a?.b!)!.c;
|
||||
```
|
||||
@@ -176,16 +176,6 @@ function clean(original, cloned, parent) {
|
||||
if (original.type === "TemplateLiteral") {
|
||||
removeTemplateElementsValue(cloned);
|
||||
}
|
||||
|
||||
// We print `(a?.b!).c` as `(a?.b)!.c`, but `typescript` parse them differently
|
||||
if (
|
||||
original.type === "ChainExpression" &&
|
||||
original.expression.type === "TSNonNullExpression"
|
||||
) {
|
||||
// Ideally, we should swap these two nodes, but `type` is the only difference
|
||||
cloned.type = "TSNonNullExpression";
|
||||
cloned.expression.type = "ChainExpression";
|
||||
}
|
||||
}
|
||||
|
||||
clean.ignoredProperties = ignoredProperties;
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
import { createTypeCheckFunction } from "../utilities/index.js";
|
||||
|
||||
/**
|
||||
@import AstPath from "../../common/ast-path.js"
|
||||
*/
|
||||
|
||||
function shouldAddParenthesesToChainExpression(path) {
|
||||
const { key, parent } = path;
|
||||
|
||||
return (
|
||||
(key === "expression" && parent.type === "TSNonNullExpression") ||
|
||||
(key === "object" &&
|
||||
parent.type === "MemberExpression" &&
|
||||
!parent.optional) ||
|
||||
(key === "callee" &&
|
||||
parent.type === "CallExpression" &&
|
||||
!parent.optional) ||
|
||||
(key === "callee" && parent.type === "NewExpression") ||
|
||||
(key === "tag" && parent.type === "TaggedTemplateExpression")
|
||||
);
|
||||
}
|
||||
|
||||
const isParenthesized = (node) => node.extra?.parenthesized;
|
||||
const isBabelOptionalChainElement = createTypeCheckFunction([
|
||||
"OptionalCallExpression",
|
||||
"OptionalMemberExpression",
|
||||
]);
|
||||
|
||||
/**
|
||||
@param {AstPath} path
|
||||
*/
|
||||
function isBabelOptionalChainRoot(path) {
|
||||
const { node } = path;
|
||||
|
||||
let child = node;
|
||||
while (child.type === "TSNonNullExpression") {
|
||||
child = child.expression;
|
||||
|
||||
if (isParenthesized(child)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isBabelOptionalChainElement(child)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isParenthesized(node)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !(
|
||||
(path.key === "expression" && path.parent.type === "TSNonNullExpression")
|
||||
// We should exclude if it's in `OptionalCallExpression` or `OptionalMemberExpression`
|
||||
// But in these cases it should not matter, since we don't need parentheses anyway
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@param {AstPath} path
|
||||
@returns {boolean}
|
||||
*/
|
||||
function shouldAddParenthesesToChainElement(path) {
|
||||
return (
|
||||
(path.node.type === "ChainExpression" || isBabelOptionalChainRoot(path)) &&
|
||||
shouldAddParenthesesToChainExpression(path)
|
||||
);
|
||||
}
|
||||
|
||||
export { shouldAddParenthesesToChainElement };
|
||||
@@ -26,6 +26,7 @@ import {
|
||||
stripChainElementWrappers,
|
||||
} from "../utilities/index.js";
|
||||
import { returnArgumentHasLeadingComment } from "../utilities/return-statement-has-leading-comment.js";
|
||||
import { shouldAddParenthesesToChainElement } from "./chain-expression.js";
|
||||
import { shouldAddParenthesesToIdentifier } from "./identifier.js";
|
||||
|
||||
/**
|
||||
@@ -829,15 +830,16 @@ function needsParentheses(path, options) {
|
||||
}
|
||||
case "OptionalMemberExpression":
|
||||
case "OptionalCallExpression":
|
||||
case "CallExpression":
|
||||
case "MemberExpression":
|
||||
case "ChainExpression":
|
||||
case "TSNonNullExpression":
|
||||
if (shouldAddParenthesesToChainElement(path)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// fallthrough
|
||||
case "CallExpression":
|
||||
case "MemberExpression":
|
||||
case "TaggedTemplateExpression":
|
||||
case "TSNonNullExpression":
|
||||
if (
|
||||
key === "callee" &&
|
||||
(parent.type === "BindExpression" || parent.type === "NewExpression")
|
||||
@@ -1086,158 +1088,6 @@ function shouldWrapFunctionForExportDefault(path, options) {
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
Matches following cases:
|
||||
|
||||
```js
|
||||
(a?.b).c;
|
||||
(a?.()).b;
|
||||
(a?.b!).c;
|
||||
(a?.()!).b;
|
||||
(a?.b)!.c;
|
||||
(a?.())!.b;
|
||||
|
||||
(a?.b)();
|
||||
(a?.())();
|
||||
|
||||
new (a?.b)();
|
||||
new (a?.())();
|
||||
|
||||
(a?.b)``;
|
||||
(a?.())``;
|
||||
```
|
||||
*/
|
||||
/**
|
||||
* @param {AstPath} path
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function shouldAddParenthesesToChainElement(path) {
|
||||
if (
|
||||
// ESTree
|
||||
path.match(
|
||||
undefined,
|
||||
(node, name) => name === "expression" && node.type === "ChainExpression",
|
||||
(node, name) =>
|
||||
name === "tag" && node.type === "TaggedTemplateExpression",
|
||||
) ||
|
||||
// Babel
|
||||
path.match(
|
||||
(node) =>
|
||||
node.type === "OptionalCallExpression" ||
|
||||
node.type === "OptionalMemberExpression",
|
||||
(node, name) =>
|
||||
name === "tag" && node.type === "TaggedTemplateExpression",
|
||||
) ||
|
||||
// Babel-ts
|
||||
// (a?.b)!``;
|
||||
// (a?.b!)``;
|
||||
path.match(
|
||||
(node) =>
|
||||
node.type === "OptionalCallExpression" ||
|
||||
node.type === "OptionalMemberExpression",
|
||||
(node, name) =>
|
||||
name === "expression" && node.type === "TSNonNullExpression",
|
||||
(node, name) =>
|
||||
name === "tag" && node.type === "TaggedTemplateExpression",
|
||||
) ||
|
||||
// case (a?.b)!``; in Typescript
|
||||
path.match(
|
||||
undefined,
|
||||
(node, name) => name === "expression" && node.type === "ChainExpression",
|
||||
(node, name) =>
|
||||
name === "expression" && node.type === "TSNonNullExpression",
|
||||
(node, name) =>
|
||||
name === "tag" && node.type === "TaggedTemplateExpression",
|
||||
) ||
|
||||
// case (a?.b!)``; in Typescript
|
||||
path.match(
|
||||
undefined,
|
||||
(node, name) =>
|
||||
name === "expression" && node.type === "TSNonNullExpression",
|
||||
(node, name) => name === "expression" && node.type === "ChainExpression",
|
||||
(node, name) =>
|
||||
name === "tag" && node.type === "TaggedTemplateExpression",
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (
|
||||
path.match(
|
||||
(node) =>
|
||||
node.type === "OptionalMemberExpression" ||
|
||||
node.type === "OptionalCallExpression",
|
||||
(node, name) =>
|
||||
(name === "object" && node.type === "MemberExpression") ||
|
||||
(name === "callee" &&
|
||||
(node.type === "CallExpression" || node.type === "NewExpression")),
|
||||
) ||
|
||||
path.match(
|
||||
(node) =>
|
||||
node.type === "OptionalMemberExpression" ||
|
||||
node.type === "OptionalCallExpression",
|
||||
(node, name) =>
|
||||
name === "expression" && node.type === "TSNonNullExpression",
|
||||
(node, name) =>
|
||||
(name === "object" && node.type === "MemberExpression") ||
|
||||
(name === "callee" && node.type === "CallExpression"),
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// ESTree, same logic as babel
|
||||
if (
|
||||
path.match(
|
||||
(node) =>
|
||||
node.type === "CallExpression" || node.type === "MemberExpression",
|
||||
(node, name) => name === "expression" && node.type === "ChainExpression",
|
||||
) &&
|
||||
(path.match(
|
||||
undefined,
|
||||
undefined,
|
||||
(node, name) =>
|
||||
(name === "callee" &&
|
||||
((node.type === "CallExpression" && !node.optional) ||
|
||||
node.type === "NewExpression")) ||
|
||||
(name === "object" &&
|
||||
node.type === "MemberExpression" &&
|
||||
!node.optional),
|
||||
) ||
|
||||
path.match(
|
||||
undefined,
|
||||
undefined,
|
||||
(node, name) =>
|
||||
name === "expression" && node.type === "TSNonNullExpression",
|
||||
(node, name) =>
|
||||
(name === "object" && node.type === "MemberExpression") ||
|
||||
(name === "callee" && node.type === "CallExpression"),
|
||||
))
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Babel treat `(a?.b!).c` and `(a?.b)!.c` the same, https://github.com/babel/babel/discussions/15077
|
||||
// Use this to align with babel
|
||||
if (
|
||||
path.match(
|
||||
(node) =>
|
||||
node.type === "CallExpression" || node.type === "MemberExpression",
|
||||
(node, name) =>
|
||||
name === "expression" && node.type === "TSNonNullExpression",
|
||||
(node, name) => name === "expression" && node.type === "ChainExpression",
|
||||
(node, name) =>
|
||||
(name === "object" && node.type === "MemberExpression") ||
|
||||
(name === "callee" && node.type === "CallExpression"),
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// This function only handle cases above
|
||||
return false;
|
||||
}
|
||||
|
||||
function isDecoratorMemberExpression(node) {
|
||||
if (node.type === "Identifier") {
|
||||
return true;
|
||||
|
||||
@@ -46,16 +46,12 @@ import { printOptionalToken } from "./miscellaneous.js";
|
||||
// The way it is structured in the AST is via a nested sequence of
|
||||
// MemberExpression and CallExpression. We need to traverse the AST
|
||||
// and make groups out of it to print it in the desired way.
|
||||
/*
|
||||
- `BindExpression`
|
||||
- `MemberExpression`
|
||||
- `OptionalMemberExpression`
|
||||
*/
|
||||
function printMemberChain(path, options, print) {
|
||||
// TODO[@fisker]: skip `TSNonNullExpression`
|
||||
/* c8 ignore next 6 */
|
||||
if (path.node.type === "ChainExpression") {
|
||||
return path.call(
|
||||
() => printMemberChain(path, options, print),
|
||||
"expression",
|
||||
);
|
||||
}
|
||||
|
||||
const isExpressionStatement =
|
||||
(path.parent.type === "ChainExpression" ? path.grandparent : path.parent)
|
||||
.type === "ExpressionStatement";
|
||||
@@ -95,10 +91,6 @@ function printMemberChain(path, options, print) {
|
||||
function rec() {
|
||||
const { node } = path;
|
||||
|
||||
if (node.type === "ChainExpression") {
|
||||
return path.call(rec, "expression");
|
||||
}
|
||||
|
||||
if (
|
||||
isCallExpression(node) &&
|
||||
(isMemberish(node.callee) || isCallExpression(node.callee))
|
||||
@@ -137,6 +129,7 @@ function printMemberChain(path, options, print) {
|
||||
} else if (node.type === "TSNonNullExpression") {
|
||||
printedNodes.unshift({
|
||||
node,
|
||||
needsParens: needsParentheses(path, options),
|
||||
printed: printComments(path, "!", options),
|
||||
});
|
||||
path.call(rec, "expression");
|
||||
|
||||
@@ -68,7 +68,7 @@ printWidth: 80
|
||||
=====================================output=====================================
|
||||
{{ foo?.bar!.bam }}
|
||||
{{ (foo?.bar)!.bam }}
|
||||
{{ (foo?.bar)!.bam }}
|
||||
{{ (foo?.bar!).bam }}
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
@@ -506,9 +506,8 @@ if (true) {
|
||||
.type;
|
||||
const secondType3 = (sourceCode?.getNodeByRangeIndex1234(second.range[0])!)
|
||||
.type;
|
||||
// TODO[@fisker]: Fix
|
||||
// const secondType4 = (sourceCode?.getNodeByRangeIndex1234(second.range[0])!)!
|
||||
// .type;
|
||||
const secondType4 = (sourceCode?.getNodeByRangeIndex1234(second.range[0])!)!
|
||||
.type;
|
||||
const secondType5 = sourceCode.getNodeByRangeIndex1234(second.range[0])!!
|
||||
.type;
|
||||
}
|
||||
@@ -525,10 +524,10 @@ if (true) {
|
||||
)).type;
|
||||
const secondType3 = (sourceCode?.getNodeByRangeIndex1234(
|
||||
second.range[0],
|
||||
))!.type;
|
||||
// TODO[@fisker]: Fix
|
||||
// const secondType4 = (sourceCode?.getNodeByRangeIndex1234(second.range[0])!)!
|
||||
// .type;
|
||||
)!).type;
|
||||
const secondType4 = (sourceCode?.getNodeByRangeIndex1234(
|
||||
second.range[0],
|
||||
)!)!.type;
|
||||
const secondType5 = sourceCode.getNodeByRangeIndex1234(
|
||||
second.range[0],
|
||||
)!!.type;
|
||||
|
||||
@@ -6,9 +6,8 @@ if (true) {
|
||||
.type;
|
||||
const secondType3 = (sourceCode?.getNodeByRangeIndex1234(second.range[0])!)
|
||||
.type;
|
||||
// TODO[@fisker]: Fix
|
||||
// const secondType4 = (sourceCode?.getNodeByRangeIndex1234(second.range[0])!)!
|
||||
// .type;
|
||||
const secondType4 = (sourceCode?.getNodeByRangeIndex1234(second.range[0])!)!
|
||||
.type;
|
||||
const secondType5 = sourceCode.getNodeByRangeIndex1234(second.range[0])!!
|
||||
.type;
|
||||
}
|
||||
|
||||
@@ -74,14 +74,14 @@ foo((a?.b)!)
|
||||
=====================================output=====================================
|
||||
// Member expressions
|
||||
(a?.b)!();
|
||||
(a?.b)!();
|
||||
(a?.b!)();
|
||||
(a!?.b)();
|
||||
(a.b?.c)!();
|
||||
(a.b?.c)!();
|
||||
(a.b?.c!)();
|
||||
(a.b!?.c)();
|
||||
(a!.b?.c)();
|
||||
(a?.b.c)!();
|
||||
(a?.b.c)!();
|
||||
(a?.b.c!)();
|
||||
(a?.b!.c)();
|
||||
(a!?.b.c)();
|
||||
a[b?.c]!();
|
||||
@@ -105,21 +105,21 @@ a![b?.()]();
|
||||
(a?.()).b!();
|
||||
(a?.()).b!();
|
||||
(a?.())!.b();
|
||||
(a?.())!.b();
|
||||
(a?.()!).b();
|
||||
(a!?.()).b();
|
||||
|
||||
// Call expressions
|
||||
(a?.())!();
|
||||
(a?.())!();
|
||||
(a?.()!)();
|
||||
(a!?.())();
|
||||
(a.b.c?.())!();
|
||||
(a.b.c?.())!();
|
||||
(a.b.c?.()!)();
|
||||
(a.b.c!?.())();
|
||||
(a.b?.c())!();
|
||||
(a.b?.c())!();
|
||||
(a.b?.c()!)();
|
||||
(a.b!?.c())();
|
||||
(a?.b.c())!();
|
||||
(a?.b.c())!();
|
||||
(a?.b.c()!)();
|
||||
(a?.b!.c())();
|
||||
a(b?.c)!();
|
||||
a(b?.c)!();
|
||||
@@ -127,15 +127,15 @@ a(b?.c!)();
|
||||
(a?.b)()!();
|
||||
(a?.b)()!();
|
||||
(a?.b)!()();
|
||||
(a?.b)!()();
|
||||
(a?.b!)()();
|
||||
(a?.())()!();
|
||||
(a?.())()!();
|
||||
(a?.())!()();
|
||||
(a?.())!()();
|
||||
(a?.()!)()();
|
||||
(a!?.())()();
|
||||
|
||||
// Not \`.callee\`
|
||||
foo(a?.b!);
|
||||
foo((a?.b)!);
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
@@ -285,14 +285,14 @@ _[a?.b!]
|
||||
=====================================output=====================================
|
||||
// Member expressions
|
||||
(a?.b)!.foo;
|
||||
(a?.b)!.foo;
|
||||
(a?.b!).foo;
|
||||
(a!?.b).foo;
|
||||
(a.b?.c)!.foo;
|
||||
(a.b?.c)!.foo;
|
||||
(a.b?.c!).foo;
|
||||
(a.b!?.c).foo;
|
||||
(a!.b?.c).foo;
|
||||
(a?.b.c)!.foo;
|
||||
(a?.b.c)!.foo;
|
||||
(a?.b.c!).foo;
|
||||
(a?.b!.c).foo;
|
||||
(a!?.b.c).foo;
|
||||
a[b?.c]!.foo;
|
||||
@@ -301,7 +301,7 @@ a[b?.c!].foo;
|
||||
a[b!?.c].foo;
|
||||
(a?.b).c!.foo;
|
||||
(a?.b).c!.foo;
|
||||
(a?.b)!.c.foo;
|
||||
(a?.b!).c.foo;
|
||||
(a!?.b).c.foo;
|
||||
a[b?.()]!.foo;
|
||||
a[b?.()]!.foo;
|
||||
@@ -311,26 +311,26 @@ a![b?.()].foo;
|
||||
(a?.b).c!.foo;
|
||||
(a?.b).c!.foo;
|
||||
(a?.b)!.c.foo;
|
||||
(a?.b)!.c.foo;
|
||||
(a?.b!).c.foo;
|
||||
(a!?.b).c.foo;
|
||||
(a?.()).b!.foo;
|
||||
(a?.()).b!.foo;
|
||||
(a?.())!.b.foo;
|
||||
(a?.())!.b.foo;
|
||||
(a?.()!).b.foo;
|
||||
(a!?.()).b.foo;
|
||||
|
||||
// Call expressions
|
||||
(a?.())!.foo;
|
||||
(a?.())!.foo;
|
||||
(a?.()!).foo;
|
||||
(a!?.()).foo;
|
||||
(a.b.c?.())!.foo;
|
||||
(a.b.c?.())!.foo;
|
||||
(a.b.c?.()!).foo;
|
||||
(a.b.c!?.()).foo;
|
||||
(a.b?.c())!.foo;
|
||||
(a.b?.c())!.foo;
|
||||
(a.b?.c()!).foo;
|
||||
(a.b!?.c()).foo;
|
||||
(a?.b.c())!.foo;
|
||||
(a?.b.c())!.foo;
|
||||
(a?.b.c()!).foo;
|
||||
(a?.b!.c()).foo;
|
||||
a(b?.c)!.foo;
|
||||
a(b?.c)!.foo;
|
||||
@@ -338,11 +338,11 @@ a(b?.c!).foo;
|
||||
(a?.b)()!.foo;
|
||||
(a?.b)()!.foo;
|
||||
(a?.b)!().foo;
|
||||
(a?.b)!().foo;
|
||||
(a?.b!)().foo;
|
||||
(a?.())()!.foo;
|
||||
(a?.())()!.foo;
|
||||
(a?.())!().foo;
|
||||
(a?.())!().foo;
|
||||
(a?.()!)().foo;
|
||||
(a!?.())().foo;
|
||||
|
||||
// Not \`.object\`
|
||||
@@ -444,7 +444,7 @@ new a[b?.c!]();
|
||||
new a[b!?.c]();
|
||||
new (a?.b).c!();
|
||||
new (a?.b).c!();
|
||||
new (a?.b)!.c();
|
||||
new (a?.b!).c();
|
||||
new (a!?.b).c();
|
||||
new a[b?.()]!();
|
||||
new a[b?.()]!();
|
||||
@@ -454,7 +454,7 @@ new a![b?.()]();
|
||||
new (a?.b).c!();
|
||||
new (a?.b).c!();
|
||||
new (a?.b)!.c();
|
||||
new (a?.b)!.c();
|
||||
new (a?.b!).c();
|
||||
new (a!?.b).c();
|
||||
// FIXME: new ((a?.()).b)! ();
|
||||
// FIXME: new ((a?.()).b!) ();
|
||||
@@ -481,11 +481,11 @@ new (a(b?.c!))();
|
||||
new ((a?.b)()!)();
|
||||
new ((a?.b)()!)();
|
||||
new ((a?.b)!())();
|
||||
new ((a?.b)!())();
|
||||
new ((a?.b!)())();
|
||||
new ((a?.())()!)();
|
||||
new ((a?.())()!)();
|
||||
new ((a?.())!())();
|
||||
new ((a?.())!())();
|
||||
new ((a?.()!)())();
|
||||
new ((a!?.())())();
|
||||
|
||||
// Not \`.callee\`
|
||||
@@ -565,14 +565,14 @@ printWidth: 80
|
||||
=====================================output=====================================
|
||||
// Member expressions
|
||||
(a?.b)!\`\`;
|
||||
(a?.b)!\`\`;
|
||||
(a?.b!)\`\`;
|
||||
(a!?.b)\`\`;
|
||||
(a.b?.c)!\`\`;
|
||||
(a.b?.c)!\`\`;
|
||||
(a.b?.c!)\`\`;
|
||||
(a.b!?.c)\`\`;
|
||||
(a!.b?.c)\`\`;
|
||||
(a?.b.c)!\`\`;
|
||||
(a?.b.c)!\`\`;
|
||||
(a?.b.c!)\`\`;
|
||||
(a?.b!.c)\`\`;
|
||||
(a!?.b.c)\`\`;
|
||||
a[b?.c]!\`\`;
|
||||
@@ -581,7 +581,7 @@ a[b?.c!]\`\`;
|
||||
a[b!?.c]\`\`;
|
||||
(a?.b).c!\`\`;
|
||||
(a?.b).c!\`\`;
|
||||
(a?.b)!.c\`\`;
|
||||
(a?.b!).c\`\`;
|
||||
(a!?.b).c\`\`;
|
||||
a[b?.()]!\`\`;
|
||||
a[b?.()]!\`\`;
|
||||
@@ -591,26 +591,26 @@ a![b?.()]\`\`;
|
||||
(a?.b).c!\`\`;
|
||||
(a?.b).c!\`\`;
|
||||
(a?.b)!.c\`\`;
|
||||
(a?.b)!.c\`\`;
|
||||
(a?.b!).c\`\`;
|
||||
(a!?.b).c\`\`;
|
||||
(a?.()).b!\`\`;
|
||||
(a?.()).b!\`\`;
|
||||
(a?.())!.b\`\`;
|
||||
(a?.())!.b\`\`;
|
||||
(a?.()!).b\`\`;
|
||||
(a!?.()).b\`\`;
|
||||
|
||||
// Call expressions
|
||||
(a?.())!\`\`;
|
||||
(a?.())!\`\`;
|
||||
(a?.()!)\`\`;
|
||||
(a!?.())\`\`;
|
||||
(a.b.c?.())!\`\`;
|
||||
(a.b.c?.())!\`\`;
|
||||
(a.b.c?.()!)\`\`;
|
||||
(a.b.c!?.())\`\`;
|
||||
(a.b?.c())!\`\`;
|
||||
(a.b?.c())!\`\`;
|
||||
(a.b?.c()!)\`\`;
|
||||
(a.b!?.c())\`\`;
|
||||
(a?.b.c())!\`\`;
|
||||
(a?.b.c())!\`\`;
|
||||
(a?.b.c()!)\`\`;
|
||||
(a?.b!.c())\`\`;
|
||||
a(b?.c)!\`\`;
|
||||
a(b?.c)!\`\`;
|
||||
@@ -618,11 +618,11 @@ a(b?.c!)\`\`;
|
||||
(a?.b)()!\`\`;
|
||||
(a?.b)()!\`\`;
|
||||
(a?.b)!()\`\`;
|
||||
(a?.b)!()\`\`;
|
||||
(a?.b!)()\`\`;
|
||||
(a?.())()!\`\`;
|
||||
(a?.())()!\`\`;
|
||||
(a?.())!()\`\`;
|
||||
(a?.())!()\`\`;
|
||||
(a?.()!)()\`\`;
|
||||
(a!?.())()\`\`;
|
||||
|
||||
================================================================================
|
||||
@@ -640,8 +640,8 @@ printWidth: 80
|
||||
(a?.())!.b;
|
||||
|
||||
=====================================output=====================================
|
||||
(a?.b)!.c;
|
||||
(a?.())!.b;
|
||||
(a?.b!).c;
|
||||
(a?.()!).b;
|
||||
(a?.b)!.c;
|
||||
(a?.())!.b;
|
||||
|
||||
|
||||
@@ -105,7 +105,9 @@ a?.().b!.c?.c;
|
||||
(a?.().b!).c;
|
||||
(a?.().b)!.c;
|
||||
|
||||
(a?.b)![c?.d!]
|
||||
(a?.b)![c?.d!];
|
||||
|
||||
(a?.b!!)!!.c;
|
||||
|
||||
=====================================output=====================================
|
||||
a?.b!.c;
|
||||
@@ -114,7 +116,7 @@ a?.b.c!.d;
|
||||
a!.b?.c;
|
||||
a?.b!?.c;
|
||||
a?.b!.c?.c;
|
||||
(a?.b)!.c;
|
||||
(a?.b!).c;
|
||||
(a?.b)!.c;
|
||||
|
||||
a?.().b!.c;
|
||||
@@ -122,11 +124,13 @@ a?.().b!.c.d;
|
||||
a?.().b.c!.d;
|
||||
a?.().b!?.c;
|
||||
a?.().b!.c?.c;
|
||||
(a?.().b)!.c;
|
||||
(a?.().b!).c;
|
||||
(a?.().b)!.c;
|
||||
|
||||
(a?.b)![c?.d!];
|
||||
|
||||
(a?.b!!)!!.c;
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
|
||||
@@ -15,4 +15,6 @@ a?.().b!.c?.c;
|
||||
(a?.().b!).c;
|
||||
(a?.().b)!.c;
|
||||
|
||||
(a?.b)![c?.d!]
|
||||
(a?.b)![c?.d!];
|
||||
|
||||
(a?.b!!)!!.c;
|
||||
@@ -78,8 +78,8 @@ long1 = \`long \${
|
||||
} long longlong \${a.b.c.d.e} long longlong \${a.b.c.d.e} long longlong \${a.b.c.d.e} long long\`;
|
||||
|
||||
long1 = \`long \${
|
||||
a //comment
|
||||
?.b!
|
||||
(a //comment
|
||||
?.b)!
|
||||
} long longlong \${a.b.c.d.e} long longlong \${a.b.c.d.e} long longlong \${a.b.c.d.e} long long\`;
|
||||
|
||||
================================================================================
|
||||
|
||||
@@ -126,7 +126,7 @@ const footer = "<footer></footer>";
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`optional-chainning.tsx format 1`] = `
|
||||
exports[`optional-chaining.tsx format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["typescript"]
|
||||
printWidth: 80
|
||||
|
||||
File renamed without changes.
Reference in new issue
Block a user