diff --git a/changelog_unreleased/javascript/13183.md b/changelog_unreleased/javascript/13183.md new file mode 100644 index 000000000..84f76dd5c --- /dev/null +++ b/changelog_unreleased/javascript/13183.md @@ -0,0 +1,38 @@ +#### New Ternary Formatting: A Curious Case of the Ternaries (#13183 by @rattrayalex) + +This is implemented behind a `--experimental-ternaries` flag. + +--- + +We move the `?` in multiline ternaries to the end of the first line instead of the start of the second, along with several related changes. + +While it might look weird at first, beta-testing shows that after a few hours of use, developers find it makes nested ternaries much more readable and useful. + +This PR resolves one of our [a highly-upvoted issue](https://github.com/prettier/prettier/issues/5814) without the problems its proposed solution would reintroduce. + +## Example + + +```js +// "Questioning" ternaries for simple ternaries: +const content = + children && !isEmptyChildren(children) ? + render(children) + : renderDefaultChildren(); + +// "Case-style" ternaries for chained ternaries: +const message = + i % 3 === 0 && i % 5 === 0 ? "fizzbuzz" + : i % 3 === 0 ? "fizz" + : i % 5 === 0 ? "buzz" + : String(i); + +// Smoothly transitions between "case-style" and "questioning" when things get complicated: +const reactRouterResult = + children && !isEmptyChildren(children) ? children + : props.match ? + component ? React.createElement(component, props) + : render ? render(props) + : null + : null +``` diff --git a/cspell.json b/cspell.json index ef3ab0022..0dcad9df6 100644 --- a/cspell.json +++ b/cspell.json @@ -356,6 +356,7 @@ "unparseable", "Unrestrict", "unstaged", + "upvoted", "valourous", "Vanderwerff", "vanguarding", diff --git a/docs/options.md b/docs/options.md index 3c72525f4..f2318cece 100644 --- a/docs/options.md +++ b/docs/options.md @@ -9,6 +9,19 @@ Prettier ships with a handful of format options. If you change any options, it’s recommended to do it via a [configuration file](configuration.md). This way the Prettier CLI, [editor integrations](editors.md) and other tooling knows what options you use. +## Experimental Ternaries + +Try prettier's [new ternary formatting](https://github.com/prettier/prettier/pull/13183) before it becomes the default behavior. + +Valid options: + +- `true` - Use curious ternaries, with the question mark after the condition. +- `false` - Retain the default behavior of ternaries; keep question marks on the same line as the consequent. + +| Default | CLI Override | API Override | +| ------- | -------------------------- | ------------------------------- | +| `false` | `--experimental-ternaries` | `experimentalTernaries: ` | + ## Print Width Specify the line length that the printer will wrap on. diff --git a/src/language-js/comments/handle-comments.js b/src/language-js/comments/handle-comments.js index 417146c68..0712fbe2e 100644 --- a/src/language-js/comments/handle-comments.js +++ b/src/language-js/comments/handle-comments.js @@ -46,6 +46,7 @@ import isTypeCastComment from "../utils/is-type-cast-comment.js"; function handleOwnLineComment(context) { return [ handleIgnoreComments, + handleConditionalExpressionComments, handleLastFunctionArgComments, handleMemberExpressionComments, handleIfStatementComments, @@ -60,6 +61,7 @@ function handleOwnLineComment(context) { handleMethodNameComments, handleLabeledStatementComments, handleBreakAndContinueStatementComments, + handleNestedConditionalExpressionComments, ].some((fn) => fn(context)); } @@ -335,12 +337,44 @@ function handleMemberExpressionComments({ return false; } +function handleNestedConditionalExpressionComments({ + comment, + enclosingNode, + followingNode, + options, +}) { + if (!options.experimentalTernaries) { + return false; + } + + const enclosingIsCond = + enclosingNode?.type === "ConditionalExpression" || + enclosingNode?.type === "ConditionalTypeAnnotation" || + enclosingNode?.type === "TSConditionalType"; + + if (!enclosingIsCond) { + return false; + } + + const followingIsCond = + followingNode?.type === "ConditionalExpression" || + followingNode?.type === "ConditionalTypeAnnotation" || + followingNode?.type === "TSConditionalType"; + + if (followingIsCond) { + addDanglingComment(enclosingNode, comment); + return true; + } + return false; +} + function handleConditionalExpressionComments({ comment, precedingNode, enclosingNode, followingNode, text, + options, }) { const isSameLineAsPrecedingNode = precedingNode && @@ -349,9 +383,25 @@ function handleConditionalExpressionComments({ if ( (!precedingNode || !isSameLineAsPrecedingNode) && (enclosingNode?.type === "ConditionalExpression" || + enclosingNode?.type === "ConditionalTypeAnnotation" || enclosingNode?.type === "TSConditionalType") && followingNode ) { + if ( + options.experimentalTernaries && + enclosingNode.alternate === followingNode && + !( + isBlockComment(comment) && + !hasNewlineInRange( + options.originalText, + locStart(comment), + locEnd(comment), + ) + ) + ) { + addDanglingComment(enclosingNode, comment); + return true; + } addLeadingComment(followingNode, comment); return true; } diff --git a/src/language-js/needs-parens.js b/src/language-js/needs-parens.js index f51b8dbda..6814a8d98 100644 --- a/src/language-js/needs-parens.js +++ b/src/language-js/needs-parens.js @@ -781,7 +781,11 @@ function needsParens(path, options) { return key === "callee"; case "ConditionalExpression": - return key === "test"; + // TODO remove this case entirely once we've removed this flag. + if (!options.experimentalTernaries) { + return key === "test"; + } + return false; case "MemberExpression": case "OptionalMemberExpression": diff --git a/src/language-js/options.js b/src/language-js/options.js index 403357ab1..f7627c189 100644 --- a/src/language-js/options.js +++ b/src/language-js/options.js @@ -36,6 +36,15 @@ const options = { oppositeDescription: "Do not print semicolons, except at the beginning of lines which may need them.", }, + experimentalTernaries: { + category: CATEGORY_JAVASCRIPT, + type: "boolean", + default: false, + description: + "Use curious ternaries, with the question mark after the condition.", + oppositeDescription: + "Default behavior of ternaries; keep question marks on the same line as the consequent.", + }, singleQuote: commonOptions.singleQuote, jsxSingleQuote: { category: CATEGORY_JAVASCRIPT, diff --git a/src/language-js/print/assignment.js b/src/language-js/print/assignment.js index a12a45df2..a1f869866 100644 --- a/src/language-js/print/assignment.js +++ b/src/language-js/print/assignment.js @@ -187,9 +187,22 @@ function shouldBreakAfterOperator(path, options, print, hasShortKey) { case "StringLiteralTypeAnnotation": case "SequenceExpression": return true; + case "TSConditionalType": + case "ConditionalTypeAnnotation": + if (!options.experimentalTernaries) { + break; + } + return true; case "ConditionalExpression": { - const { test } = rightNode; - return isBinaryish(test) && !shouldInlineLogicalExpression(test); + if (!options.experimentalTernaries) { + const { test } = rightNode; + return isBinaryish(test) && !shouldInlineLogicalExpression(test); + } + const { consequent, alternate } = rightNode; + return ( + consequent.type === "ConditionalExpression" || + alternate.type === "ConditionalExpression" + ); } case "ClassExpression": return isNonEmptyArray(rightNode.decorators); diff --git a/src/language-js/print/estree.js b/src/language-js/print/estree.js index 6d872ce4c..5c51d7a2e 100644 --- a/src/language-js/print/estree.js +++ b/src/language-js/print/estree.js @@ -320,7 +320,7 @@ function printEstree(path, options, print, args) { return parts; case "ConditionalExpression": - return printTernary(path, options, print); + return printTernary(path, options, print, args); case "VariableDeclaration": { const printed = path.map(print, "declarations"); diff --git a/src/language-js/print/function.js b/src/language-js/print/function.js index 0049081ba..6ac200332 100644 --- a/src/language-js/print/function.js +++ b/src/language-js/print/function.js @@ -243,7 +243,11 @@ function printReturnOrThrowArgument(path, options, print) { argumentDoc = ["(", indent([hardline, argumentDoc]), hardline, ")"]; } else if ( isBinaryish(node.argument) || - node.argument.type === "SequenceExpression" + node.argument.type === "SequenceExpression" || + (options.experimentalTernaries && + node.argument.type === "ConditionalExpression" && + (node.argument.consequent.type === "ConditionalExpression" || + node.argument.alternate.type === "ConditionalExpression")) ) { argumentDoc = group([ ifBreak("("), diff --git a/src/language-js/print/ternary-old.js b/src/language-js/print/ternary-old.js new file mode 100644 index 000000000..e6a601719 --- /dev/null +++ b/src/language-js/print/ternary-old.js @@ -0,0 +1,351 @@ +import hasNewlineInRange from "../../utils/has-newline-in-range.js"; +import { + isJsxElement, + isCallExpression, + isMemberExpression, + isBinaryCastExpression, + hasComment, +} from "../utils/index.js"; +import { locStart, locEnd } from "../loc.js"; +import isBlockComment from "../utils/is-block-comment.js"; +import { + line, + softline, + group, + indent, + align, + ifBreak, + dedent, + breakParent, +} from "../../document/builders.js"; + +/** + * @typedef {import("../../document/builders.js").Doc} Doc + * @typedef {import("../../common/ast-path.js").default} AstPath + * + * @typedef {any} Options - Prettier options (TBD ...) + */ + +// If we have nested conditional expressions, we want to print them in JSX mode +// if there's at least one JSXElement somewhere in the tree. +// +// A conditional expression chain like this should be printed in normal mode, +// because there aren't JSXElements anywhere in it: +// +// isA ? "A" : isB ? "B" : isC ? "C" : "Unknown"; +// +// But a conditional expression chain like this should be printed in JSX mode, +// because there is a JSXElement in the last ConditionalExpression: +// +// isA ? "A" : isB ? "B" : isC ? "C" : Unknown; +// +// This type of ConditionalExpression chain is structured like this in the AST: +// +// ConditionalExpression { +// test: ..., +// consequent: ..., +// alternate: ConditionalExpression { +// test: ..., +// consequent: ..., +// alternate: ConditionalExpression { +// test: ..., +// consequent: ..., +// alternate: ..., +// } +// } +// } +function conditionalExpressionChainContainsJsx(node) { + // Given this code: + // + // // Using a ConditionalExpression as the consequent is uncommon, but should + // // be handled. + // A ? B : C ? D : E ? F ? G : H : I + // + // which has this AST: + // + // ConditionalExpression { + // test: Identifier(A), + // consequent: Identifier(B), + // alternate: ConditionalExpression { + // test: Identifier(C), + // consequent: Identifier(D), + // alternate: ConditionalExpression { + // test: Identifier(E), + // consequent: ConditionalExpression { + // test: Identifier(F), + // consequent: Identifier(G), + // alternate: Identifier(H), + // }, + // alternate: Identifier(I), + // } + // } + // } + // + // We don't care about whether each node was the test, consequent, or alternate + // We are only checking if there's any JSXElements inside. + const conditionalExpressions = [node]; + for (let index = 0; index < conditionalExpressions.length; index++) { + const conditionalExpression = conditionalExpressions[index]; + for (const property of ["test", "consequent", "alternate"]) { + const node = conditionalExpression[property]; + + if (isJsxElement(node)) { + return true; + } + + if (node.type === "ConditionalExpression") { + conditionalExpressions.push(node); + } + } + } + + return false; +} + +function printTernaryTest(path, options, print) { + const { node } = path; + const isConditionalExpression = node.type === "ConditionalExpression"; + const alternateNodePropertyName = isConditionalExpression + ? "alternate" + : "falseType"; + + const { parent } = path; + + const printed = isConditionalExpression + ? print("test") + : [print("checkType"), " ", "extends", " ", print("extendsType")]; + /** + * a + * ? b + * : multiline + * test + * node + * ^^ align(2) + * ? d + * : e + */ + if (parent.type === node.type && parent[alternateNodePropertyName] === node) { + return align(2, printed); + } + return printed; +} + +const ancestorNameMap = new Map([ + ["AssignmentExpression", "right"], + ["VariableDeclarator", "init"], + ["ReturnStatement", "argument"], + ["ThrowStatement", "argument"], + ["UnaryExpression", "argument"], + ["YieldExpression", "argument"], +]); +function shouldExtraIndentForConditionalExpression(path) { + const { node } = path; + if (node.type !== "ConditionalExpression") { + return false; + } + + let parent; + let child = node; + for (let ancestorCount = 0; !parent; ancestorCount++) { + const node = path.getParentNode(ancestorCount); + + if ( + (node.type === "ChainExpression" && node.expression === child) || + (isCallExpression(node) && node.callee === child) || + (isMemberExpression(node) && node.object === child) || + (node.type === "TSNonNullExpression" && node.expression === child) + ) { + child = node; + continue; + } + + // Reached chain root + + if ( + (node.type === "NewExpression" && node.callee === child) || + (isBinaryCastExpression(node) && node.expression === child) + ) { + parent = path.getParentNode(ancestorCount + 1); + child = node; + } else { + parent = node; + } + } + + // Do not add indent to direct `ConditionalExpression` + if (child === node) { + return false; + } + + return parent[ancestorNameMap.get(parent.type)] === child; +} + +/** + * The following is the shared logic for + * ternary operators, namely ConditionalExpression, + * ConditionalTypeAnnotation and TSConditionalType + * @param {AstPath} path - The path to the ConditionalExpression/TSConditionalType node. + * @param {Options} options - Prettier options + * @param {Function} print - Print function to call recursively + * @returns {Doc} + */ +function printTernaryOld(path, options, print) { + const { node } = path; + const isConditionalExpression = node.type === "ConditionalExpression"; + const consequentNodePropertyName = isConditionalExpression + ? "consequent" + : "trueType"; + const alternateNodePropertyName = isConditionalExpression + ? "alternate" + : "falseType"; + const testNodePropertyNames = isConditionalExpression + ? ["test"] + : ["checkType", "extendsType"]; + const consequentNode = node[consequentNodePropertyName]; + const alternateNode = node[alternateNodePropertyName]; + const parts = []; + + // We print a ConditionalExpression in either "JSX mode" or "normal mode". + // See `tests/format/jsx/conditional-expression.js` for more info. + let jsxMode = false; + const { parent } = path; + const isParentTest = + parent.type === node.type && + testNodePropertyNames.some((prop) => parent[prop] === node); + let forceNoIndent = parent.type === node.type && !isParentTest; + + // Find the outermost non-ConditionalExpression parent, and the outermost + // ConditionalExpression parent. We'll use these to determine if we should + // print in JSX mode. + let currentParent; + let previousParent; + let i = 0; + do { + previousParent = currentParent || node; + currentParent = path.getParentNode(i); + i++; + } while ( + currentParent && + currentParent.type === node.type && + testNodePropertyNames.every( + (prop) => currentParent[prop] !== previousParent, + ) + ); + const firstNonConditionalParent = currentParent || parent; + const lastConditionalParent = previousParent; + + if ( + isConditionalExpression && + (isJsxElement(node[testNodePropertyNames[0]]) || + isJsxElement(consequentNode) || + isJsxElement(alternateNode) || + conditionalExpressionChainContainsJsx(lastConditionalParent)) + ) { + jsxMode = true; + forceNoIndent = true; + + // Even though they don't need parens, we wrap (almost) everything in + // parens when using ?: within JSX, because the parens are analogous to + // curly braces in an if statement. + const wrap = (doc) => [ + ifBreak("("), + indent([softline, doc]), + softline, + ifBreak(")"), + ]; + + // The only things we don't wrap are: + // * Nested conditional expressions in alternates + // * null + // * undefined + const isNil = (node) => + node.type === "NullLiteral" || + (node.type === "Literal" && node.value === null) || + (node.type === "Identifier" && node.name === "undefined"); + + parts.push( + " ? ", + isNil(consequentNode) + ? print(consequentNodePropertyName) + : wrap(print(consequentNodePropertyName)), + " : ", + alternateNode.type === node.type || isNil(alternateNode) + ? print(alternateNodePropertyName) + : wrap(print(alternateNodePropertyName)), + ); + } else { + // normal mode + const part = [ + line, + "? ", + consequentNode.type === node.type ? ifBreak("", "(") : "", + align(2, print(consequentNodePropertyName)), + consequentNode.type === node.type ? ifBreak("", ")") : "", + line, + ": ", + align(2, print(alternateNodePropertyName)), + ]; + parts.push( + parent.type !== node.type || + parent[alternateNodePropertyName] === node || + isParentTest + ? part + : options.useTabs + ? dedent(indent(part)) + : align(Math.max(0, options.tabWidth - 2), part), + ); + } + + // We want a whole chain of ConditionalExpressions to all + // break if any of them break. That means we should only group around the + // outer-most ConditionalExpression. + const shouldBreak = [ + consequentNodePropertyName, + alternateNodePropertyName, + ...testNodePropertyNames, + ].some((property) => + hasComment( + node[property], + (comment) => + isBlockComment(comment) && + hasNewlineInRange( + options.originalText, + locStart(comment), + locEnd(comment), + ), + ), + ); + const maybeGroup = (doc) => + parent === firstNonConditionalParent + ? group(doc, { shouldBreak }) + : shouldBreak + ? [doc, breakParent] + : doc; + + // Break the closing paren to keep the chain right after it: + // (a + // ? b + // : c + // ).call() + const breakClosingParen = + !jsxMode && + (isMemberExpression(parent) || + (parent.type === "NGPipeExpression" && parent.left === node)) && + !parent.computed; + + const shouldExtraIndent = shouldExtraIndentForConditionalExpression(path); + + const result = maybeGroup([ + printTernaryTest(path, options, print), + forceNoIndent ? parts : indent(parts), + isConditionalExpression && breakClosingParen && !shouldExtraIndent + ? softline + : "", + ]); + + return isParentTest || shouldExtraIndent + ? group([indent([softline, result]), softline]) + : result; +} + +export { printTernaryOld }; diff --git a/src/language-js/print/ternary.js b/src/language-js/print/ternary.js index 7f27026cc..32a3768ab 100644 --- a/src/language-js/print/ternary.js +++ b/src/language-js/print/ternary.js @@ -4,20 +4,28 @@ import { isCallExpression, isMemberExpression, isBinaryCastExpression, + getComments, + isLoneShortArgument, + isSimpleExpressionByNodeCount, hasComment, + CommentCheckFlags, } from "../utils/index.js"; import { locStart, locEnd } from "../loc.js"; import isBlockComment from "../utils/is-block-comment.js"; import { line, softline, + hardline, group, indent, - align, - ifBreak, dedent, + ifBreak, breakParent, } from "../../document/builders.js"; +import pathNeedsParens from "../needs-parens.js"; +import { printDanglingComments } from "../../main/comments/print.js"; + +import { printTernaryOld } from "./ternary-old.js"; /** * @typedef {import("../../document/builders.js").Doc} Doc @@ -26,108 +34,39 @@ import { * @typedef {any} Options - Prettier options (TBD ...) */ -// If we have nested conditional expressions, we want to print them in JSX mode -// if there's at least one JSXElement somewhere in the tree. -// -// A conditional expression chain like this should be printed in normal mode, -// because there aren't JSXElements anywhere in it: -// -// isA ? "A" : isB ? "B" : isC ? "C" : "Unknown"; -// -// But a conditional expression chain like this should be printed in JSX mode, -// because there is a JSXElement in the last ConditionalExpression: -// -// isA ? "A" : isB ? "B" : isC ? "C" : Unknown; -// -// This type of ConditionalExpression chain is structured like this in the AST: -// -// ConditionalExpression { -// test: ..., -// consequent: ..., -// alternate: ConditionalExpression { -// test: ..., -// consequent: ..., -// alternate: ConditionalExpression { -// test: ..., -// consequent: ..., -// alternate: ..., -// } -// } -// } -function conditionalExpressionChainContainsJsx(node) { - // Given this code: - // - // // Using a ConditionalExpression as the consequent is uncommon, but should - // // be handled. - // A ? B : C ? D : E ? F ? G : H : I - // - // which has this AST: - // - // ConditionalExpression { - // test: Identifier(A), - // consequent: Identifier(B), - // alternate: ConditionalExpression { - // test: Identifier(C), - // consequent: Identifier(D), - // alternate: ConditionalExpression { - // test: Identifier(E), - // consequent: ConditionalExpression { - // test: Identifier(F), - // consequent: Identifier(G), - // alternate: Identifier(H), - // }, - // alternate: Identifier(I), - // } - // } - // } - // - // We don't care about whether each node was the test, consequent, or alternate - // We are only checking if there's any JSXElements inside. - const conditionalExpressions = [node]; - for (let index = 0; index < conditionalExpressions.length; index++) { - const conditionalExpression = conditionalExpressions[index]; - for (const property of ["test", "consequent", "alternate"]) { - const node = conditionalExpression[property]; - - if (isJsxElement(node)) { - return true; - } - - if (node.type === "ConditionalExpression") { - conditionalExpressions.push(node); - } - } - } - - return false; +// Break the closing paren to keep the chain right after it: +// (a +// ? b +// : c +// ).call() +function shouldBreakClosingParen(node, parent) { + return ( + (isMemberExpression(parent) || + (parent.type === "NGPipeExpression" && parent.left === node)) && + !parent.computed + ); } -function printTernaryTest(path, options, print) { - const { node } = path; - const isConditionalExpression = node.type === "ConditionalExpression"; - const alternateNodePropertyName = isConditionalExpression - ? "alternate" - : "falseType"; - - const { parent } = path; - - const printed = isConditionalExpression - ? print("test") - : [print("checkType"), " ", "extends", " ", print("extendsType")]; - /** - * a - * ? b - * : multiline - * test - * node - * ^^ align(2) - * ? d - * : e - */ - if (parent.type === node.type && parent[alternateNodePropertyName] === node) { - return align(2, printed); - } - return printed; +function hasMultilineBlockComments( + testNodes, + consequentNode, + alternateNode, + options, +) { + const comments = [ + ...testNodes.map((node) => getComments(node)), + getComments(consequentNode), + getComments(alternateNode), + ].flat(); + return comments.some( + (comment) => + isBlockComment(comment) && + hasNewlineInRange( + options.originalText, + locStart(comment), + locEnd(comment), + ), + ); } const ancestorNameMap = new Map([ @@ -138,6 +77,18 @@ const ancestorNameMap = new Map([ ["UnaryExpression", "argument"], ["YieldExpression", "argument"], ]); +/** + * Do we want to wrap the entire ternary in its own indent? + * Eg; for when instead of this: + * foo = cond ? + * cons + * : alt + * We want this: + * foo = + * cond ? + * cons + * : alt + */ function shouldExtraIndentForConditionalExpression(path) { const { node } = path; if (node.type !== "ConditionalExpression") { @@ -160,7 +111,6 @@ function shouldExtraIndentForConditionalExpression(path) { } // Reached chain root - if ( (node.type === "NewExpression" && node.callee === child) || (isBinaryCastExpression(node) && node.expression === child) @@ -180,6 +130,13 @@ function shouldExtraIndentForConditionalExpression(path) { return parent[ancestorNameMap.get(parent.type)] === child; } +const wrapInParens = (doc) => [ + ifBreak("("), + indent([softline, doc]), + softline, + ifBreak(")"), +]; + /** * The following is the shared logic for * ternary operators, namely ConditionalExpression, @@ -189,9 +146,16 @@ function shouldExtraIndentForConditionalExpression(path) { * @param {Function} print - Print function to call recursively * @returns {Doc} */ -function printTernary(path, options, print) { +function printTernary(path, options, print, args) { + if (!options.experimentalTernaries) { + return printTernaryOld(path, options, print); + } + const { node } = path; const isConditionalExpression = node.type === "ConditionalExpression"; + const isTSConditional = + node.type === "TSConditionalType" || + node.type === "ConditionalTypeAnnotation"; // For Flow. const consequentNodePropertyName = isConditionalExpression ? "consequent" : "trueType"; @@ -203,20 +167,22 @@ function printTernary(path, options, print) { : ["checkType", "extendsType"]; const consequentNode = node[consequentNodePropertyName]; const alternateNode = node[alternateNodePropertyName]; - const parts = []; - - // We print a ConditionalExpression in either "JSX mode" or "normal mode". - // See `tests/format/jsx/conditional-expression.js` for more info. - let jsxMode = false; + const testNodes = testNodePropertyNames.map((prop) => node[prop]); const { parent } = path; - const isParentTest = - parent.type === node.type && + + const isParentTernary = parent.type === node.type; + const isInTest = + isParentTernary && testNodePropertyNames.some((prop) => parent[prop] === node); - let forceNoIndent = parent.type === node.type && !isParentTest; + const isInAlternate = + isParentTernary && parent[alternateNodePropertyName] === node; + const isConsequentTernary = consequentNode.type === node.type; + const isAlternateTernary = alternateNode.type === node.type; + const isInChain = isAlternateTernary || isInAlternate; + const isBigTabs = options.tabWidth > 2 || options.useTabs; // Find the outermost non-ConditionalExpression parent, and the outermost - // ConditionalExpression parent. We'll use these to determine if we should - // print in JSX mode. + // ConditionalExpression parent. let currentParent; let previousParent; let i = 0; @@ -232,120 +198,228 @@ function printTernary(path, options, print) { ) ); const firstNonConditionalParent = currentParent || parent; - const lastConditionalParent = previousParent; - if ( + const isOnSameLineAsAssignment = + args && + args.assignmentLayout && + args.assignmentLayout !== "break-after-operator" && + (parent.type === "AssignmentExpression" || + parent.type === "VariableDeclarator" || + parent.type === "ClassProperty" || + parent.type === "PropertyDefinition" || + parent.type === "ClassPrivateProperty" || + parent.type === "ObjectProperty" || + parent.type === "Property"); + + const isOnSameLineAsReturn = + (parent.type === "ReturnStatement" || parent.type === "ThrowStatement") && + !(isConsequentTernary || isAlternateTernary); + + const isInJsx = isConditionalExpression && - (isJsxElement(node[testNodePropertyNames[0]]) || - isJsxElement(consequentNode) || - isJsxElement(alternateNode) || - conditionalExpressionChainContainsJsx(lastConditionalParent)) - ) { - jsxMode = true; - forceNoIndent = true; + firstNonConditionalParent.type === "JSXExpressionContainer" && + path.grandparent.type !== "JSXAttribute"; - // Even though they don't need parens, we wrap (almost) everything in - // parens when using ?: within JSX, because the parens are analogous to - // curly braces in an if statement. - const wrap = (doc) => [ - ifBreak("("), - indent([softline, doc]), - softline, - ifBreak(")"), - ]; + const shouldExtraIndent = shouldExtraIndentForConditionalExpression(path); + const breakClosingParen = shouldBreakClosingParen(node, parent); + const breakTSClosingParen = isTSConditional && pathNeedsParens(path, options); - // The only things we don't wrap are: - // * Nested conditional expressions in alternates - // * null - // * undefined - const isNil = (node) => - node.type === "NullLiteral" || - (node.type === "Literal" && node.value === null) || - (node.type === "Identifier" && node.name === "undefined"); - - parts.push( - " ? ", - isNil(consequentNode) - ? print(consequentNodePropertyName) - : wrap(print(consequentNodePropertyName)), - " : ", - alternateNode.type === node.type || isNil(alternateNode) - ? print(alternateNodePropertyName) - : wrap(print(alternateNodePropertyName)), - ); - } else { - // normal mode - const part = [ - line, - "? ", - consequentNode.type === node.type ? ifBreak("", "(") : "", - align(2, print(consequentNodePropertyName)), - consequentNode.type === node.type ? ifBreak("", ")") : "", - line, - ": ", - align(2, print(alternateNodePropertyName)), - ]; - parts.push( - parent.type !== node.type || - parent[alternateNodePropertyName] === node || - isParentTest - ? part - : options.useTabs - ? dedent(indent(part)) - : align(Math.max(0, options.tabWidth - 2), part), - ); - } + const fillTab = !isBigTabs + ? "" + : options.useTabs + ? "\t" + : " ".repeat(options.tabWidth - 1); // We want a whole chain of ConditionalExpressions to all // break if any of them break. That means we should only group around the // outer-most ConditionalExpression. - const shouldBreak = [ - consequentNodePropertyName, - alternateNodePropertyName, - ...testNodePropertyNames, - ].some((property) => - hasComment( - node[property], - (comment) => - isBlockComment(comment) && - hasNewlineInRange( - options.originalText, - locStart(comment), - locEnd(comment), - ), - ), - ); - const maybeGroup = (doc) => - parent === firstNonConditionalParent - ? group(doc, { shouldBreak }) - : shouldBreak - ? [doc, breakParent] - : doc; + const shouldBreak = + hasMultilineBlockComments( + testNodes, + consequentNode, + alternateNode, + options, + ) || + isConsequentTernary || + isAlternateTernary; - // Break the closing paren to keep the chain right after it: - // (a - // ? b - // : c - // ).call() - const breakClosingParen = - !jsxMode && - (isMemberExpression(parent) || - (parent.type === "NGPipeExpression" && parent.left === node)) && - !parent.computed; + // Enable this syntax when relevant, to avoid pushing a short consequent to the next line: + // + // const result = foo != null ? foo : ( + // some + long + expression + // ); + const tryToParenthesizeAlternate = + !isInChain && + !isParentTernary && + !isTSConditional && + (isInJsx + ? // In JSX, we want this with a null-consequent to mirror booleans: + // + // {!foo ? null : ( + // something.else() + // )} + // + // But not in the general case, where it's (subjectively) better to have things multiline. + consequentNode.type === "NullLiteral" || + (consequentNode.type === "Literal" && consequentNode.value === null) + : // Right now, we do this when: + // 1. The test is simple and, + // 2. The consequent is short. + // This heuristic could probably be refined over time, but felt right after moderate amounts of tinkering. + isLoneShortArgument(consequentNode, options) && + isSimpleExpressionByNodeCount(node.test, 3)); - const shouldExtraIndent = shouldExtraIndentForConditionalExpression(path); + const shouldGroupTestAndConsequent = + isInChain || + isInAlternate || + (isTSConditional && !isParentTernary) || + (isParentTernary && + isConditionalExpression && + isSimpleExpressionByNodeCount(node.test, 1)) || + tryToParenthesizeAlternate; - const result = maybeGroup([ - printTernaryTest(path, options, print), - forceNoIndent ? parts : indent(parts), - isConditionalExpression && breakClosingParen && !shouldExtraIndent - ? softline - : "", + const consequentComments = []; + if ( + !isConsequentTernary && + hasComment(consequentNode, CommentCheckFlags.Dangling) + ) { + path.call((childPath) => { + consequentComments.push( + printDanglingComments(childPath, options), + hardline, + ); + }, "consequent"); + } + const alternateComments = []; + if (hasComment(node.test, CommentCheckFlags.Dangling)) { + path.call((childPath) => { + alternateComments.push(printDanglingComments(childPath, options)); + }, "test"); + } + if ( + !isAlternateTernary && + hasComment(alternateNode, CommentCheckFlags.Dangling) + ) { + path.call((childPath) => { + alternateComments.push(printDanglingComments(childPath, options)); + }, "alternate"); + } + if (hasComment(node, CommentCheckFlags.Dangling)) { + alternateComments.push(printDanglingComments(path, options)); + } + + const testId = Symbol("test"); + const consequentId = Symbol("consequent"); + const testAndConsequentId = Symbol("test-and-consequent"); + + const printedTest = isConditionalExpression + ? [ + wrapInParens(print("test")), + node.test.type === "ConditionalExpression" ? breakParent : "", + ] + : [ + print("checkType"), + " ", + "extends", + " ", + node.extendsType.type === "TSConditionalType" || + node.extendsType.type === "ConditionalTypeAnnotation" || + node.extendsType.type === "TSMappedType" + ? print("extendsType") + : group(wrapInParens(print("extendsType"))), + ]; + const printedTestWithQuestionMark = group([printedTest, " ?"], { + id: testId, + }); + + const printedConsequent = print(consequentNodePropertyName); + const consequent = indent([ + isConsequentTernary || + (isInJsx && (isJsxElement(consequentNode) || isParentTernary || isInChain)) + ? hardline + : line, + consequentComments, + printedConsequent, ]); - return isParentTest || shouldExtraIndent - ? group([indent([softline, result]), softline]) - : result; + const printedTestAndConsequent = shouldGroupTestAndConsequent + ? group( + [ + printedTestWithQuestionMark, + // Avoid indenting consequent if it isn't a chain, even if the test breaks. + isInChain + ? consequent + : // If the test breaks, also break the consequent + ifBreak(consequent, group(consequent, { id: consequentId }), { + groupId: testId, + }), + ], + { id: testAndConsequentId }, + ) + : [printedTestWithQuestionMark, consequent]; + + const printedAlternate = print(alternateNodePropertyName); + const printedAlternateWithParens = tryToParenthesizeAlternate + ? ifBreak(printedAlternate, dedent(wrapInParens(printedAlternate)), { + groupId: testAndConsequentId, + }) + : printedAlternate; + + const parts = [ + printedTestAndConsequent, + + alternateComments.length > 0 + ? [indent([hardline, alternateComments]), hardline] + : isAlternateTernary + ? hardline + : tryToParenthesizeAlternate + ? ifBreak(line, " ", { groupId: testAndConsequentId }) + : line, + + ":", + + isAlternateTernary + ? " " + : !isBigTabs + ? " " + : shouldGroupTestAndConsequent + ? ifBreak( + fillTab, + ifBreak(isInChain || tryToParenthesizeAlternate ? " " : fillTab, " "), + { groupId: testAndConsequentId }, + ) + : ifBreak(fillTab, " "), + + isAlternateTernary + ? printedAlternateWithParens + : group([ + indent(printedAlternateWithParens), + isInJsx && !tryToParenthesizeAlternate ? softline : "", + ]), + + breakClosingParen && !shouldExtraIndent ? softline : "", + shouldBreak ? breakParent : "", + ]; + + const result = + isOnSameLineAsAssignment && !shouldBreak + ? // We try to preserve the case of a single-line ternary bumped to the line after assignment: + // + // const foo = + // cond ? result : otherwise; + // + // However, this sadly means that tests are always shunted to the next line in this case, + // which I'm ambivalent about but some people like keeping on the same line as the assignment. + group(indent([softline, group(parts)])) + : isOnSameLineAsAssignment || isOnSameLineAsReturn + ? group(indent(parts)) + : shouldExtraIndent || (isTSConditional && isInTest) + ? group([indent([softline, parts]), breakTSClosingParen ? softline : ""]) + : parent === firstNonConditionalParent + ? group(parts) + : parts; + + return result; } export { printTernary }; diff --git a/src/language-js/print/type-annotation.js b/src/language-js/print/type-annotation.js index 286d7d780..25e74a70e 100644 --- a/src/language-js/print/type-annotation.js +++ b/src/language-js/print/type-annotation.js @@ -161,6 +161,9 @@ function printUnionType(path, options, print) { // If there's a leading comment, the parent is doing the indentation const shouldIndent = parent.type !== "TypeParameterInstantiation" && + (parent.type !== "TSConditionalType" || !options.experimentalTernaries) && + (parent.type !== "ConditionalTypeAnnotation" || + !options.experimentalTernaries) && parent.type !== "TSTypeParameterInstantiation" && parent.type !== "GenericTypeAnnotation" && parent.type !== "TSTypeReference" && diff --git a/tests/format/flow/conditional-types-comments/__snapshots__/jsfmt.spec.js.snap b/tests/format/flow/conditional-types-comments/__snapshots__/jsfmt.spec.js.snap index 096c3d137..758dac9bd 100644 --- a/tests/format/flow/conditional-types-comments/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/flow/conditional-types-comments/__snapshots__/jsfmt.spec.js.snap @@ -94,8 +94,9 @@ c */? foo : bar : bar; =====================================output===================================== // @flow -type A = B extends T // comment - ? foo +type A = B extends T + ? // comment + foo : bar; type A = B extends test /* comment @@ -105,50 +106,56 @@ type A = B extends test /* comment ? foo : bar; -type T = test extends B /* comment +type T = test extends B + ? /* comment comment comment comment */ - ? foo + foo : bar; -type T = test extends B /* comment +type T = test extends B + ? /* comment comment comment comment */ - ? foo - : test extends B /* comment + foo + : test extends B + ? /* comment comment comment */ - ? foo + foo : bar; -type T = test extends B /* comment */ ? foo : bar; +type T = test extends B ? /* comment */ foo : bar; type T = test extends B - ? foo /* comment + ? foo + : /* comment comment comment comment */ - : bar; + bar; type T = test extends B - ? foo /* comment + ? foo + : /* comment comment comment comment */ - : test extends B - ? foo /* comment + test extends B + ? foo + : /* comment comment comment */ - : bar; + bar; -type T = test extends B ? foo /* comment */ : bar; +type T = test extends B ? foo : /* comment */ bar; type T = test extends B ? test extends B /* c diff --git a/tests/format/js/comments-closure-typecast/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/comments-closure-typecast/__snapshots__/jsfmt.spec.js.snap index 49dd59fe2..1014fd61c 100644 --- a/tests/format/js/comments-closure-typecast/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/js/comments-closure-typecast/__snapshots__/jsfmt.spec.js.snap @@ -427,6 +427,8 @@ printWidth: 80 const fooooba1 = /** @type {Array.} */ (fooobaarbazzItems || foo); const fooooba2 = /** @type {Array.} */ (fooobaarbazzItems + foo); const fooooba3 = /** @type {Array.} */ (fooobaarbazzItems || foo) ? foo : bar; +const fooooba4 = /** @type {Array.} */ + (fooobaarbazzItems || foo) ? foo : bar; =====================================output===================================== const fooooba1 = /** @type {Array.} */ ( @@ -440,6 +442,9 @@ const fooooba3 = /** @type {Array.} */ ( ) ? foo : bar; +const fooooba4 = + /** @type {Array.} */ + (fooobaarbazzItems || foo) ? foo : bar; ================================================================================ `; diff --git a/tests/format/js/comments-closure-typecast/issue-9358.js b/tests/format/js/comments-closure-typecast/issue-9358.js index d98246653..fcf881d56 100644 --- a/tests/format/js/comments-closure-typecast/issue-9358.js +++ b/tests/format/js/comments-closure-typecast/issue-9358.js @@ -1,3 +1,5 @@ const fooooba1 = /** @type {Array.} */ (fooobaarbazzItems || foo); const fooooba2 = /** @type {Array.} */ (fooobaarbazzItems + foo); const fooooba3 = /** @type {Array.} */ (fooobaarbazzItems || foo) ? foo : bar; +const fooooba4 = /** @type {Array.} */ + (fooobaarbazzItems || foo) ? foo : bar; diff --git a/tests/format/js/conditional/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/conditional/__snapshots__/jsfmt.spec.js.snap index c2a0de225..90675cc6f 100644 --- a/tests/format/js/conditional/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/js/conditional/__snapshots__/jsfmt.spec.js.snap @@ -1,5 +1,267 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`comments.js - {"experimentalTernaries":true} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +var inspect = 4 === util.inspect.length + ? // node <= 0.8.x + (function(v, colors) { + return util.inspect(v, void 0, void 0, colors); + }) + : // node > 0.8.x + (function(v, colors) { + return util.inspect(v, { colors: colors }); + }); + +var inspect = 4 === util.inspect.length + ? // node <= 0.8.x + (function(v, colors) { + return util.inspect(v, void 0, void 0, colors); + }) + : // node > 0.8.x + (function(v, colors) { + return util.inspect(v, { colors: colors }); + }); + +const extractTextPluginOptions = shouldUseRelativeAssetPaths + // Making sure that the publicPath goes back to to build folder. + ? { publicPath: Array(cssFilename.split('/').length).join('../') } : + {}; + +const extractTextPluginOptions2 = shouldUseRelativeAssetPaths + ? // Making sure that the publicPath goes back to to build folder. + { publicPath: Array(cssFilename.split("/").length).join("../") } + : {}; + +const extractTextPluginOptions3 = shouldUseRelativeAssetPaths // Making sure that the publicPath goes back to to build folder. + ? { publicPath: Array(cssFilename.split("/").length).join("../") } + : {}; + +const { configureStore } = process.env.NODE_ENV === "production" + ? require("./configureProdStore") // a + : require("./configureDevStore"); // b + +test /* comment + comment + comment +*/ + ? foo + : bar; + +test + ? /* comment + comment + comment + comment + */ + foo + : bar; + +test + ? /* comment + comment + comment + comment + */ + foo + : test + ? /* comment + comment + comment */ + foo + : bar; + +test + ? /* comment */ + foo + : bar; + +test + ? foo + : /* comment + comment + comment + comment + */ + bar; + +test + ? foo + : /* comment + comment + comment + comment + A newline will be added after this comment, unfortunately – but it can be removed manually, see next statement. + */ + test + ? foo + : /* comment + comment + comment + */ + bar; + + +// It is at least possible to delete the extra newline that was +// unfortunately added before the second condition above: +test ? + foo :/* comment + comment + comment + comment + */ +test ? + foo : + /* comment + comment + comment + */ + bar; + +test + ? foo + : /* comment */ + bar; + +test ? test /* c +c */? foo : bar : bar; + +=====================================output===================================== +var inspect = + 4 === util.inspect.length ? + // node <= 0.8.x + function (v, colors) { + return util.inspect(v, void 0, void 0, colors); + } + // node > 0.8.x + : function (v, colors) { + return util.inspect(v, { colors: colors }); + }; + +var inspect = + 4 === util.inspect.length ? + // node <= 0.8.x + function (v, colors) { + return util.inspect(v, void 0, void 0, colors); + } + // node > 0.8.x + : function (v, colors) { + return util.inspect(v, { colors: colors }); + }; + +const extractTextPluginOptions = + shouldUseRelativeAssetPaths ? + // Making sure that the publicPath goes back to to build folder. + { publicPath: Array(cssFilename.split("/").length).join("../") } + : {}; + +const extractTextPluginOptions2 = + shouldUseRelativeAssetPaths ? + // Making sure that the publicPath goes back to to build folder. + { publicPath: Array(cssFilename.split("/").length).join("../") } + : {}; + +const extractTextPluginOptions3 = + ( + shouldUseRelativeAssetPaths // Making sure that the publicPath goes back to to build folder. + ) ? + { publicPath: Array(cssFilename.split("/").length).join("../") } + : {}; + +const { configureStore } = + process.env.NODE_ENV === "production" ? + require("./configureProdStore") // a + : require("./configureDevStore"); // b + +( + test /* comment + comment + comment +*/ +) ? + foo +: bar; + +test ? + /* comment + comment + comment + comment + */ + foo +: bar; + +test ? + /* comment + comment + comment + comment + */ + foo +: test ? + /* comment + comment + comment */ + foo +: bar; + +test ? /* comment */ foo : bar; + +test ? foo + /* comment + comment + comment + comment + */ +: bar; + +test ? foo + /* comment + comment + comment + comment + A newline will be added after this comment, unfortunately – but it can be removed manually, see next statement. + */ +: test ? foo + /* comment + comment + comment + */ +: bar; + +// It is at least possible to delete the extra newline that was +// unfortunately added before the second condition above: +test ? + foo /* comment + comment + comment + comment + */ +: test ? foo + /* comment + comment + comment + */ +: bar; + +test ? foo : /* comment */ bar; + +test ? + ( + test /* c +c */ + ) ? + foo + : bar +: bar; + +================================================================================ +`; + exports[`comments.js format 1`] = ` ====================================options===================================== parsers: ["babel", "flow", "typescript"] @@ -256,6 +518,25 @@ c */ ================================================================================ `; +exports[`new-expression.js - {"experimentalTernaries":true} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +const testConsole = new TestConsole( + config.useStderr ? process.stderr : process.stdout +); + +=====================================output===================================== +const testConsole = new TestConsole( + config.useStderr ? process.stderr : process.stdout, +); + +================================================================================ +`; + exports[`new-expression.js format 1`] = ` ====================================options===================================== parsers: ["babel", "flow", "typescript"] @@ -274,6 +555,285 @@ const testConsole = new TestConsole( ================================================================================ `; +exports[`new-ternary-examples.js - {"experimentalTernaries":true} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +// from https://gist.github.com/rattrayalex/dacbf5838571a47f22d0ae1f8b960268 +// Input and output should match (for 2-space indent formatting). +// TypeScript is here: prettier/tests/format/typescript/conditional-types/new-ternary-spec.ts +// EXAMPLES +// mostly taken from https://github.com/prettier/prettier/issues/9561 + +const message = + i % 3 === 0 && i % 5 === 0 ? "fizzbuzz" + : i % 3 === 0 ? "fizz" + : i % 5 === 0 ? "buzz" + : String(i); + +const paymentMessageShort = + state == "success" ? "Payment completed successfully" + : state == "processing" ? "Payment processing" + : state == "invalid_cvc" ? "There was an issue with your CVC number" + : state == "invalid_expiry" ? "Expiry must be sometime in the past." + : "There was an issue with the payment. Please contact support."; + +const paymentMessageWithABreak = + state == "success" ? "Payment completed successfully" + : state == "processing" ? "Payment processing" + : state == "invalid_cvc" ? + "There was an issue with your CVC number, and you need to take a prompt action on it." + : state == "invalid_expiry" ? "Expiry must be sometime in the past." + : "There was an issue with the payment. Please contact support."; + +const typeofExample = + definition.encode ? + definition.encode( + typeof row[field] !== "undefined" ? row[field] + : typeof definition.default !== "undefined" ? definition.default + : null, + ) + : typeof row[field] !== "undefined" ? row[field] + : typeof definition.default !== "undefined" ? definition.default + : null; + +// (the following is semantically equivalent to the above, but written in a more-confusing style – it'd be hard to grok no matter the formatting) +const typeofExampleFlipped = + definition.encode ? + definition.encode( + typeof row[field] === "undefined" ? + typeof definition.default === "undefined" ? + null + : definition.default + : row[field], + ) + : typeof row[field] === "undefined" ? + typeof definition.default === "undefined" ? + null + : definition.default + : row[field]; + +// JSX Examples: + +const typicalLongConsequentWithNullAlternate = ( +
+ {children && !isEmptyChildren(children) ? + + : null} +
+); + +const reactRouterExampleJSX = ( +
+ {children && !isEmptyChildren(children) ? + children + : props.match ? + component ? + React.createElement(component, props) + : render ? + render(props) + : null + : null} +
+); + +const reactRouterExampleNonJSX = + children && !isEmptyChildren(children) ? children + : props.match ? + component ? React.createElement(component, props) + : render ? render(props) + : null + : null; + +inJSXExpressionContainer.withLongConditionals.example = ( +
+ {isACat() && (someReallyLongCondition || moreInThisLongCondition) ? + someReallyLargeExpression.toMakeMeowNoise().willCauseParens() + : someReallyLongCondition || moreInThisLongCondition ? + bark() + : someReallyLargeExpression.toMakeMeowNoise().willCauseParens()} +
+); + +inJSXExpressionContainer.withLoops.orBooleans.example = ( +
+ {items ? + items.map((item) => + item.display ? + + : , + ) + : null} + + {showTheStuff && + (foo ? + + : )} +
+); + +inJSXExpressionContainer.withNullConditional = ( +
+ {isACat() ? null : } + {isACat() && (someReallyLongCondition || moreInThisLongCondition) ? null : ( + + )} + {( + isACat() && + (someReallyLongCondition || + moreInThisLongCondition || + evenMoreInThisExtraLongConditional) + ) ? + null + : } +
+); + +=====================================output===================================== +// from https://gist.github.com/rattrayalex/dacbf5838571a47f22d0ae1f8b960268 +// Input and output should match (for 2-space indent formatting). +// TypeScript is here: prettier/tests/format/typescript/conditional-types/new-ternary-spec.ts +// EXAMPLES +// mostly taken from https://github.com/prettier/prettier/issues/9561 + +const message = + i % 3 === 0 && i % 5 === 0 ? "fizzbuzz" + : i % 3 === 0 ? "fizz" + : i % 5 === 0 ? "buzz" + : String(i); + +const paymentMessageShort = + state == "success" ? "Payment completed successfully" + : state == "processing" ? "Payment processing" + : state == "invalid_cvc" ? "There was an issue with your CVC number" + : state == "invalid_expiry" ? "Expiry must be sometime in the past." + : "There was an issue with the payment. Please contact support."; + +const paymentMessageWithABreak = + state == "success" ? "Payment completed successfully" + : state == "processing" ? "Payment processing" + : state == "invalid_cvc" ? + "There was an issue with your CVC number, and you need to take a prompt action on it." + : state == "invalid_expiry" ? "Expiry must be sometime in the past." + : "There was an issue with the payment. Please contact support."; + +const typeofExample = + definition.encode ? + definition.encode( + typeof row[field] !== "undefined" ? row[field] + : typeof definition.default !== "undefined" ? definition.default + : null, + ) + : typeof row[field] !== "undefined" ? row[field] + : typeof definition.default !== "undefined" ? definition.default + : null; + +// (the following is semantically equivalent to the above, but written in a more-confusing style – it'd be hard to grok no matter the formatting) +const typeofExampleFlipped = + definition.encode ? + definition.encode( + typeof row[field] === "undefined" ? + typeof definition.default === "undefined" ? + null + : definition.default + : row[field], + ) + : typeof row[field] === "undefined" ? + typeof definition.default === "undefined" ? + null + : definition.default + : row[field]; + +// JSX Examples: + +const typicalLongConsequentWithNullAlternate = ( +
+ {children && !isEmptyChildren(children) ? + + : null} +
+); + +const reactRouterExampleJSX = ( +
+ {children && !isEmptyChildren(children) ? + children + : props.match ? + component ? + React.createElement(component, props) + : render ? + render(props) + : null + : null} +
+); + +const reactRouterExampleNonJSX = + children && !isEmptyChildren(children) ? children + : props.match ? + component ? React.createElement(component, props) + : render ? render(props) + : null + : null; + +inJSXExpressionContainer.withLongConditionals.example = ( +
+ {isACat() && (someReallyLongCondition || moreInThisLongCondition) ? + someReallyLargeExpression.toMakeMeowNoise().willCauseParens() + : someReallyLongCondition || moreInThisLongCondition ? + bark() + : someReallyLargeExpression.toMakeMeowNoise().willCauseParens()} +
+); + +inJSXExpressionContainer.withLoops.orBooleans.example = ( +
+ {items ? + items.map((item) => + item.display ? + + : , + ) + : null} + + {showTheStuff && + (foo ? + + : )} +
+); + +inJSXExpressionContainer.withNullConditional = ( +
+ {isACat() ? null : } + {isACat() && (someReallyLongCondition || moreInThisLongCondition) ? null : ( + + )} + {( + isACat() && + (someReallyLongCondition || + moreInThisLongCondition || + evenMoreInThisExtraLongConditional) + ) ? + null + : } +
+); + +================================================================================ +`; + exports[`new-ternary-examples.js format 1`] = ` ====================================options===================================== parsers: ["babel", "flow", "typescript"] @@ -312,27 +872,28 @@ const typeofExample = definition.encode( typeof row[field] !== "undefined" ? row[field] : typeof definition.default !== "undefined" ? definition.default - : null + : null, ) : typeof row[field] !== "undefined" ? row[field] : typeof definition.default !== "undefined" ? definition.default - : null + : null; // (the following is semantically equivalent to the above, but written in a more-confusing style – it'd be hard to grok no matter the formatting) const typeofExampleFlipped = definition.encode ? definition.encode( typeof row[field] === "undefined" ? - typeof definition.default === "undefined" ? null + typeof definition.default === "undefined" ? + null : definition.default - : row[field] + : row[field], ) : typeof row[field] === "undefined" ? - typeof definition.default === "undefined" ? null + typeof definition.default === "undefined" ? + null : definition.default : row[field]; - // JSX Examples: const typicalLongConsequentWithNullAlternate = ( @@ -352,8 +913,10 @@ const reactRouterExampleJSX = ( {children && !isEmptyChildren(children) ? children : props.match ? - component ? React.createElement(component, props) - : render ? render(props) + component ? + React.createElement(component, props) + : render ? + render(props) : null : null} @@ -369,41 +932,28 @@ const reactRouterExampleNonJSX = inJSXExpressionContainer.withLongConditionals.example = (
- {( - isACat() && - (someReallyLongCondition || - moreInThisLongCondition) - ) ? - someReallyLargeExpression - .toMakeMeowNoise() - .willCauseParens() - : ( - someReallyLongCondition || - moreInThisLongCondition - ) ? + {isACat() && (someReallyLongCondition || moreInThisLongCondition) ? + someReallyLargeExpression.toMakeMeowNoise().willCauseParens() + : someReallyLongCondition || moreInThisLongCondition ? bark() - : someReallyLargeExpression - .toMakeMeowNoise() - .willCauseParens() - } + : someReallyLargeExpression.toMakeMeowNoise().willCauseParens()}
); inJSXExpressionContainer.withLoops.orBooleans.example = (
{items ? - items.map((item) => ( + items.map((item) => item.display ? - : - )) + : , + ) : null} - {showTheStuff && ( - foo ? + {showTheStuff && + (foo ? - : - )} + : )}
); @@ -413,9 +963,14 @@ inJSXExpressionContainer.withNullConditional = ( {isACat() && (someReallyLongCondition || moreInThisLongCondition) ? null : ( )} - {isACat() && (someReallyLongCondition || moreInThisLongCondition || evenMoreInThisExtraLongConditional) ? null : ( - - )} + {( + isACat() && + (someReallyLongCondition || + moreInThisLongCondition || + evenMoreInThisExtraLongConditional) + ) ? + null + : } ); @@ -574,8 +1129,9 @@ inJSXExpressionContainer.withNullConditional = ( ================================================================================ `; -exports[`new-ternary-spec.js format 1`] = ` +exports[`new-ternary-spec.js - {"experimentalTernaries":true} format 1`] = ` ====================================options===================================== +experimentalTernaries: true parsers: ["babel", "flow", "typescript"] printWidth: 80 | printWidth @@ -592,13 +1148,16 @@ const lessShort = isLoudReallyLoud() ? makeNoiseReallyLoudly.omgSoLoud() : silent(); // next, indent the consequent: -const andIndented = isLoudReallyReallyReallyReallyLoud() ? +const andIndented = + isLoudReallyReallyReallyReallyLoud() ? makeNoiseReallyReallyReallyReallyReallyLoudly.omgSoLoud() : silent(); // unless the consequent is short (less than ten characters long): -const shortSoCase = isLoudReallyReallyReallyReallyLoud() ? silent() - : makeNoiseReallyReallyReallyReallyReallyLoudly.omgSoLoud(); +const shortSoCase = + isLoudReallyReallyReallyReallyLoud() ? silent() : ( + makeNoiseReallyReallyReallyReallyReallyLoudly.omgSoLoud() + ); // if chained, always break and put after the = const chainedShort = @@ -668,7 +1227,8 @@ const mostlyShort = : "idk"; // long conditional, short consequent/alternate, not chained - do indent after ? -const longConditional = ( +const longConditional = + ( bifornCringerMoshedPerplexSawder === 2 / askTrovenaBeenaDependsRowans && glimseGlyphsHazardNoopsTieTie >= averredBathersBoxroomBuggyNurl().anodyneCondosMalateOverateRetinol() @@ -694,9 +1254,410 @@ definition.encode( : typeof definition.default !== "undefined" ? definition.default : null, typeof row[field] === "undefined" ? - typeof definition.default === "undefined" ? null + typeof definition.default === "undefined" ? + null : definition.default - : row[field] + : row[field], +); + +// In a return, break and over-indent: +const inReturn = () => { + if (short) { + return foo ? 1 : 2; + } + return typeof row[aVeryLongFieldName] !== "undefined" ? + row[aVeryLongFieldName] + : null; +}; + +// Remove current JSX Mode, and replace it with this algorithm: +// When a ternary's parent is a JSXExpressionContainer which is not in a JSXAttribute, +// force the consequent to break, +// and if the alternate breaks, +// add a newline before the closing curly brace. +// Special case when the consequent is \`null\`: +// do not add a line before or after it, +// and wrap the alternate in parens. + +const someJSX = ( +
+ Typical jsx case: + {showFoo ? + + : } + Nested, and with a non-jsx consequent is the same: + {component ? + React.createElement(component, props) + : render ? +
{render(props)}
+ :
Nothing is here
} + As is a non-jsx consequent: + {showTheJSXElement ? +
the stuff
+ : renderOtherStuff()} + But if the alternate breaks, add a newline before the closing curly brace: + {showTheThing || pleaseShowTheThing ? + + : + } + When the consequent is \`null\` and the alternate breaks, + hug it with parens to match boolean behavior: + {!thing ? null : ( + + )} +
+); + +ternaryWithJSXElements.hasNoSpecialCasing = + component ?
{React.createElement(component, props)}
+ : render ?
{render(props)}
+ :
Nothing is here
; + +jsxExpressionContainer.inJSXAttribute.hasNoSpecialCasing = ( + : } + withJSXBroken={ + isRed || isSomeOtherLongCondition.thatBreaksTheLine() ? + + : + } + /> +); + +=====================================output===================================== +// from https://gist.github.com/rattrayalex/dacbf5838571a47f22d0ae1f8b960268 +// Input and output should match (for 2-space indent formatting). +// TypeScript is here: prettier/tests/format/typescript/conditional-types/new-ternary-spec.ts + +// remain on one line if possible: +const short = isLoud() ? makeNoise() : silent(); + +// next, put everything after the = +const lessShort = + isLoudReallyLoud() ? makeNoiseReallyLoudly.omgSoLoud() : silent(); + +// next, indent the consequent: +const andIndented = + isLoudReallyReallyReallyReallyLoud() ? + makeNoiseReallyReallyReallyReallyReallyLoudly.omgSoLoud() + : silent(); + +// unless the consequent is short (less than ten characters long): +const shortSoCase = + isLoudReallyReallyReallyReallyLoud() ? silent() : ( + makeNoiseReallyReallyReallyReallyReallyLoudly.omgSoLoud() + ); + +// if chained, always break and put after the = +const chainedShort = + isCat() ? meow() + : isDog() ? bark() + : silent(); + +// when a consequent breaks in a chain: +const chainedWithLongConsequent = + isCat() ? + someReallyLargeExpression + .thatWouldCauseALineBreak() + .willCauseAnIndentButNotParens() + : isDog() ? bark() + : silent(); + +// nested ternary in consequent always breaks: +const chainedWithTernaryConsequent = + isCat() ? + aNestedCondition ? theResult() + : theAlternate() + : isDog() ? bark() + : silent(); + +// consequent and terminal alternate break: +const consequentAndTerminalAlternateBreak = + isCat() ? + someReallyLargeExpression + .thatWouldCauseALineBreak() + .willCauseAnIndentButNotParens() + : isDog() ? bark() + : someReallyLargeExpression + .thatWouldCauseALineBreak() + .willCauseAnIndentButNotParens(); + +// multiline conditions and consequents/alternates: +const multilineConditionsConsequentsAndAlternates = + ( + isAnAdorableKittyCat() && + (someReallyLongCondition || moreInThisLongCondition) + ) ? + someReallyLargeExpression + .thatWouldCauseALineBreak() + .willCauseAnIndentButNotParens() + : ( + isNotAnAdorableKittyCat() && + (someReallyLongCondition || moreInThisLongCondition) + ) ? + bark() + : shortCondition() ? shortConsequent() + : someReallyLargeExpression + .thatWouldCauseALineBreak() + .willCauseAnIndentButNotParens(); + +// illustrating case of mostly short conditionals +const mostlyShort = + x === 1 ? "one" + : x === 2 ? "two" + : x === 3 ? "three" + : ( + x === 5 && + y === 7 && + someOtherThing.thatIsSoLong.thatItBreaksTheTestCondition() + ) ? + "four" + : x === 6 ? "six" + : "idk"; + +// long conditional, short consequent/alternate, not chained - do indent after ? +const longConditional = + ( + bifornCringerMoshedPerplexSawder === 2 / askTrovenaBeenaDependsRowans && + glimseGlyphsHazardNoopsTieTie >= + averredBathersBoxroomBuggyNurl().anodyneCondosMalateOverateRetinol() + ) ? + "foo" + : "bar"; + +// long conditional, short consequent/alternate, chained +// (break on short consequents iff in chained ternary and its conditional broke) +const longConditionalChained = + ( + bifornCringerMoshedPerplexSawder === 2 / askTrovenaBeenaDependsRowans && + glimseGlyphsHazardNoopsTieTie >= + averredBathersBoxroomBuggyNurl().anodyneCondosMalateOverateRetinol() + ) ? + "foo" + : anotherCondition ? "bar" + : "baz"; + +// As a function parameter, don't add an extra indent: +definition.encode( + typeof row[field] !== "undefined" ? row[field] + : typeof definition.default !== "undefined" ? definition.default + : null, + typeof row[field] === "undefined" ? + typeof definition.default === "undefined" ? + null + : definition.default + : row[field], +); + +// In a return, break and over-indent: +const inReturn = () => { + if (short) { + return foo ? 1 : 2; + } + return typeof row[aVeryLongFieldName] !== "undefined" ? + row[aVeryLongFieldName] + : null; +}; + +// Remove current JSX Mode, and replace it with this algorithm: +// When a ternary's parent is a JSXExpressionContainer which is not in a JSXAttribute, +// force the consequent to break, +// and if the alternate breaks, +// add a newline before the closing curly brace. +// Special case when the consequent is \`null\`: +// do not add a line before or after it, +// and wrap the alternate in parens. + +const someJSX = ( +
+ Typical jsx case: + {showFoo ? + + : } + Nested, and with a non-jsx consequent is the same: + {component ? + React.createElement(component, props) + : render ? +
{render(props)}
+ :
Nothing is here
} + As is a non-jsx consequent: + {showTheJSXElement ? +
the stuff
+ : renderOtherStuff()} + But if the alternate breaks, add a newline before the closing curly brace: + {showTheThing || pleaseShowTheThing ? + + : + } + When the consequent is \`null\` and the alternate breaks, hug it with parens + to match boolean behavior: + {!thing ? null : ( + + )} +
+); + +ternaryWithJSXElements.hasNoSpecialCasing = + component ?
{React.createElement(component, props)}
+ : render ?
{render(props)}
+ :
Nothing is here
; + +jsxExpressionContainer.inJSXAttribute.hasNoSpecialCasing = ( + : } + withJSXBroken={ + isRed || isSomeOtherLongCondition.thatBreaksTheLine() ? + + : + } + /> +); + +================================================================================ +`; + +exports[`new-ternary-spec.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +// from https://gist.github.com/rattrayalex/dacbf5838571a47f22d0ae1f8b960268 +// Input and output should match (for 2-space indent formatting). +// TypeScript is here: prettier/tests/format/typescript/conditional-types/new-ternary-spec.ts + +// remain on one line if possible: +const short = isLoud() ? makeNoise() : silent(); + +// next, put everything after the = +const lessShort = + isLoudReallyLoud() ? makeNoiseReallyLoudly.omgSoLoud() : silent(); + +// next, indent the consequent: +const andIndented = + isLoudReallyReallyReallyReallyLoud() ? + makeNoiseReallyReallyReallyReallyReallyLoudly.omgSoLoud() + : silent(); + +// unless the consequent is short (less than ten characters long): +const shortSoCase = + isLoudReallyReallyReallyReallyLoud() ? silent() : ( + makeNoiseReallyReallyReallyReallyReallyLoudly.omgSoLoud() + ); + +// if chained, always break and put after the = +const chainedShort = + isCat() ? meow() + : isDog() ? bark() + : silent(); + +// when a consequent breaks in a chain: +const chainedWithLongConsequent = + isCat() ? + someReallyLargeExpression + .thatWouldCauseALineBreak() + .willCauseAnIndentButNotParens() + : isDog() ? bark() + : silent(); + +// nested ternary in consequent always breaks: +const chainedWithTernaryConsequent = + isCat() ? + aNestedCondition ? theResult() + : theAlternate() + : isDog() ? bark() + : silent(); + +// consequent and terminal alternate break: +const consequentAndTerminalAlternateBreak = + isCat() ? + someReallyLargeExpression + .thatWouldCauseALineBreak() + .willCauseAnIndentButNotParens() + : isDog() ? bark() + : someReallyLargeExpression + .thatWouldCauseALineBreak() + .willCauseAnIndentButNotParens(); + +// multiline conditions and consequents/alternates: +const multilineConditionsConsequentsAndAlternates = + ( + isAnAdorableKittyCat() && + (someReallyLongCondition || moreInThisLongCondition) + ) ? + someReallyLargeExpression + .thatWouldCauseALineBreak() + .willCauseAnIndentButNotParens() + : ( + isNotAnAdorableKittyCat() && + (someReallyLongCondition || moreInThisLongCondition) + ) ? + bark() + : shortCondition() ? shortConsequent() + : someReallyLargeExpression + .thatWouldCauseALineBreak() + .willCauseAnIndentButNotParens(); + +// illustrating case of mostly short conditionals +const mostlyShort = + x === 1 ? "one" + : x === 2 ? "two" + : x === 3 ? "three" + : ( + x === 5 && + y === 7 && + someOtherThing.thatIsSoLong.thatItBreaksTheTestCondition() + ) ? + "four" + : x === 6 ? "six" + : "idk"; + +// long conditional, short consequent/alternate, not chained - do indent after ? +const longConditional = + ( + bifornCringerMoshedPerplexSawder === 2 / askTrovenaBeenaDependsRowans && + glimseGlyphsHazardNoopsTieTie >= + averredBathersBoxroomBuggyNurl().anodyneCondosMalateOverateRetinol() + ) ? + "foo" + : "bar"; + +// long conditional, short consequent/alternate, chained +// (break on short consequents iff in chained ternary and its conditional broke) +const longConditionalChained = + ( + bifornCringerMoshedPerplexSawder === 2 / askTrovenaBeenaDependsRowans && + glimseGlyphsHazardNoopsTieTie >= + averredBathersBoxroomBuggyNurl().anodyneCondosMalateOverateRetinol() + ) ? + "foo" + : anotherCondition ? "bar" + : "baz"; + +// As a function parameter, don't add an extra indent: +definition.encode( + typeof row[field] !== "undefined" ? row[field] + : typeof definition.default !== "undefined" ? definition.default + : null, + typeof row[field] === "undefined" ? + typeof definition.default === "undefined" ? + null + : definition.default + : row[field], ); // In a return, break and over-indent: @@ -967,6 +1928,25 @@ jsxExpressionContainer.inJSXAttribute.hasNoSpecialCasing = ( ================================================================================ `; +exports[`no-confusing-arrow.js - {"experimentalTernaries":true} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +// no-confusing-arrow +var x = a => 1 ? 2 : 3; +var x = a <= 1 ? 2 : 3; + +=====================================output===================================== +// no-confusing-arrow +var x = (a) => (1 ? 2 : 3); +var x = a <= 1 ? 2 : 3; + +================================================================================ +`; + exports[`no-confusing-arrow.js format 1`] = ` ====================================options===================================== parsers: ["babel", "flow", "typescript"] @@ -985,6 +1965,342 @@ var x = a <= 1 ? 2 : 3; ================================================================================ `; +exports[`postfix-ternary-regressions.js - {"experimentalTernaries":true} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== + +// concatened string in consequent should be visually distinguishable from alternate +// … or maybe this is okay, because the colon is enough? +const avatar = has_ordered ? + 'https://marmelab.com/posters/avatar/longer-word-that-breaks-consequent-' + + numberOfCustomers + + '.jpeg' + : undefined; + +// Similarly, in the alternate: +const redirectUrl = pathName ? + pathName + : nextPathName + nextSearch || + defaultAuthParams.afterLoginUrl.makeThisLongerSoItBreaks; + +// And another, more pathological case of the above: +const isEmpty = obj => + obj instanceof Date ? + false + : obj === '' || + obj === null || + obj === undefined || + obj === somethingThatIsLonger || + shallowEqual(obj, {}); + + +// Again, this case is a bit hard to distinguish the alternate. +const eventsFromOrders = + orderIds && orders ? + orderIds.map(id => ({ + type: 'order', + date: orders[id].date, + data: orders[id], + })) + : []; + +// Kinda weird to have dedents to the level of "return" in a function. +function foo() { + return !linkTo ? + false + : typeof linkTo === 'function' + ? linkTo(record, reference) + : linkToRecord(rootPath, sourceId, linkTo_as_string); +} +function foo2() { + return React.isValidElement(emptyText) + ? React.cloneElement(emptyText) + : emptyText === '' + ? ' ' // em space, forces the display of an empty line of normal height + : translate(emptyText, { _: emptyText }); +} + +// Function call ideally wouldnt break break +const matchingReferencesError = isMatchingReferencesError( + matchingReferences +) + ? translate(matchingReferences.error, { + _: matchingReferences.error, + }) + : null; + +// This one is kinda confusing any way you slice it… +const obj = { + error: + matchingReferencesError && + (!input.value || + (input.value && + selectedReferencesDataStatus === REFERENCES_STATUS_EMPTY)) + ? translate('ra.input.references.all_missing', { + _: 'ra.input.references.all_missing', + }) + : null, +} + +// I think we should indent after the inner || on this, and do better wtih the parens around the && +const obj2 = { + warning: + matchingReferencesError || + (input.value && selectedReferencesDataStatus !== REFERENCES_STATUS_READY) + ? matchingReferencesError || + translate('ra.input.references.many_missing', { + _: 'ra.input.references.many_missing', + }) + : null, +} + +// The boolean conditions in the test should look cohesive. +const selectedReferencesDataStatus = + !isEmpty(value) && typeof value === 'string' && !pattern.test(value) + ? getMessage(message, { pattern }, value, values) + : undefined + + +// Would be nice if these two nested ternaries didn't look like a single one. +resolveRedirectTo( + redirectTo, + basePath, + payload + ? payload.id || (payload.data ? payload.data.id : null) + : requestPayload + ? requestPayload.id + : null, + payload && payload.data + ? payload.data + : requestPayload && requestPayload.data + ? requestPayload.data + : null +) + +const delayedDataProvider = new Proxy(restProvider, { + get: (target, name, self) => + name === 'then' ? // as we await for the dataProvider, JS calls then on it. We must trap that call or else the dataProvider will be called with the then method + self + : ( + (resource, params) => + new Promise(resolve => + setTimeout( + () => + resolve( + restProvider[name](resource, params) + ), + 500 + ) + ) + ), +}); + +function foo4() { + return !match || match.length < 5 ? line : ( + match[1] + match[2] + match[3] + match[4] + ) +} + +function foo5() { + return !match || match.length < 5 ? foo(line) : ( + match[1] + match[2] + match[3] + match[4] + ) +} + +function foo6() { + return !match || match.length < 5 ? linethatisverylongandbreaksthelinehooray : ( + match[1] + match[2] + match[3] + match[4] + ) +} + +function foo7() { + return !match || match.length < 5 ? linethatisverylongandbreaksthelinehoorayjustabitlonger : ( + match[1] + match[2] + match[3] + match[4] + ) +} + +const badComments = + schema.model ? schema + // If model is an array where the items schema is a referred model then we need to use that + : schema.type === 'array' ? schema.items + : schema; + +const anotherBadComment = + refModel ? + // If we're in a shared params file then reference the model name directly + inSharedParamsFile ? refModel + // If we're not in a shared params file then reference the in-file type + : classRef() + // We don't have a model name, use the in-file name + : classRef() + +=====================================output===================================== +// concatened string in consequent should be visually distinguishable from alternate +// … or maybe this is okay, because the colon is enough? +const avatar = + has_ordered ? + "https://marmelab.com/posters/avatar/longer-word-that-breaks-consequent-" + + numberOfCustomers + + ".jpeg" + : undefined; + +// Similarly, in the alternate: +const redirectUrl = + pathName ? pathName : ( + nextPathName + nextSearch || + defaultAuthParams.afterLoginUrl.makeThisLongerSoItBreaks + ); + +// And another, more pathological case of the above: +const isEmpty = (obj) => + obj instanceof Date ? false : ( + obj === "" || + obj === null || + obj === undefined || + obj === somethingThatIsLonger || + shallowEqual(obj, {}) + ); + +// Again, this case is a bit hard to distinguish the alternate. +const eventsFromOrders = + orderIds && orders ? + orderIds.map((id) => ({ + type: "order", + date: orders[id].date, + data: orders[id], + })) + : []; + +// Kinda weird to have dedents to the level of "return" in a function. +function foo() { + return ( + !linkTo ? false + : typeof linkTo === "function" ? linkTo(record, reference) + : linkToRecord(rootPath, sourceId, linkTo_as_string) + ); +} +function foo2() { + return ( + React.isValidElement(emptyText) ? React.cloneElement(emptyText) + : emptyText === "" ? + " " // em space, forces the display of an empty line of normal height + : translate(emptyText, { _: emptyText }) + ); +} + +// Function call ideally wouldnt break break +const matchingReferencesError = + isMatchingReferencesError(matchingReferences) ? + translate(matchingReferences.error, { + _: matchingReferences.error, + }) + : null; + +// This one is kinda confusing any way you slice it… +const obj = { + error: + ( + matchingReferencesError && + (!input.value || + (input.value && + selectedReferencesDataStatus === REFERENCES_STATUS_EMPTY)) + ) ? + translate("ra.input.references.all_missing", { + _: "ra.input.references.all_missing", + }) + : null, +}; + +// I think we should indent after the inner || on this, and do better wtih the parens around the && +const obj2 = { + warning: + ( + matchingReferencesError || + (input.value && selectedReferencesDataStatus !== REFERENCES_STATUS_READY) + ) ? + matchingReferencesError || + translate("ra.input.references.many_missing", { + _: "ra.input.references.many_missing", + }) + : null, +}; + +// The boolean conditions in the test should look cohesive. +const selectedReferencesDataStatus = + !isEmpty(value) && typeof value === "string" && !pattern.test(value) ? + getMessage(message, { pattern }, value, values) + : undefined; + +// Would be nice if these two nested ternaries didn't look like a single one. +resolveRedirectTo( + redirectTo, + basePath, + payload ? payload.id || (payload.data ? payload.data.id : null) + : requestPayload ? requestPayload.id + : null, + payload && payload.data ? payload.data + : requestPayload && requestPayload.data ? requestPayload.data + : null, +); + +const delayedDataProvider = new Proxy(restProvider, { + get: (target, name, self) => + ( + name === "then" // as we await for the dataProvider, JS calls then on it. We must trap that call or else the dataProvider will be called with the then method + ) ? + self + : (resource, params) => + new Promise((resolve) => + setTimeout(() => resolve(restProvider[name](resource, params)), 500), + ), +}); + +function foo4() { + return !match || match.length < 5 ? + line + : match[1] + match[2] + match[3] + match[4]; +} + +function foo5() { + return !match || match.length < 5 ? + foo(line) + : match[1] + match[2] + match[3] + match[4]; +} + +function foo6() { + return !match || match.length < 5 ? + linethatisverylongandbreaksthelinehooray + : match[1] + match[2] + match[3] + match[4]; +} + +function foo7() { + return !match || match.length < 5 ? + linethatisverylongandbreaksthelinehoorayjustabitlonger + : match[1] + match[2] + match[3] + match[4]; +} + +const badComments = + schema.model ? schema + // If model is an array where the items schema is a referred model then we need to use that + : schema.type === "array" ? schema.items + : schema; + +const anotherBadComment = + refModel ? + // If we're in a shared params file then reference the model name directly + inSharedParamsFile ? refModel + // If we're not in a shared params file then reference the in-file type + : classRef() + // We don't have a model name, use the in-file name + : classRef(); + +================================================================================ +`; + exports[`postfix-ternary-regressions.js format 1`] = ` ====================================options===================================== parsers: ["babel", "flow", "typescript"] @@ -1142,6 +2458,21 @@ function foo7() { ) } +const badComments = + schema.model ? schema + // If model is an array where the items schema is a referred model then we need to use that + : schema.type === 'array' ? schema.items + : schema; + +const anotherBadComment = + refModel ? + // If we're in a shared params file then reference the model name directly + inSharedParamsFile ? refModel + // If we're not in a shared params file then reference the in-file type + : classRef() + // We don't have a model name, use the in-file name + : classRef() + =====================================output===================================== // concatened string in consequent should be visually distinguishable from alternate // … or maybe this is okay, because the colon is enough? @@ -1283,5 +2614,21 @@ function foo7() { : match[1] + match[2] + match[3] + match[4]; } +const badComments = schema.model + ? schema + : // If model is an array where the items schema is a referred model then we need to use that + schema.type === "array" + ? schema.items + : schema; + +const anotherBadComment = refModel + ? // If we're in a shared params file then reference the model name directly + inSharedParamsFile + ? refModel + : // If we're not in a shared params file then reference the in-file type + classRef() + : // We don't have a model name, use the in-file name + classRef(); + ================================================================================ `; diff --git a/tests/format/js/conditional/jsfmt.spec.js b/tests/format/js/conditional/jsfmt.spec.js index 628d261a5..2f8bbb8c5 100644 --- a/tests/format/js/conditional/jsfmt.spec.js +++ b/tests/format/js/conditional/jsfmt.spec.js @@ -1 +1,4 @@ run_spec(import.meta, ["babel", "flow", "typescript"]); +run_spec(import.meta, ["babel", "flow", "typescript"], { + experimentalTernaries: true, +}); diff --git a/tests/format/js/conditional/new-ternary-examples.js b/tests/format/js/conditional/new-ternary-examples.js index 8c319faf9..599e8df1b 100644 --- a/tests/format/js/conditional/new-ternary-examples.js +++ b/tests/format/js/conditional/new-ternary-examples.js @@ -30,27 +30,28 @@ const typeofExample = definition.encode( typeof row[field] !== "undefined" ? row[field] : typeof definition.default !== "undefined" ? definition.default - : null + : null, ) : typeof row[field] !== "undefined" ? row[field] : typeof definition.default !== "undefined" ? definition.default - : null + : null; // (the following is semantically equivalent to the above, but written in a more-confusing style – it'd be hard to grok no matter the formatting) const typeofExampleFlipped = definition.encode ? definition.encode( typeof row[field] === "undefined" ? - typeof definition.default === "undefined" ? null + typeof definition.default === "undefined" ? + null : definition.default - : row[field] + : row[field], ) : typeof row[field] === "undefined" ? - typeof definition.default === "undefined" ? null + typeof definition.default === "undefined" ? + null : definition.default : row[field]; - // JSX Examples: const typicalLongConsequentWithNullAlternate = ( @@ -70,8 +71,10 @@ const reactRouterExampleJSX = ( {children && !isEmptyChildren(children) ? children : props.match ? - component ? React.createElement(component, props) - : render ? render(props) + component ? + React.createElement(component, props) + : render ? + render(props) : null : null} @@ -87,41 +90,28 @@ const reactRouterExampleNonJSX = inJSXExpressionContainer.withLongConditionals.example = (
- {( - isACat() && - (someReallyLongCondition || - moreInThisLongCondition) - ) ? - someReallyLargeExpression - .toMakeMeowNoise() - .willCauseParens() - : ( - someReallyLongCondition || - moreInThisLongCondition - ) ? + {isACat() && (someReallyLongCondition || moreInThisLongCondition) ? + someReallyLargeExpression.toMakeMeowNoise().willCauseParens() + : someReallyLongCondition || moreInThisLongCondition ? bark() - : someReallyLargeExpression - .toMakeMeowNoise() - .willCauseParens() - } + : someReallyLargeExpression.toMakeMeowNoise().willCauseParens()}
); inJSXExpressionContainer.withLoops.orBooleans.example = (
{items ? - items.map((item) => ( + items.map((item) => item.display ? - : - )) + : , + ) : null} - {showTheStuff && ( - foo ? + {showTheStuff && + (foo ? - : - )} + : )}
); @@ -131,8 +121,13 @@ inJSXExpressionContainer.withNullConditional = ( {isACat() && (someReallyLongCondition || moreInThisLongCondition) ? null : ( )} - {isACat() && (someReallyLongCondition || moreInThisLongCondition || evenMoreInThisExtraLongConditional) ? null : ( - - )} + {( + isACat() && + (someReallyLongCondition || + moreInThisLongCondition || + evenMoreInThisExtraLongConditional) + ) ? + null + : } ); diff --git a/tests/format/js/conditional/new-ternary-spec.js b/tests/format/js/conditional/new-ternary-spec.js index 74e7a362a..4d41dd6f7 100644 --- a/tests/format/js/conditional/new-ternary-spec.js +++ b/tests/format/js/conditional/new-ternary-spec.js @@ -10,13 +10,16 @@ const lessShort = isLoudReallyLoud() ? makeNoiseReallyLoudly.omgSoLoud() : silent(); // next, indent the consequent: -const andIndented = isLoudReallyReallyReallyReallyLoud() ? +const andIndented = + isLoudReallyReallyReallyReallyLoud() ? makeNoiseReallyReallyReallyReallyReallyLoudly.omgSoLoud() : silent(); // unless the consequent is short (less than ten characters long): -const shortSoCase = isLoudReallyReallyReallyReallyLoud() ? silent() - : makeNoiseReallyReallyReallyReallyReallyLoudly.omgSoLoud(); +const shortSoCase = + isLoudReallyReallyReallyReallyLoud() ? silent() : ( + makeNoiseReallyReallyReallyReallyReallyLoudly.omgSoLoud() + ); // if chained, always break and put after the = const chainedShort = @@ -86,7 +89,8 @@ const mostlyShort = : "idk"; // long conditional, short consequent/alternate, not chained - do indent after ? -const longConditional = ( +const longConditional = + ( bifornCringerMoshedPerplexSawder === 2 / askTrovenaBeenaDependsRowans && glimseGlyphsHazardNoopsTieTie >= averredBathersBoxroomBuggyNurl().anodyneCondosMalateOverateRetinol() @@ -112,9 +116,10 @@ definition.encode( : typeof definition.default !== "undefined" ? definition.default : null, typeof row[field] === "undefined" ? - typeof definition.default === "undefined" ? null + typeof definition.default === "undefined" ? + null : definition.default - : row[field] + : row[field], ); // In a return, break and over-indent: diff --git a/tests/format/js/conditional/postfix-ternary-regressions.js b/tests/format/js/conditional/postfix-ternary-regressions.js index 3d1f9ce7e..f21af9133 100644 --- a/tests/format/js/conditional/postfix-ternary-regressions.js +++ b/tests/format/js/conditional/postfix-ternary-regressions.js @@ -148,3 +148,18 @@ function foo7() { match[1] + match[2] + match[3] + match[4] ) } + +const badComments = + schema.model ? schema + // If model is an array where the items schema is a referred model then we need to use that + : schema.type === 'array' ? schema.items + : schema; + +const anotherBadComment = + refModel ? + // If we're in a shared params file then reference the model name directly + inSharedParamsFile ? refModel + // If we're not in a shared params file then reference the in-file type + : classRef() + // We don't have a model name, use the in-file name + : classRef() diff --git a/tests/format/js/ternaries/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/ternaries/__snapshots__/jsfmt.spec.js.snap index d38220788..af420d62d 100644 --- a/tests/format/js/ternaries/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/js/ternaries/__snapshots__/jsfmt.spec.js.snap @@ -1,5 +1,193 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`binary.js - {"experimentalTernaries":true,"tabWidth":4} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 + | printWidth +=====================================input====================================== +const funnelSnapshotCard = (report === MY_OVERVIEW && + !ReportGK.xar_metrics_active_capitol_v2) || + (report === COMPANY_OVERVIEW && + !ReportGK.xar_metrics_active_capitol_v2_company_metrics) + ? + : null; + +room = room.map((row, rowIndex) => ( + row.map((col, colIndex) => ( + (rowIndex === 0 || colIndex === 0 || rowIndex === height || colIndex === width) ? 1 : 0 + )) +)) + +=====================================output===================================== +const funnelSnapshotCard = + ( + (report === MY_OVERVIEW && !ReportGK.xar_metrics_active_capitol_v2) || + (report === COMPANY_OVERVIEW && + !ReportGK.xar_metrics_active_capitol_v2_company_metrics) + ) ? + + : null; + +room = room.map((row, rowIndex) => + row.map((col, colIndex) => + ( + rowIndex === 0 || + colIndex === 0 || + rowIndex === height || + colIndex === width + ) ? + 1 + : 0, + ), +); + +================================================================================ +`; + +exports[`binary.js - {"experimentalTernaries":true,"useTabs":true,"tabWidth":4} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 +useTabs: true + | printWidth +=====================================input====================================== +const funnelSnapshotCard = (report === MY_OVERVIEW && + !ReportGK.xar_metrics_active_capitol_v2) || + (report === COMPANY_OVERVIEW && + !ReportGK.xar_metrics_active_capitol_v2_company_metrics) + ? + : null; + +room = room.map((row, rowIndex) => ( + row.map((col, colIndex) => ( + (rowIndex === 0 || colIndex === 0 || rowIndex === height || colIndex === width) ? 1 : 0 + )) +)) + +=====================================output===================================== +const funnelSnapshotCard = + ( + (report === MY_OVERVIEW && !ReportGK.xar_metrics_active_capitol_v2) || + (report === COMPANY_OVERVIEW && + !ReportGK.xar_metrics_active_capitol_v2_company_metrics) + ) ? + + : null; + +room = room.map((row, rowIndex) => + row.map((col, colIndex) => + ( + rowIndex === 0 || + colIndex === 0 || + rowIndex === height || + colIndex === width + ) ? + 1 + : 0, + ), +); + +================================================================================ +`; + +exports[`binary.js - {"experimentalTernaries":true,"useTabs":true} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +useTabs: true + | printWidth +=====================================input====================================== +const funnelSnapshotCard = (report === MY_OVERVIEW && + !ReportGK.xar_metrics_active_capitol_v2) || + (report === COMPANY_OVERVIEW && + !ReportGK.xar_metrics_active_capitol_v2_company_metrics) + ? + : null; + +room = room.map((row, rowIndex) => ( + row.map((col, colIndex) => ( + (rowIndex === 0 || colIndex === 0 || rowIndex === height || colIndex === width) ? 1 : 0 + )) +)) + +=====================================output===================================== +const funnelSnapshotCard = + ( + (report === MY_OVERVIEW && !ReportGK.xar_metrics_active_capitol_v2) || + (report === COMPANY_OVERVIEW && + !ReportGK.xar_metrics_active_capitol_v2_company_metrics) + ) ? + + : null; + +room = room.map((row, rowIndex) => + row.map((col, colIndex) => + ( + rowIndex === 0 || + colIndex === 0 || + rowIndex === height || + colIndex === width + ) ? + 1 + : 0, + ), +); + +================================================================================ +`; + +exports[`binary.js - {"experimentalTernaries":true} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +const funnelSnapshotCard = (report === MY_OVERVIEW && + !ReportGK.xar_metrics_active_capitol_v2) || + (report === COMPANY_OVERVIEW && + !ReportGK.xar_metrics_active_capitol_v2_company_metrics) + ? + : null; + +room = room.map((row, rowIndex) => ( + row.map((col, colIndex) => ( + (rowIndex === 0 || colIndex === 0 || rowIndex === height || colIndex === width) ? 1 : 0 + )) +)) + +=====================================output===================================== +const funnelSnapshotCard = + ( + (report === MY_OVERVIEW && !ReportGK.xar_metrics_active_capitol_v2) || + (report === COMPANY_OVERVIEW && + !ReportGK.xar_metrics_active_capitol_v2_company_metrics) + ) ? + + : null; + +room = room.map((row, rowIndex) => + row.map((col, colIndex) => + ( + rowIndex === 0 || + colIndex === 0 || + rowIndex === height || + colIndex === width + ) ? + 1 + : 0, + ), +); + +================================================================================ +`; + exports[`binary.js - {"tabWidth":4} format 1`] = ` ====================================options===================================== parsers: ["babel", "flow", "typescript"] @@ -168,6 +356,142 @@ room = room.map((row, rowIndex) => ================================================================================ `; +exports[`func-call.js - {"experimentalTernaries":true,"tabWidth":4} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 + | printWidth +=====================================input====================================== +fn( + bifornCringerMoshedPerplexSawder, + askTrovenaBeenaDependsRowans, + glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && + anodyneCondosMalateOverateRetinol + ? annularCooeedSplicesWalksWayWay + : kochabCooieGameOnOboleUnweave +); +// TODO(rattrayalex): try to indent consequent/alternate here. + +=====================================output===================================== +fn( + bifornCringerMoshedPerplexSawder, + askTrovenaBeenaDependsRowans, + ( + glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && + anodyneCondosMalateOverateRetinol + ) ? + annularCooeedSplicesWalksWayWay + : kochabCooieGameOnOboleUnweave, +); +// TODO(rattrayalex): try to indent consequent/alternate here. + +================================================================================ +`; + +exports[`func-call.js - {"experimentalTernaries":true,"useTabs":true,"tabWidth":4} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 +useTabs: true + | printWidth +=====================================input====================================== +fn( + bifornCringerMoshedPerplexSawder, + askTrovenaBeenaDependsRowans, + glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && + anodyneCondosMalateOverateRetinol + ? annularCooeedSplicesWalksWayWay + : kochabCooieGameOnOboleUnweave +); +// TODO(rattrayalex): try to indent consequent/alternate here. + +=====================================output===================================== +fn( + bifornCringerMoshedPerplexSawder, + askTrovenaBeenaDependsRowans, + ( + glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && + anodyneCondosMalateOverateRetinol + ) ? + annularCooeedSplicesWalksWayWay + : kochabCooieGameOnOboleUnweave, +); +// TODO(rattrayalex): try to indent consequent/alternate here. + +================================================================================ +`; + +exports[`func-call.js - {"experimentalTernaries":true,"useTabs":true} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +useTabs: true + | printWidth +=====================================input====================================== +fn( + bifornCringerMoshedPerplexSawder, + askTrovenaBeenaDependsRowans, + glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && + anodyneCondosMalateOverateRetinol + ? annularCooeedSplicesWalksWayWay + : kochabCooieGameOnOboleUnweave +); +// TODO(rattrayalex): try to indent consequent/alternate here. + +=====================================output===================================== +fn( + bifornCringerMoshedPerplexSawder, + askTrovenaBeenaDependsRowans, + ( + glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && + anodyneCondosMalateOverateRetinol + ) ? + annularCooeedSplicesWalksWayWay + : kochabCooieGameOnOboleUnweave, +); +// TODO(rattrayalex): try to indent consequent/alternate here. + +================================================================================ +`; + +exports[`func-call.js - {"experimentalTernaries":true} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +fn( + bifornCringerMoshedPerplexSawder, + askTrovenaBeenaDependsRowans, + glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && + anodyneCondosMalateOverateRetinol + ? annularCooeedSplicesWalksWayWay + : kochabCooieGameOnOboleUnweave +); +// TODO(rattrayalex): try to indent consequent/alternate here. + +=====================================output===================================== +fn( + bifornCringerMoshedPerplexSawder, + askTrovenaBeenaDependsRowans, + ( + glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl && + anodyneCondosMalateOverateRetinol + ) ? + annularCooeedSplicesWalksWayWay + : kochabCooieGameOnOboleUnweave, +); +// TODO(rattrayalex): try to indent consequent/alternate here. + +================================================================================ +`; + exports[`func-call.js - {"tabWidth":4} format 1`] = ` ====================================options===================================== parsers: ["babel", "flow", "typescript"] @@ -292,6 +616,1342 @@ fn( ================================================================================ `; +exports[`indent.js - {"experimentalTernaries":true,"tabWidth":4} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 + | printWidth +=====================================input====================================== +aaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb : ccccccccccccccc ? ddddddddddddddd : eeeeeeeeeeeeeee ? fffffffffffffff : gggggggggggggggg + +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +? +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +? +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +? +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +: +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +: +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +: +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +a + ? { + a: 0 + } + : { + a: { + a: 0 + } + ? { + a: 0 + } + : { + y: { + a: 0 + } + ? { + a: 0 + } + : { + a: 0 + } + } + } + +a + ? { + a: function() { + return a + ? { + a: [ + a + ? { + a: 0, + b: [ + a + ? [ + 0, + 1 + ] + : [] + ] + } + : [ + [ + 0, + { + a: 0 + }, + a + ? 0 + : 1 + ], + function() { + return a + ? { + a: 0 + } + : [ + { + a: 0 + }, + {} + ]; + } + ] + ] + } + : [ + a + ? function() { + a + ? a( + a + ? { + a: a( + { + a: 0 + } + ) + } + : [ + 0, + a(), + a( + a(), + { + a: 0 + }, + a + ? a() + : a( + { + a: 0 + } + ) + ), + a() + ? { + a: a(), + b: [] + } + : {} + ] + ): + a( + a() + ? { + a: 0 + } + : (function(a) { + return a() + ? [ + { + a: 0, + b: a() + } + ] + : a( + [ + a + ? { + a: 0 + } + : {}, + { + a: 0 + } + ] + ); + })( + a + ? function(a) { + return function() { + return 0; + }; + } + : function(a) { + return function() { + return 1; + } + } + ) + ); + } + : function() { + + } + ]; + } + } + : a; + +=====================================output===================================== +aaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb +: ccccccccccccccc ? ddddddddddddddd +: eeeeeeeeeeeeeee ? fffffffffffffff +: gggggggggggggggg; + +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ? + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ? + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ? + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; + +a ? + { + a: 0, + } +: { + a: + ( + { + a: 0, + } + ) ? + { + a: 0, + } + : { + y: + ( + { + a: 0, + } + ) ? + { + a: 0, + } + : { + a: 0, + }, + }, + }; + +a ? + { + a: function () { + return a ? + { + a: [ + a ? + { + a: 0, + b: [a ? [0, 1] : []], + } + : [ + [ + 0, + { + a: 0, + }, + a ? 0 : 1, + ], + function () { + return a ? + { + a: 0, + } + : [ + { + a: 0, + }, + {}, + ]; + }, + ], + ], + } + : [ + a ? + function () { + a ? + a( + a ? + { + a: a({ + a: 0, + }), + } + : [ + 0, + a(), + a( + a(), + { + a: 0, + }, + a ? a() : ( + a({ + a: 0, + }) + ), + ), + a() ? + { + a: a(), + b: [], + } + : {}, + ], + ) + : a( + a() ? + { + a: 0, + } + : (function (a) { + return a() ? + [ + { + a: 0, + b: a(), + }, + ] + : a([ + a ? + { + a: 0, + } + : {}, + { + a: 0, + }, + ]); + })( + a ? + function (a) { + return function () { + return 0; + }; + } + : function (a) { + return function () { + return 1; + }; + }, + ), + ); + } + : function () {}, + ]; + }, + } +: a; + +================================================================================ +`; + +exports[`indent.js - {"experimentalTernaries":true,"useTabs":true,"tabWidth":4} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 +useTabs: true + | printWidth +=====================================input====================================== +aaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb : ccccccccccccccc ? ddddddddddddddd : eeeeeeeeeeeeeee ? fffffffffffffff : gggggggggggggggg + +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +? +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +? +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +? +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +: +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +: +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +: +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +a + ? { + a: 0 + } + : { + a: { + a: 0 + } + ? { + a: 0 + } + : { + y: { + a: 0 + } + ? { + a: 0 + } + : { + a: 0 + } + } + } + +a + ? { + a: function() { + return a + ? { + a: [ + a + ? { + a: 0, + b: [ + a + ? [ + 0, + 1 + ] + : [] + ] + } + : [ + [ + 0, + { + a: 0 + }, + a + ? 0 + : 1 + ], + function() { + return a + ? { + a: 0 + } + : [ + { + a: 0 + }, + {} + ]; + } + ] + ] + } + : [ + a + ? function() { + a + ? a( + a + ? { + a: a( + { + a: 0 + } + ) + } + : [ + 0, + a(), + a( + a(), + { + a: 0 + }, + a + ? a() + : a( + { + a: 0 + } + ) + ), + a() + ? { + a: a(), + b: [] + } + : {} + ] + ): + a( + a() + ? { + a: 0 + } + : (function(a) { + return a() + ? [ + { + a: 0, + b: a() + } + ] + : a( + [ + a + ? { + a: 0 + } + : {}, + { + a: 0 + } + ] + ); + })( + a + ? function(a) { + return function() { + return 0; + }; + } + : function(a) { + return function() { + return 1; + } + } + ) + ); + } + : function() { + + } + ]; + } + } + : a; + +=====================================output===================================== +aaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb +: ccccccccccccccc ? ddddddddddddddd +: eeeeeeeeeeeeeee ? fffffffffffffff +: gggggggggggggggg; + +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ? + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ? + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ? + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; + +a ? + { + a: 0, + } +: { + a: + ( + { + a: 0, + } + ) ? + { + a: 0, + } + : { + y: + ( + { + a: 0, + } + ) ? + { + a: 0, + } + : { + a: 0, + }, + }, + }; + +a ? + { + a: function () { + return a ? + { + a: [ + a ? + { + a: 0, + b: [a ? [0, 1] : []], + } + : [ + [ + 0, + { + a: 0, + }, + a ? 0 : 1, + ], + function () { + return a ? + { + a: 0, + } + : [ + { + a: 0, + }, + {}, + ]; + }, + ], + ], + } + : [ + a ? + function () { + a ? + a( + a ? + { + a: a({ + a: 0, + }), + } + : [ + 0, + a(), + a( + a(), + { + a: 0, + }, + a ? a() : ( + a({ + a: 0, + }) + ), + ), + a() ? + { + a: a(), + b: [], + } + : {}, + ], + ) + : a( + a() ? + { + a: 0, + } + : (function (a) { + return a() ? + [ + { + a: 0, + b: a(), + }, + ] + : a([ + a ? + { + a: 0, + } + : {}, + { + a: 0, + }, + ]); + })( + a ? + function (a) { + return function () { + return 0; + }; + } + : function (a) { + return function () { + return 1; + }; + }, + ), + ); + } + : function () {}, + ]; + }, + } +: a; + +================================================================================ +`; + +exports[`indent.js - {"experimentalTernaries":true,"useTabs":true} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +useTabs: true + | printWidth +=====================================input====================================== +aaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb : ccccccccccccccc ? ddddddddddddddd : eeeeeeeeeeeeeee ? fffffffffffffff : gggggggggggggggg + +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +? +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +? +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +? +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +: +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +: +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +: +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +a + ? { + a: 0 + } + : { + a: { + a: 0 + } + ? { + a: 0 + } + : { + y: { + a: 0 + } + ? { + a: 0 + } + : { + a: 0 + } + } + } + +a + ? { + a: function() { + return a + ? { + a: [ + a + ? { + a: 0, + b: [ + a + ? [ + 0, + 1 + ] + : [] + ] + } + : [ + [ + 0, + { + a: 0 + }, + a + ? 0 + : 1 + ], + function() { + return a + ? { + a: 0 + } + : [ + { + a: 0 + }, + {} + ]; + } + ] + ] + } + : [ + a + ? function() { + a + ? a( + a + ? { + a: a( + { + a: 0 + } + ) + } + : [ + 0, + a(), + a( + a(), + { + a: 0 + }, + a + ? a() + : a( + { + a: 0 + } + ) + ), + a() + ? { + a: a(), + b: [] + } + : {} + ] + ): + a( + a() + ? { + a: 0 + } + : (function(a) { + return a() + ? [ + { + a: 0, + b: a() + } + ] + : a( + [ + a + ? { + a: 0 + } + : {}, + { + a: 0 + } + ] + ); + })( + a + ? function(a) { + return function() { + return 0; + }; + } + : function(a) { + return function() { + return 1; + } + } + ) + ); + } + : function() { + + } + ]; + } + } + : a; + +=====================================output===================================== +aaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb +: ccccccccccccccc ? ddddddddddddddd +: eeeeeeeeeeeeeee ? fffffffffffffff +: gggggggggggggggg; + +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ? + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ? + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ? + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; + +a ? + { + a: 0, + } +: { + a: + ( + { + a: 0, + } + ) ? + { + a: 0, + } + : { + y: + ( + { + a: 0, + } + ) ? + { + a: 0, + } + : { + a: 0, + }, + }, + }; + +a ? + { + a: function () { + return a ? + { + a: [ + a ? + { + a: 0, + b: [a ? [0, 1] : []], + } + : [ + [ + 0, + { + a: 0, + }, + a ? 0 : 1, + ], + function () { + return a ? + { + a: 0, + } + : [ + { + a: 0, + }, + {}, + ]; + }, + ], + ], + } + : [ + a ? + function () { + a ? + a( + a ? + { + a: a({ + a: 0, + }), + } + : [ + 0, + a(), + a( + a(), + { + a: 0, + }, + a ? a() : ( + a({ + a: 0, + }) + ), + ), + a() ? + { + a: a(), + b: [], + } + : {}, + ], + ) + : a( + a() ? + { + a: 0, + } + : (function (a) { + return a() ? + [ + { + a: 0, + b: a(), + }, + ] + : a([ + a ? + { + a: 0, + } + : {}, + { + a: 0, + }, + ]); + })( + a ? + function (a) { + return function () { + return 0; + }; + } + : function (a) { + return function () { + return 1; + }; + }, + ), + ); + } + : function () {}, + ]; + }, + } +: a; + +================================================================================ +`; + +exports[`indent.js - {"experimentalTernaries":true} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +aaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb : ccccccccccccccc ? ddddddddddddddd : eeeeeeeeeeeeeee ? fffffffffffffff : gggggggggggggggg + +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +? +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +? +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +? +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +: +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +: +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +: +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +a + ? { + a: 0 + } + : { + a: { + a: 0 + } + ? { + a: 0 + } + : { + y: { + a: 0 + } + ? { + a: 0 + } + : { + a: 0 + } + } + } + +a + ? { + a: function() { + return a + ? { + a: [ + a + ? { + a: 0, + b: [ + a + ? [ + 0, + 1 + ] + : [] + ] + } + : [ + [ + 0, + { + a: 0 + }, + a + ? 0 + : 1 + ], + function() { + return a + ? { + a: 0 + } + : [ + { + a: 0 + }, + {} + ]; + } + ] + ] + } + : [ + a + ? function() { + a + ? a( + a + ? { + a: a( + { + a: 0 + } + ) + } + : [ + 0, + a(), + a( + a(), + { + a: 0 + }, + a + ? a() + : a( + { + a: 0 + } + ) + ), + a() + ? { + a: a(), + b: [] + } + : {} + ] + ): + a( + a() + ? { + a: 0 + } + : (function(a) { + return a() + ? [ + { + a: 0, + b: a() + } + ] + : a( + [ + a + ? { + a: 0 + } + : {}, + { + a: 0 + } + ] + ); + })( + a + ? function(a) { + return function() { + return 0; + }; + } + : function(a) { + return function() { + return 1; + } + } + ) + ); + } + : function() { + + } + ]; + } + } + : a; + +=====================================output===================================== +aaaaaaaaaaaaaaa ? bbbbbbbbbbbbbbbbbb +: ccccccccccccccc ? ddddddddddddddd +: eeeeeeeeeeeeeee ? fffffffffffffff +: gggggggggggggggg; + +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ? + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ? + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ? + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; + +a ? + { + a: 0, + } +: { + a: + ( + { + a: 0, + } + ) ? + { + a: 0, + } + : { + y: + ( + { + a: 0, + } + ) ? + { + a: 0, + } + : { + a: 0, + }, + }, + }; + +a ? + { + a: function () { + return a ? + { + a: [ + a ? + { + a: 0, + b: [a ? [0, 1] : []], + } + : [ + [ + 0, + { + a: 0, + }, + a ? 0 : 1, + ], + function () { + return a ? + { + a: 0, + } + : [ + { + a: 0, + }, + {}, + ]; + }, + ], + ], + } + : [ + a ? + function () { + a ? + a( + a ? + { + a: a({ + a: 0, + }), + } + : [ + 0, + a(), + a( + a(), + { + a: 0, + }, + a ? a() : ( + a({ + a: 0, + }) + ), + ), + a() ? + { + a: a(), + b: [], + } + : {}, + ], + ) + : a( + a() ? + { + a: 0, + } + : (function (a) { + return a() ? + [ + { + a: 0, + b: a(), + }, + ] + : a([ + a ? + { + a: 0, + } + : {}, + { + a: 0, + }, + ]); + })( + a ? + function (a) { + return function () { + return 0; + }; + } + : function (a) { + return function () { + return 1; + }; + }, + ), + ); + } + : function () {}, + ]; + }, + } +: a; + +================================================================================ +`; + exports[`indent.js - {"tabWidth":4} format 1`] = ` ====================================options===================================== parsers: ["babel", "flow", "typescript"] @@ -1616,6 +3276,2530 @@ a ================================================================================ `; +exports[`indent-after-paren.js - {"experimentalTernaries":true,"tabWidth":4} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 + | printWidth +=====================================input====================================== +foo7 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; + +foo8 = (condition ? firstValue : secondValue)[SomeType]; + +const foo9 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; + +function foo10() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +function foo11() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +function foo12() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +foo13 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +).Fooooooooooo.Fooooooooooo; + +foo14 = (condition ? firstValue : secondValue)[SomeType]; + +const foo15 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +).Fooooooooooo.Fooooooooooo; + +function foo16() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +function foo17() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +function foo18() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +foo19 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +foo20 = (condition ? firstValue : secondValue)[SomeType]; + +const foo21 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +function foo22() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo23() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo24() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +foo25 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + +foo26 = (condition ? firstValue : secondValue)[SomeType]; + +const foo27 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + +function foo28() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function foo29() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function foo30() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function* foo31() { + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo.Fooooooooooo]; +} + +const foo32 = new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +function foo33() { + return new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo34() { + throw new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo35() { + void new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +foo36 = new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol).Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol).Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo)); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo)); +// TODO(rattrayalex): try to fix this case + +bifornCringerMoshedPerplexSawder = ( + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).annularCooeedSplicesWalksWayWay + .annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay) + .annularCooeedSplicesWalksWayWay(); + +foo = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.()?.()?.(); + +foo = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)()()(); + +foo = + foo.bar.baz[ + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ]; + +const decorated = (arg, ignoreRequestError) => { + return ( + typeof arg === "string" || + (arg && arg.valueOf && typeof arg.valueOf() === "string") + ? $delegate(arg, ignoreRequestError) + : handleAsyncOperations(arg, ignoreRequestError) + ).foo(); +}; + +bifornCringerMoshedPerplexSawder = fn( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +fn( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +) + +bifornCringerMoshedPerplexSawder = fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +) + +bifornCringerMoshedPerplexSawder = + fn[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +bifornCringerMoshedPerplexSawder = + fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +=====================================output===================================== +foo7 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; + +foo8 = (condition ? firstValue : secondValue)[SomeType]; + +const foo9 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; + +function foo10() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +function foo11() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +function foo12() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +foo13 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; + +foo14 = (condition ? firstValue : secondValue)[SomeType]; + +const foo15 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; + +function foo16() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; +} + +function foo17() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; +} + +function foo18() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; +} + +foo19 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +foo20 = (condition ? firstValue : secondValue)[SomeType]; + +const foo21 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +function foo22() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo23() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo24() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +foo25 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + +foo26 = (condition ? firstValue : secondValue)[SomeType]; + +const foo27 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + +function foo28() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function foo29() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function foo30() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function* foo31() { + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo.Fooooooooooo]; +} + +const foo32 = new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +function foo33() { + return new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo34() { + throw new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo35() { + void new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +foo36 = new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (( + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ) ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).Fooooooooooo.Fooooooooooo; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (( + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ) ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).Fooooooooooo.Fooooooooooo; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (( + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ) ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo); +// TODO(rattrayalex): try to fix this case + +bifornCringerMoshedPerplexSawder = ( + ( + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ) ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol).annularCooeedSplicesWalksWayWay + .annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay) + .annularCooeedSplicesWalksWayWay(); + +foo = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.()?.()?.(); + +foo = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)()()(); + +foo = + foo.bar.baz[ + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ]; + +const decorated = (arg, ignoreRequestError) => { + return ( + ( + typeof arg === "string" || + (arg && arg.valueOf && typeof arg.valueOf() === "string") + ) ? + $delegate(arg, ignoreRequestError) + : handleAsyncOperations(arg, ignoreRequestError)).foo(); +}; + +bifornCringerMoshedPerplexSawder = fn( + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop, +); + +fn( + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop, +); + +bifornCringerMoshedPerplexSawder = fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop, +); + +fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop, +); + +bifornCringerMoshedPerplexSawder = + fn[ + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn[ + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +bifornCringerMoshedPerplexSawder = + fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +================================================================================ +`; + +exports[`indent-after-paren.js - {"experimentalTernaries":true,"useTabs":true,"tabWidth":4} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 +useTabs: true + | printWidth +=====================================input====================================== +foo7 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; + +foo8 = (condition ? firstValue : secondValue)[SomeType]; + +const foo9 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; + +function foo10() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +function foo11() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +function foo12() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +foo13 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +).Fooooooooooo.Fooooooooooo; + +foo14 = (condition ? firstValue : secondValue)[SomeType]; + +const foo15 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +).Fooooooooooo.Fooooooooooo; + +function foo16() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +function foo17() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +function foo18() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +foo19 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +foo20 = (condition ? firstValue : secondValue)[SomeType]; + +const foo21 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +function foo22() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo23() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo24() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +foo25 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + +foo26 = (condition ? firstValue : secondValue)[SomeType]; + +const foo27 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + +function foo28() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function foo29() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function foo30() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function* foo31() { + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo.Fooooooooooo]; +} + +const foo32 = new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +function foo33() { + return new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo34() { + throw new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo35() { + void new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +foo36 = new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol).Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol).Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo)); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo)); +// TODO(rattrayalex): try to fix this case + +bifornCringerMoshedPerplexSawder = ( + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).annularCooeedSplicesWalksWayWay + .annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay) + .annularCooeedSplicesWalksWayWay(); + +foo = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.()?.()?.(); + +foo = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)()()(); + +foo = + foo.bar.baz[ + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ]; + +const decorated = (arg, ignoreRequestError) => { + return ( + typeof arg === "string" || + (arg && arg.valueOf && typeof arg.valueOf() === "string") + ? $delegate(arg, ignoreRequestError) + : handleAsyncOperations(arg, ignoreRequestError) + ).foo(); +}; + +bifornCringerMoshedPerplexSawder = fn( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +fn( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +) + +bifornCringerMoshedPerplexSawder = fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +) + +bifornCringerMoshedPerplexSawder = + fn[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +bifornCringerMoshedPerplexSawder = + fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +=====================================output===================================== +foo7 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; + +foo8 = (condition ? firstValue : secondValue)[SomeType]; + +const foo9 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; + +function foo10() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +function foo11() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +function foo12() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +foo13 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; + +foo14 = (condition ? firstValue : secondValue)[SomeType]; + +const foo15 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; + +function foo16() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; +} + +function foo17() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; +} + +function foo18() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; +} + +foo19 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +foo20 = (condition ? firstValue : secondValue)[SomeType]; + +const foo21 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +function foo22() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo23() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo24() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +foo25 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + +foo26 = (condition ? firstValue : secondValue)[SomeType]; + +const foo27 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + +function foo28() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function foo29() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function foo30() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function* foo31() { + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo.Fooooooooooo]; +} + +const foo32 = new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +function foo33() { + return new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo34() { + throw new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo35() { + void new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +foo36 = new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (( + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ) ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).Fooooooooooo.Fooooooooooo; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (( + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ) ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).Fooooooooooo.Fooooooooooo; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (( + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ) ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo); +// TODO(rattrayalex): try to fix this case + +bifornCringerMoshedPerplexSawder = ( + ( + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ) ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol).annularCooeedSplicesWalksWayWay + .annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay) + .annularCooeedSplicesWalksWayWay(); + +foo = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.()?.()?.(); + +foo = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)()()(); + +foo = + foo.bar.baz[ + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ]; + +const decorated = (arg, ignoreRequestError) => { + return ( + ( + typeof arg === "string" || + (arg && arg.valueOf && typeof arg.valueOf() === "string") + ) ? + $delegate(arg, ignoreRequestError) + : handleAsyncOperations(arg, ignoreRequestError)).foo(); +}; + +bifornCringerMoshedPerplexSawder = fn( + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop, +); + +fn( + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop, +); + +bifornCringerMoshedPerplexSawder = fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop, +); + +fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop, +); + +bifornCringerMoshedPerplexSawder = + fn[ + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn[ + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +bifornCringerMoshedPerplexSawder = + fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +================================================================================ +`; + +exports[`indent-after-paren.js - {"experimentalTernaries":true,"useTabs":true} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +useTabs: true + | printWidth +=====================================input====================================== +foo7 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; + +foo8 = (condition ? firstValue : secondValue)[SomeType]; + +const foo9 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; + +function foo10() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +function foo11() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +function foo12() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +foo13 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +).Fooooooooooo.Fooooooooooo; + +foo14 = (condition ? firstValue : secondValue)[SomeType]; + +const foo15 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +).Fooooooooooo.Fooooooooooo; + +function foo16() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +function foo17() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +function foo18() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +foo19 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +foo20 = (condition ? firstValue : secondValue)[SomeType]; + +const foo21 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +function foo22() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo23() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo24() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +foo25 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + +foo26 = (condition ? firstValue : secondValue)[SomeType]; + +const foo27 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + +function foo28() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function foo29() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function foo30() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function* foo31() { + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo.Fooooooooooo]; +} + +const foo32 = new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +function foo33() { + return new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo34() { + throw new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo35() { + void new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +foo36 = new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol).Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol).Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo)); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo)); +// TODO(rattrayalex): try to fix this case + +bifornCringerMoshedPerplexSawder = ( + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).annularCooeedSplicesWalksWayWay + .annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay) + .annularCooeedSplicesWalksWayWay(); + +foo = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.()?.()?.(); + +foo = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)()()(); + +foo = + foo.bar.baz[ + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ]; + +const decorated = (arg, ignoreRequestError) => { + return ( + typeof arg === "string" || + (arg && arg.valueOf && typeof arg.valueOf() === "string") + ? $delegate(arg, ignoreRequestError) + : handleAsyncOperations(arg, ignoreRequestError) + ).foo(); +}; + +bifornCringerMoshedPerplexSawder = fn( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +fn( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +) + +bifornCringerMoshedPerplexSawder = fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +) + +bifornCringerMoshedPerplexSawder = + fn[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +bifornCringerMoshedPerplexSawder = + fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +=====================================output===================================== +foo7 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; + +foo8 = (condition ? firstValue : secondValue)[SomeType]; + +const foo9 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; + +function foo10() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +function foo11() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +function foo12() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +foo13 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; + +foo14 = (condition ? firstValue : secondValue)[SomeType]; + +const foo15 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; + +function foo16() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; +} + +function foo17() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; +} + +function foo18() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; +} + +foo19 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +foo20 = (condition ? firstValue : secondValue)[SomeType]; + +const foo21 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +function foo22() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo23() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo24() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +foo25 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + +foo26 = (condition ? firstValue : secondValue)[SomeType]; + +const foo27 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + +function foo28() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function foo29() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function foo30() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function* foo31() { + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo.Fooooooooooo]; +} + +const foo32 = new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +function foo33() { + return new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo34() { + throw new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo35() { + void new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +foo36 = new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (( + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ) ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).Fooooooooooo.Fooooooooooo; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (( + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ) ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).Fooooooooooo.Fooooooooooo; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (( + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ) ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo); +// TODO(rattrayalex): try to fix this case + +bifornCringerMoshedPerplexSawder = ( + ( + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ) ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol).annularCooeedSplicesWalksWayWay + .annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay) + .annularCooeedSplicesWalksWayWay(); + +foo = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.()?.()?.(); + +foo = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)()()(); + +foo = + foo.bar.baz[ + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ]; + +const decorated = (arg, ignoreRequestError) => { + return ( + ( + typeof arg === "string" || + (arg && arg.valueOf && typeof arg.valueOf() === "string") + ) ? + $delegate(arg, ignoreRequestError) + : handleAsyncOperations(arg, ignoreRequestError)).foo(); +}; + +bifornCringerMoshedPerplexSawder = fn( + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop, +); + +fn( + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop, +); + +bifornCringerMoshedPerplexSawder = fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop, +); + +fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop, +); + +bifornCringerMoshedPerplexSawder = + fn[ + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn[ + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +bifornCringerMoshedPerplexSawder = + fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +================================================================================ +`; + +exports[`indent-after-paren.js - {"experimentalTernaries":true} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +foo7 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; + +foo8 = (condition ? firstValue : secondValue)[SomeType]; + +const foo9 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; + +function foo10() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +function foo11() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +function foo12() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +foo13 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +).Fooooooooooo.Fooooooooooo; + +foo14 = (condition ? firstValue : secondValue)[SomeType]; + +const foo15 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +).Fooooooooooo.Fooooooooooo; + +function foo16() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +function foo17() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +function foo18() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ).Fooooooooooo.Fooooooooooo; +} + +foo19 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +foo20 = (condition ? firstValue : secondValue)[SomeType]; + +const foo21 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +function foo22() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo23() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo24() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +foo25 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + +foo26 = (condition ? firstValue : secondValue)[SomeType]; + +const foo27 = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + +function foo28() { + return (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function foo29() { + throw (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function foo30() { + void (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function* foo31() { + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; + yield (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo.Fooooooooooo]; +} + +const foo32 = new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +function foo33() { + return new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo34() { + throw new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +function foo35() { + void new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + )(Fooooooooooo.Fooooooooooo); +} + +foo36 = new (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz +)(Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol).Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol).Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo)); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + ((glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo)); +// TODO(rattrayalex): try to fix this case + +bifornCringerMoshedPerplexSawder = ( + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).annularCooeedSplicesWalksWayWay + .annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay) + .annularCooeedSplicesWalksWayWay(); + +foo = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.()?.()?.(); + +foo = (coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)()()(); + +foo = + foo.bar.baz[ + coooooooooooooooooooooooooooooooooooooooooooooooooooond + ? baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ]; + +const decorated = (arg, ignoreRequestError) => { + return ( + typeof arg === "string" || + (arg && arg.valueOf && typeof arg.valueOf() === "string") + ? $delegate(arg, ignoreRequestError) + : handleAsyncOperations(arg, ignoreRequestError) + ).foo(); +}; + +bifornCringerMoshedPerplexSawder = fn( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +fn( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +) + +bifornCringerMoshedPerplexSawder = fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +); + +fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +) + +bifornCringerMoshedPerplexSawder = + fn[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +bifornCringerMoshedPerplexSawder = + fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 + ? averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +=====================================output===================================== +foo7 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; + +foo8 = (condition ? firstValue : secondValue)[SomeType]; + +const foo9 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; + +function foo10() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +function foo11() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +function foo12() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo]; +} + +foo13 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; + +foo14 = (condition ? firstValue : secondValue)[SomeType]; + +const foo15 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; + +function foo16() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; +} + +function foo17() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; +} + +function foo18() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; +} + +foo19 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +foo20 = (condition ? firstValue : secondValue)[SomeType]; + +const foo21 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +function foo22() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo23() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo24() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +foo25 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + +foo26 = (condition ? firstValue : secondValue)[SomeType]; + +const foo27 = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + +function foo28() { + return ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function foo29() { + throw ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function foo30() { + void ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); +} + +function* foo31() { + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.(Fooooooooooo.Fooooooooooo); + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz).Fooooooooooo.Fooooooooooo; + yield ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)[Fooooooooooo.Fooooooooooo]; +} + +const foo32 = new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +function foo33() { + return new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo34() { + throw new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +function foo35() { + void new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); +} + +foo36 = new ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)(Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (( + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ) ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)[AnnularCooeedSplicesWalksWayWay]; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).Fooooooooooo.Fooooooooooo; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (( + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ) ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).Fooooooooooo.Fooooooooooo; + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo); + +bifornCringerMoshedPerplexSawder = + askTrovenaBeenaDependsRowans + + (( + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ) ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol)(Fooooooooooo.Fooooooooooo); +// TODO(rattrayalex): try to fix this case + +bifornCringerMoshedPerplexSawder = ( + ( + glimseGlyphsHazardNoopsTieTie === 0 && + kochabCooieGameOnOboleUnweave === Math.PI + ) ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol).annularCooeedSplicesWalksWayWay + .annularCooeedSplicesWalksWayWay(annularCooeedSplicesWalksWayWay) + .annularCooeedSplicesWalksWayWay(); + +foo = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)?.()?.()?.(); + +foo = ( + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz)()()(); + +foo = + foo.bar.baz[ + coooooooooooooooooooooooooooooooooooooooooooooooooooond ? + baaaaaaaaaaaaaaaaaaaaar + : baaaaaaaaaaaaaaaaaaaaaz + ]; + +const decorated = (arg, ignoreRequestError) => { + return ( + ( + typeof arg === "string" || + (arg && arg.valueOf && typeof arg.valueOf() === "string") + ) ? + $delegate(arg, ignoreRequestError) + : handleAsyncOperations(arg, ignoreRequestError)).foo(); +}; + +bifornCringerMoshedPerplexSawder = fn( + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop, +); + +fn( + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop, +); + +bifornCringerMoshedPerplexSawder = fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop, +); + +fn?.( + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop, +); + +bifornCringerMoshedPerplexSawder = + fn[ + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn[ + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +bifornCringerMoshedPerplexSawder = + fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop + ]; + +fn?.[ + (glimseGlyphsHazardNoopsTieTie === 0 ? + averredBathersBoxroomBuggyNurl + : anodyneCondosMalateOverateRetinol + ).prop +]; + +================================================================================ +`; + exports[`indent-after-paren.js - {"tabWidth":4} format 1`] = ` ====================================options===================================== parsers: ["babel", "flow", "typescript"] @@ -4228,6 +8412,1074 @@ fn?.[ ================================================================================ `; +exports[`nested.js - {"experimentalTernaries":true,"tabWidth":4} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 + | printWidth +=====================================input====================================== +let icecream = what == "cone" + ? p => !!p ? \`here's your \${p} cone\` : \`just the empty cone for you\` + : p => \`here's your \${p} \${what}\`; + +const value = condition1 +? value1 +: condition2 + ? value2 + : condition3 + ? value3 + : value4; + + +const StorybookLoader = ({ match }) => ( + match.params.storyId === "button" + ? + : match.params.storyId === "color" + ? + : match.params.storyId === "typography" + ? + : match.params.storyId === "loading" + ? + : match.params.storyId === "deal-list" + ? + : ( + + {'Missing story book'} + + + + + ) +) + +const message = + i % 3 === 0 && i % 5 === 0 ? + 'fizzbuzz' + : i % 3 === 0 ? + 'fizz' + : i % 5 === 0 ? + 'buzz' + : + String(i) + +const paymentMessage = state == 'success' + ? 'Payment completed successfully' + +: state == 'processing' + ? 'Payment processing' + +: state == 'invalid_cvc' + ? 'There was an issue with your CVC number' + +: state == 'invalid_expiry' + ? 'Expiry must be sometime in the past.' + + : 'There was an issue with the payment. Please contact support.' + +const paymentMessage2 = state == 'success' + ? 1 //'Payment completed successfully' + +: state == 'processing' + ? 2 //'Payment processing' + +: state == 'invalid_cvc' + ? 3 //'There was an issue with your CVC number' + +: true //state == 'invalid_expiry' + ? 4 //'Expiry must be sometime in the past.' + + : 5 // 'There was an issue with the payment. Please contact support.' + +const foo =
+ {medals[0].record ? ( + i18n('Record') + ) : medals[0].unique ? ( + i18n('Unique') + ) : medals[0].type === 0 ? ( + i18n('Silver') + ) : medals[0].type === 1 ? ( + i18n('Gold') + ) : medals[0].type === 2 ? ( + i18n('Platinum') + ) : ( + i18n('Theme') + )} +
+ +a + ? literalline + : { + 123: 12 + } + ? line + : softline + +const config = { + onFailure: onFailure !== undefined ? onFailure : ( + error => { + notify( + typeof error === 'string' ? + error + : error.message || 'ra.notification.http_error', + 'warning', + { + _: + typeof error === 'string' ? error + : error && error.message ? error.message + : undefined, + } + ); + refresh(); + } + ) +} + +showNotification( + typeof error === 'string' ? error : error.message || body, + level || 'warning', + { + messageArgs, + undoable: false, + } +) + +const result = children && !isEmptyChildren(children) + ? children + : props.match + ? component + ? React.createElement(component, props) + : render + ? render(props) + : null + : null; + +=====================================output===================================== +let icecream = + what == "cone" ? + (p) => (!!p ? \`here's your \${p} cone\` : \`just the empty cone for you\`) + : (p) => \`here's your \${p} \${what}\`; + +const value = + condition1 ? value1 + : condition2 ? value2 + : condition3 ? value3 + : value4; + +const StorybookLoader = ({ match }) => + match.params.storyId === "button" ? + : match.params.storyId === "color" ? + : match.params.storyId === "typography" ? + : match.params.storyId === "loading" ? + : match.params.storyId === "deal-list" ? + : + {"Missing story book"} + + + + ; + +const message = + i % 3 === 0 && i % 5 === 0 ? "fizzbuzz" + : i % 3 === 0 ? "fizz" + : i % 5 === 0 ? "buzz" + : String(i); + +const paymentMessage = + state == "success" ? "Payment completed successfully" + : state == "processing" ? "Payment processing" + : state == "invalid_cvc" ? "There was an issue with your CVC number" + : state == "invalid_expiry" ? "Expiry must be sometime in the past." + : "There was an issue with the payment. Please contact support."; + +const paymentMessage2 = + state == "success" ? + 1 //'Payment completed successfully' + : state == "processing" ? + 2 //'Payment processing' + : state == "invalid_cvc" ? + 3 //'There was an issue with your CVC number' + : ( + true //state == 'invalid_expiry' + ) ? + 4 //'Expiry must be sometime in the past.' + : 5; // 'There was an issue with the payment. Please contact support.' + +const foo = ( +
+ {medals[0].record ? + i18n("Record") + : medals[0].unique ? + i18n("Unique") + : medals[0].type === 0 ? + i18n("Silver") + : medals[0].type === 1 ? + i18n("Gold") + : medals[0].type === 2 ? + i18n("Platinum") + : i18n("Theme")} +
+); + +a ? literalline +: ( + { + 123: 12, + } +) ? + line +: softline; + +const config = { + onFailure: + onFailure !== undefined ? onFailure : ( + (error) => { + notify( + typeof error === "string" ? error : ( + error.message || "ra.notification.http_error" + ), + "warning", + { + _: + typeof error === "string" ? error + : error && error.message ? error.message + : undefined, + }, + ); + refresh(); + } + ), +}; + +showNotification( + typeof error === "string" ? error : error.message || body, + level || "warning", + { + messageArgs, + undoable: false, + }, +); + +const result = + children && !isEmptyChildren(children) ? children + : props.match ? + component ? React.createElement(component, props) + : render ? render(props) + : null + : null; + +================================================================================ +`; + +exports[`nested.js - {"experimentalTernaries":true,"useTabs":true,"tabWidth":4} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 +useTabs: true + | printWidth +=====================================input====================================== +let icecream = what == "cone" + ? p => !!p ? \`here's your \${p} cone\` : \`just the empty cone for you\` + : p => \`here's your \${p} \${what}\`; + +const value = condition1 +? value1 +: condition2 + ? value2 + : condition3 + ? value3 + : value4; + + +const StorybookLoader = ({ match }) => ( + match.params.storyId === "button" + ? + : match.params.storyId === "color" + ? + : match.params.storyId === "typography" + ? + : match.params.storyId === "loading" + ? + : match.params.storyId === "deal-list" + ? + : ( + + {'Missing story book'} + + + + + ) +) + +const message = + i % 3 === 0 && i % 5 === 0 ? + 'fizzbuzz' + : i % 3 === 0 ? + 'fizz' + : i % 5 === 0 ? + 'buzz' + : + String(i) + +const paymentMessage = state == 'success' + ? 'Payment completed successfully' + +: state == 'processing' + ? 'Payment processing' + +: state == 'invalid_cvc' + ? 'There was an issue with your CVC number' + +: state == 'invalid_expiry' + ? 'Expiry must be sometime in the past.' + + : 'There was an issue with the payment. Please contact support.' + +const paymentMessage2 = state == 'success' + ? 1 //'Payment completed successfully' + +: state == 'processing' + ? 2 //'Payment processing' + +: state == 'invalid_cvc' + ? 3 //'There was an issue with your CVC number' + +: true //state == 'invalid_expiry' + ? 4 //'Expiry must be sometime in the past.' + + : 5 // 'There was an issue with the payment. Please contact support.' + +const foo =
+ {medals[0].record ? ( + i18n('Record') + ) : medals[0].unique ? ( + i18n('Unique') + ) : medals[0].type === 0 ? ( + i18n('Silver') + ) : medals[0].type === 1 ? ( + i18n('Gold') + ) : medals[0].type === 2 ? ( + i18n('Platinum') + ) : ( + i18n('Theme') + )} +
+ +a + ? literalline + : { + 123: 12 + } + ? line + : softline + +const config = { + onFailure: onFailure !== undefined ? onFailure : ( + error => { + notify( + typeof error === 'string' ? + error + : error.message || 'ra.notification.http_error', + 'warning', + { + _: + typeof error === 'string' ? error + : error && error.message ? error.message + : undefined, + } + ); + refresh(); + } + ) +} + +showNotification( + typeof error === 'string' ? error : error.message || body, + level || 'warning', + { + messageArgs, + undoable: false, + } +) + +const result = children && !isEmptyChildren(children) + ? children + : props.match + ? component + ? React.createElement(component, props) + : render + ? render(props) + : null + : null; + +=====================================output===================================== +let icecream = + what == "cone" ? + (p) => (!!p ? \`here's your \${p} cone\` : \`just the empty cone for you\`) + : (p) => \`here's your \${p} \${what}\`; + +const value = + condition1 ? value1 + : condition2 ? value2 + : condition3 ? value3 + : value4; + +const StorybookLoader = ({ match }) => + match.params.storyId === "button" ? + : match.params.storyId === "color" ? + : match.params.storyId === "typography" ? + : match.params.storyId === "loading" ? + : match.params.storyId === "deal-list" ? + : + {"Missing story book"} + + + + ; + +const message = + i % 3 === 0 && i % 5 === 0 ? "fizzbuzz" + : i % 3 === 0 ? "fizz" + : i % 5 === 0 ? "buzz" + : String(i); + +const paymentMessage = + state == "success" ? "Payment completed successfully" + : state == "processing" ? "Payment processing" + : state == "invalid_cvc" ? "There was an issue with your CVC number" + : state == "invalid_expiry" ? "Expiry must be sometime in the past." + : "There was an issue with the payment. Please contact support."; + +const paymentMessage2 = + state == "success" ? + 1 //'Payment completed successfully' + : state == "processing" ? + 2 //'Payment processing' + : state == "invalid_cvc" ? + 3 //'There was an issue with your CVC number' + : ( + true //state == 'invalid_expiry' + ) ? + 4 //'Expiry must be sometime in the past.' + : 5; // 'There was an issue with the payment. Please contact support.' + +const foo = ( +
+ {medals[0].record ? + i18n("Record") + : medals[0].unique ? + i18n("Unique") + : medals[0].type === 0 ? + i18n("Silver") + : medals[0].type === 1 ? + i18n("Gold") + : medals[0].type === 2 ? + i18n("Platinum") + : i18n("Theme")} +
+); + +a ? literalline +: ( + { + 123: 12, + } +) ? + line +: softline; + +const config = { + onFailure: + onFailure !== undefined ? onFailure : ( + (error) => { + notify( + typeof error === "string" ? error : ( + error.message || "ra.notification.http_error" + ), + "warning", + { + _: + typeof error === "string" ? error + : error && error.message ? error.message + : undefined, + }, + ); + refresh(); + } + ), +}; + +showNotification( + typeof error === "string" ? error : error.message || body, + level || "warning", + { + messageArgs, + undoable: false, + }, +); + +const result = + children && !isEmptyChildren(children) ? children + : props.match ? + component ? React.createElement(component, props) + : render ? render(props) + : null + : null; + +================================================================================ +`; + +exports[`nested.js - {"experimentalTernaries":true,"useTabs":true} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +useTabs: true + | printWidth +=====================================input====================================== +let icecream = what == "cone" + ? p => !!p ? \`here's your \${p} cone\` : \`just the empty cone for you\` + : p => \`here's your \${p} \${what}\`; + +const value = condition1 +? value1 +: condition2 + ? value2 + : condition3 + ? value3 + : value4; + + +const StorybookLoader = ({ match }) => ( + match.params.storyId === "button" + ? + : match.params.storyId === "color" + ? + : match.params.storyId === "typography" + ? + : match.params.storyId === "loading" + ? + : match.params.storyId === "deal-list" + ? + : ( + + {'Missing story book'} + + + + + ) +) + +const message = + i % 3 === 0 && i % 5 === 0 ? + 'fizzbuzz' + : i % 3 === 0 ? + 'fizz' + : i % 5 === 0 ? + 'buzz' + : + String(i) + +const paymentMessage = state == 'success' + ? 'Payment completed successfully' + +: state == 'processing' + ? 'Payment processing' + +: state == 'invalid_cvc' + ? 'There was an issue with your CVC number' + +: state == 'invalid_expiry' + ? 'Expiry must be sometime in the past.' + + : 'There was an issue with the payment. Please contact support.' + +const paymentMessage2 = state == 'success' + ? 1 //'Payment completed successfully' + +: state == 'processing' + ? 2 //'Payment processing' + +: state == 'invalid_cvc' + ? 3 //'There was an issue with your CVC number' + +: true //state == 'invalid_expiry' + ? 4 //'Expiry must be sometime in the past.' + + : 5 // 'There was an issue with the payment. Please contact support.' + +const foo =
+ {medals[0].record ? ( + i18n('Record') + ) : medals[0].unique ? ( + i18n('Unique') + ) : medals[0].type === 0 ? ( + i18n('Silver') + ) : medals[0].type === 1 ? ( + i18n('Gold') + ) : medals[0].type === 2 ? ( + i18n('Platinum') + ) : ( + i18n('Theme') + )} +
+ +a + ? literalline + : { + 123: 12 + } + ? line + : softline + +const config = { + onFailure: onFailure !== undefined ? onFailure : ( + error => { + notify( + typeof error === 'string' ? + error + : error.message || 'ra.notification.http_error', + 'warning', + { + _: + typeof error === 'string' ? error + : error && error.message ? error.message + : undefined, + } + ); + refresh(); + } + ) +} + +showNotification( + typeof error === 'string' ? error : error.message || body, + level || 'warning', + { + messageArgs, + undoable: false, + } +) + +const result = children && !isEmptyChildren(children) + ? children + : props.match + ? component + ? React.createElement(component, props) + : render + ? render(props) + : null + : null; + +=====================================output===================================== +let icecream = + what == "cone" ? + (p) => (!!p ? \`here's your \${p} cone\` : \`just the empty cone for you\`) + : (p) => \`here's your \${p} \${what}\`; + +const value = + condition1 ? value1 + : condition2 ? value2 + : condition3 ? value3 + : value4; + +const StorybookLoader = ({ match }) => + match.params.storyId === "button" ? + : match.params.storyId === "color" ? + : match.params.storyId === "typography" ? + : match.params.storyId === "loading" ? + : match.params.storyId === "deal-list" ? + : + {"Missing story book"} + + + + ; + +const message = + i % 3 === 0 && i % 5 === 0 ? "fizzbuzz" + : i % 3 === 0 ? "fizz" + : i % 5 === 0 ? "buzz" + : String(i); + +const paymentMessage = + state == "success" ? "Payment completed successfully" + : state == "processing" ? "Payment processing" + : state == "invalid_cvc" ? "There was an issue with your CVC number" + : state == "invalid_expiry" ? "Expiry must be sometime in the past." + : "There was an issue with the payment. Please contact support."; + +const paymentMessage2 = + state == "success" ? + 1 //'Payment completed successfully' + : state == "processing" ? + 2 //'Payment processing' + : state == "invalid_cvc" ? + 3 //'There was an issue with your CVC number' + : ( + true //state == 'invalid_expiry' + ) ? + 4 //'Expiry must be sometime in the past.' + : 5; // 'There was an issue with the payment. Please contact support.' + +const foo = ( +
+ {medals[0].record ? + i18n("Record") + : medals[0].unique ? + i18n("Unique") + : medals[0].type === 0 ? + i18n("Silver") + : medals[0].type === 1 ? + i18n("Gold") + : medals[0].type === 2 ? + i18n("Platinum") + : i18n("Theme")} +
+); + +a ? literalline +: ( + { + 123: 12, + } +) ? + line +: softline; + +const config = { + onFailure: + onFailure !== undefined ? onFailure : ( + (error) => { + notify( + typeof error === "string" ? error : ( + error.message || "ra.notification.http_error" + ), + "warning", + { + _: + typeof error === "string" ? error + : error && error.message ? error.message + : undefined, + }, + ); + refresh(); + } + ), +}; + +showNotification( + typeof error === "string" ? error : error.message || body, + level || "warning", + { + messageArgs, + undoable: false, + }, +); + +const result = + children && !isEmptyChildren(children) ? children + : props.match ? + component ? React.createElement(component, props) + : render ? render(props) + : null + : null; + +================================================================================ +`; + +exports[`nested.js - {"experimentalTernaries":true} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +let icecream = what == "cone" + ? p => !!p ? \`here's your \${p} cone\` : \`just the empty cone for you\` + : p => \`here's your \${p} \${what}\`; + +const value = condition1 +? value1 +: condition2 + ? value2 + : condition3 + ? value3 + : value4; + + +const StorybookLoader = ({ match }) => ( + match.params.storyId === "button" + ? + : match.params.storyId === "color" + ? + : match.params.storyId === "typography" + ? + : match.params.storyId === "loading" + ? + : match.params.storyId === "deal-list" + ? + : ( + + {'Missing story book'} + + + + + ) +) + +const message = + i % 3 === 0 && i % 5 === 0 ? + 'fizzbuzz' + : i % 3 === 0 ? + 'fizz' + : i % 5 === 0 ? + 'buzz' + : + String(i) + +const paymentMessage = state == 'success' + ? 'Payment completed successfully' + +: state == 'processing' + ? 'Payment processing' + +: state == 'invalid_cvc' + ? 'There was an issue with your CVC number' + +: state == 'invalid_expiry' + ? 'Expiry must be sometime in the past.' + + : 'There was an issue with the payment. Please contact support.' + +const paymentMessage2 = state == 'success' + ? 1 //'Payment completed successfully' + +: state == 'processing' + ? 2 //'Payment processing' + +: state == 'invalid_cvc' + ? 3 //'There was an issue with your CVC number' + +: true //state == 'invalid_expiry' + ? 4 //'Expiry must be sometime in the past.' + + : 5 // 'There was an issue with the payment. Please contact support.' + +const foo =
+ {medals[0].record ? ( + i18n('Record') + ) : medals[0].unique ? ( + i18n('Unique') + ) : medals[0].type === 0 ? ( + i18n('Silver') + ) : medals[0].type === 1 ? ( + i18n('Gold') + ) : medals[0].type === 2 ? ( + i18n('Platinum') + ) : ( + i18n('Theme') + )} +
+ +a + ? literalline + : { + 123: 12 + } + ? line + : softline + +const config = { + onFailure: onFailure !== undefined ? onFailure : ( + error => { + notify( + typeof error === 'string' ? + error + : error.message || 'ra.notification.http_error', + 'warning', + { + _: + typeof error === 'string' ? error + : error && error.message ? error.message + : undefined, + } + ); + refresh(); + } + ) +} + +showNotification( + typeof error === 'string' ? error : error.message || body, + level || 'warning', + { + messageArgs, + undoable: false, + } +) + +const result = children && !isEmptyChildren(children) + ? children + : props.match + ? component + ? React.createElement(component, props) + : render + ? render(props) + : null + : null; + +=====================================output===================================== +let icecream = + what == "cone" ? + (p) => (!!p ? \`here's your \${p} cone\` : \`just the empty cone for you\`) + : (p) => \`here's your \${p} \${what}\`; + +const value = + condition1 ? value1 + : condition2 ? value2 + : condition3 ? value3 + : value4; + +const StorybookLoader = ({ match }) => + match.params.storyId === "button" ? + : match.params.storyId === "color" ? + : match.params.storyId === "typography" ? + : match.params.storyId === "loading" ? + : match.params.storyId === "deal-list" ? + : + {"Missing story book"} + + + + ; + +const message = + i % 3 === 0 && i % 5 === 0 ? "fizzbuzz" + : i % 3 === 0 ? "fizz" + : i % 5 === 0 ? "buzz" + : String(i); + +const paymentMessage = + state == "success" ? "Payment completed successfully" + : state == "processing" ? "Payment processing" + : state == "invalid_cvc" ? "There was an issue with your CVC number" + : state == "invalid_expiry" ? "Expiry must be sometime in the past." + : "There was an issue with the payment. Please contact support."; + +const paymentMessage2 = + state == "success" ? + 1 //'Payment completed successfully' + : state == "processing" ? + 2 //'Payment processing' + : state == "invalid_cvc" ? + 3 //'There was an issue with your CVC number' + : ( + true //state == 'invalid_expiry' + ) ? + 4 //'Expiry must be sometime in the past.' + : 5; // 'There was an issue with the payment. Please contact support.' + +const foo = ( +
+ {medals[0].record ? + i18n("Record") + : medals[0].unique ? + i18n("Unique") + : medals[0].type === 0 ? + i18n("Silver") + : medals[0].type === 1 ? + i18n("Gold") + : medals[0].type === 2 ? + i18n("Platinum") + : i18n("Theme")} +
+); + +a ? literalline +: ( + { + 123: 12, + } +) ? + line +: softline; + +const config = { + onFailure: + onFailure !== undefined ? onFailure : ( + (error) => { + notify( + typeof error === "string" ? error : ( + error.message || "ra.notification.http_error" + ), + "warning", + { + _: + typeof error === "string" ? error + : error && error.message ? error.message + : undefined, + }, + ); + refresh(); + } + ), +}; + +showNotification( + typeof error === "string" ? error : error.message || body, + level || "warning", + { + messageArgs, + undoable: false, + }, +); + +const result = + children && !isEmptyChildren(children) ? children + : props.match ? + component ? React.createElement(component, props) + : render ? render(props) + : null + : null; + +================================================================================ +`; + exports[`nested.js - {"tabWidth":4} format 1`] = ` ====================================options===================================== parsers: ["babel", "flow", "typescript"] @@ -5372,6 +10624,350 @@ const result = ================================================================================ `; +exports[`nested-in-condition.js - {"experimentalTernaries":true,"tabWidth":4} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 + | printWidth +=====================================input====================================== +$var = ($number % 10 >= 2 && ($number % 100 < 10 || $number % 100 >= 20) +? kochabCooieGameOnOboleUnweave +: annularCooeedSplicesWalksWayWay) + ? anodyneCondosMalateOverateRetinol + : averredBathersBoxroomBuggyNurl; + +const value = (bifornCringerMoshedPerplexSawder +? askTrovenaBeenaDependsRowans +: glimseGlyphsHazardNoopsTieTie) + ? true + ? true + : false + : true + ? true + : false; + +(bifornCringerMoshedPerplexSawder ? ( + askTrovenaBeenaDependsRowans +) : ( + glimseGlyphsHazardNoopsTieTie +)) ? ( + + + + + + + + +) : ( + + + + + +); + +=====================================output===================================== +$var = + ( + $number % 10 >= 2 && ($number % 100 < 10 || $number % 100 >= 20) ? + kochabCooieGameOnOboleUnweave + : annularCooeedSplicesWalksWayWay + ) ? + anodyneCondosMalateOverateRetinol + : averredBathersBoxroomBuggyNurl; + +const value = + ( + bifornCringerMoshedPerplexSawder ? askTrovenaBeenaDependsRowans + : glimseGlyphsHazardNoopsTieTie + ) ? + true ? true + : false + : true ? true + : false; + +( + bifornCringerMoshedPerplexSawder ? askTrovenaBeenaDependsRowans + : glimseGlyphsHazardNoopsTieTie +) ? + + + + + + + + +: + + + + ; + +================================================================================ +`; + +exports[`nested-in-condition.js - {"experimentalTernaries":true,"useTabs":true,"tabWidth":4} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 +useTabs: true + | printWidth +=====================================input====================================== +$var = ($number % 10 >= 2 && ($number % 100 < 10 || $number % 100 >= 20) +? kochabCooieGameOnOboleUnweave +: annularCooeedSplicesWalksWayWay) + ? anodyneCondosMalateOverateRetinol + : averredBathersBoxroomBuggyNurl; + +const value = (bifornCringerMoshedPerplexSawder +? askTrovenaBeenaDependsRowans +: glimseGlyphsHazardNoopsTieTie) + ? true + ? true + : false + : true + ? true + : false; + +(bifornCringerMoshedPerplexSawder ? ( + askTrovenaBeenaDependsRowans +) : ( + glimseGlyphsHazardNoopsTieTie +)) ? ( + + + + + + + + +) : ( + + + + + +); + +=====================================output===================================== +$var = + ( + $number % 10 >= 2 && ($number % 100 < 10 || $number % 100 >= 20) ? + kochabCooieGameOnOboleUnweave + : annularCooeedSplicesWalksWayWay + ) ? + anodyneCondosMalateOverateRetinol + : averredBathersBoxroomBuggyNurl; + +const value = + ( + bifornCringerMoshedPerplexSawder ? askTrovenaBeenaDependsRowans + : glimseGlyphsHazardNoopsTieTie + ) ? + true ? true + : false + : true ? true + : false; + +( + bifornCringerMoshedPerplexSawder ? askTrovenaBeenaDependsRowans + : glimseGlyphsHazardNoopsTieTie +) ? + + + + + + + + +: + + + + ; + +================================================================================ +`; + +exports[`nested-in-condition.js - {"experimentalTernaries":true,"useTabs":true} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +useTabs: true + | printWidth +=====================================input====================================== +$var = ($number % 10 >= 2 && ($number % 100 < 10 || $number % 100 >= 20) +? kochabCooieGameOnOboleUnweave +: annularCooeedSplicesWalksWayWay) + ? anodyneCondosMalateOverateRetinol + : averredBathersBoxroomBuggyNurl; + +const value = (bifornCringerMoshedPerplexSawder +? askTrovenaBeenaDependsRowans +: glimseGlyphsHazardNoopsTieTie) + ? true + ? true + : false + : true + ? true + : false; + +(bifornCringerMoshedPerplexSawder ? ( + askTrovenaBeenaDependsRowans +) : ( + glimseGlyphsHazardNoopsTieTie +)) ? ( + + + + + + + + +) : ( + + + + + +); + +=====================================output===================================== +$var = + ( + $number % 10 >= 2 && ($number % 100 < 10 || $number % 100 >= 20) ? + kochabCooieGameOnOboleUnweave + : annularCooeedSplicesWalksWayWay + ) ? + anodyneCondosMalateOverateRetinol + : averredBathersBoxroomBuggyNurl; + +const value = + ( + bifornCringerMoshedPerplexSawder ? askTrovenaBeenaDependsRowans + : glimseGlyphsHazardNoopsTieTie + ) ? + true ? true + : false + : true ? true + : false; + +( + bifornCringerMoshedPerplexSawder ? askTrovenaBeenaDependsRowans + : glimseGlyphsHazardNoopsTieTie +) ? + + + + + + + + +: + + + + ; + +================================================================================ +`; + +exports[`nested-in-condition.js - {"experimentalTernaries":true} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +$var = ($number % 10 >= 2 && ($number % 100 < 10 || $number % 100 >= 20) +? kochabCooieGameOnOboleUnweave +: annularCooeedSplicesWalksWayWay) + ? anodyneCondosMalateOverateRetinol + : averredBathersBoxroomBuggyNurl; + +const value = (bifornCringerMoshedPerplexSawder +? askTrovenaBeenaDependsRowans +: glimseGlyphsHazardNoopsTieTie) + ? true + ? true + : false + : true + ? true + : false; + +(bifornCringerMoshedPerplexSawder ? ( + askTrovenaBeenaDependsRowans +) : ( + glimseGlyphsHazardNoopsTieTie +)) ? ( + + + + + + + + +) : ( + + + + + +); + +=====================================output===================================== +$var = + ( + $number % 10 >= 2 && ($number % 100 < 10 || $number % 100 >= 20) ? + kochabCooieGameOnOboleUnweave + : annularCooeedSplicesWalksWayWay + ) ? + anodyneCondosMalateOverateRetinol + : averredBathersBoxroomBuggyNurl; + +const value = + ( + bifornCringerMoshedPerplexSawder ? askTrovenaBeenaDependsRowans + : glimseGlyphsHazardNoopsTieTie + ) ? + true ? true + : false + : true ? true + : false; + +( + bifornCringerMoshedPerplexSawder ? askTrovenaBeenaDependsRowans + : glimseGlyphsHazardNoopsTieTie +) ? + + + + + + + + +: + + + + ; + +================================================================================ +`; + exports[`nested-in-condition.js - {"tabWidth":4} format 1`] = ` ====================================options===================================== parsers: ["babel", "flow", "typescript"] @@ -5728,6 +11324,174 @@ const value = ( ================================================================================ `; +exports[`parenthesis.js - {"experimentalTernaries":true,"tabWidth":4} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 + | printWidth +=====================================input====================================== +debug ? this.state.isVisible ? "partially visible" : "hidden" : null; +debug ? this.state.isVisible && somethingComplex ? "partially visible" : "hidden" : null; + +a => a ? () => {a} : () => {a} +a => a ? a : a +a => a ? aasdasdasdasdasdasdaaasdasdasdasdasdasdasdasdasdasdasdasdasdaaaaaa : a + +=====================================output===================================== +debug ? + this.state.isVisible ? + "partially visible" + : "hidden" +: null; +debug ? + this.state.isVisible && somethingComplex ? + "partially visible" + : "hidden" +: null; + +(a) => + a ? + () => { + a; + } + : () => { + a; + }; +(a) => (a ? a : a); +(a) => + a ? aasdasdasdasdasdasdaaasdasdasdasdasdasdasdasdasdasdasdasdasdaaaaaa : a; + +================================================================================ +`; + +exports[`parenthesis.js - {"experimentalTernaries":true,"useTabs":true,"tabWidth":4} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 +useTabs: true + | printWidth +=====================================input====================================== +debug ? this.state.isVisible ? "partially visible" : "hidden" : null; +debug ? this.state.isVisible && somethingComplex ? "partially visible" : "hidden" : null; + +a => a ? () => {a} : () => {a} +a => a ? a : a +a => a ? aasdasdasdasdasdasdaaasdasdasdasdasdasdasdasdasdasdasdasdasdaaaaaa : a + +=====================================output===================================== +debug ? + this.state.isVisible ? + "partially visible" + : "hidden" +: null; +debug ? + this.state.isVisible && somethingComplex ? + "partially visible" + : "hidden" +: null; + +(a) => + a ? + () => { + a; + } + : () => { + a; + }; +(a) => (a ? a : a); +(a) => + a ? aasdasdasdasdasdasdaaasdasdasdasdasdasdasdasdasdasdasdasdasdaaaaaa : a; + +================================================================================ +`; + +exports[`parenthesis.js - {"experimentalTernaries":true,"useTabs":true} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +useTabs: true + | printWidth +=====================================input====================================== +debug ? this.state.isVisible ? "partially visible" : "hidden" : null; +debug ? this.state.isVisible && somethingComplex ? "partially visible" : "hidden" : null; + +a => a ? () => {a} : () => {a} +a => a ? a : a +a => a ? aasdasdasdasdasdasdaaasdasdasdasdasdasdasdasdasdasdasdasdasdaaaaaa : a + +=====================================output===================================== +debug ? + this.state.isVisible ? + "partially visible" + : "hidden" +: null; +debug ? + this.state.isVisible && somethingComplex ? + "partially visible" + : "hidden" +: null; + +(a) => + a ? + () => { + a; + } + : () => { + a; + }; +(a) => (a ? a : a); +(a) => + a ? aasdasdasdasdasdasdaaasdasdasdasdasdasdasdasdasdasdasdasdasdaaaaaa : a; + +================================================================================ +`; + +exports[`parenthesis.js - {"experimentalTernaries":true} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +debug ? this.state.isVisible ? "partially visible" : "hidden" : null; +debug ? this.state.isVisible && somethingComplex ? "partially visible" : "hidden" : null; + +a => a ? () => {a} : () => {a} +a => a ? a : a +a => a ? aasdasdasdasdasdasdaaasdasdasdasdasdasdasdasdasdasdasdasdasdaaaaaa : a + +=====================================output===================================== +debug ? + this.state.isVisible ? + "partially visible" + : "hidden" +: null; +debug ? + this.state.isVisible && somethingComplex ? + "partially visible" + : "hidden" +: null; + +(a) => + a ? + () => { + a; + } + : () => { + a; + }; +(a) => (a ? a : a); +(a) => + a ? aasdasdasdasdasdasdaaasdasdasdasdasdasdasdasdasdasdasdasdasdaaaaaa : a; + +================================================================================ +`; + exports[`parenthesis.js - {"tabWidth":4} format 1`] = ` ====================================options===================================== parsers: ["babel", "flow", "typescript"] @@ -5876,6 +11640,270 @@ debug ================================================================================ `; +exports[`test.js - {"experimentalTernaries":true,"tabWidth":4} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 + | printWidth +=====================================input====================================== +const obj0 = conditionIsTruthy ? shortThing : otherShortThing + +const obj1 = conditionIsTruthy ? { some: 'long', object: 'with', lots: 'of', stuff } : shortThing + +const obj2 = conditionIsTruthy ? shortThing : { some: 'long', object: 'with', lots: 'of', stuff } + +const obj3 = conditionIsTruthy ? { some: 'eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger', object: 'with', lots: 'of', stuff } : shortThing + +const obj4 = conditionIsTruthy ? shortThing : { some: 'eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger', object: 'with', lots: 'of', stuff } + +const obj5 = conditionIsTruthy ? { some: 'long', object: 'with', lots: 'of', stuff } : { some: 'eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger', object: 'with', lots: 'of', stuff } + +=====================================output===================================== +const obj0 = conditionIsTruthy ? shortThing : otherShortThing; + +const obj1 = + conditionIsTruthy ? + { some: "long", object: "with", lots: "of", stuff } + : shortThing; + +const obj2 = + conditionIsTruthy ? shortThing : ( + { some: "long", object: "with", lots: "of", stuff } + ); + +const obj3 = + conditionIsTruthy ? + { + some: "eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger", + object: "with", + lots: "of", + stuff, + } + : shortThing; + +const obj4 = + conditionIsTruthy ? shortThing : ( + { + some: "eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger", + object: "with", + lots: "of", + stuff, + } + ); + +const obj5 = + conditionIsTruthy ? + { some: "long", object: "with", lots: "of", stuff } + : { + some: "eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger", + object: "with", + lots: "of", + stuff, + }; + +================================================================================ +`; + +exports[`test.js - {"experimentalTernaries":true,"useTabs":true,"tabWidth":4} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +tabWidth: 4 +useTabs: true + | printWidth +=====================================input====================================== +const obj0 = conditionIsTruthy ? shortThing : otherShortThing + +const obj1 = conditionIsTruthy ? { some: 'long', object: 'with', lots: 'of', stuff } : shortThing + +const obj2 = conditionIsTruthy ? shortThing : { some: 'long', object: 'with', lots: 'of', stuff } + +const obj3 = conditionIsTruthy ? { some: 'eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger', object: 'with', lots: 'of', stuff } : shortThing + +const obj4 = conditionIsTruthy ? shortThing : { some: 'eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger', object: 'with', lots: 'of', stuff } + +const obj5 = conditionIsTruthy ? { some: 'long', object: 'with', lots: 'of', stuff } : { some: 'eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger', object: 'with', lots: 'of', stuff } + +=====================================output===================================== +const obj0 = conditionIsTruthy ? shortThing : otherShortThing; + +const obj1 = + conditionIsTruthy ? + { some: "long", object: "with", lots: "of", stuff } + : shortThing; + +const obj2 = + conditionIsTruthy ? shortThing : ( + { some: "long", object: "with", lots: "of", stuff } + ); + +const obj3 = + conditionIsTruthy ? + { + some: "eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger", + object: "with", + lots: "of", + stuff, + } + : shortThing; + +const obj4 = + conditionIsTruthy ? shortThing : ( + { + some: "eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger", + object: "with", + lots: "of", + stuff, + } + ); + +const obj5 = + conditionIsTruthy ? + { some: "long", object: "with", lots: "of", stuff } + : { + some: "eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger", + object: "with", + lots: "of", + stuff, + }; + +================================================================================ +`; + +exports[`test.js - {"experimentalTernaries":true,"useTabs":true} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 +useTabs: true + | printWidth +=====================================input====================================== +const obj0 = conditionIsTruthy ? shortThing : otherShortThing + +const obj1 = conditionIsTruthy ? { some: 'long', object: 'with', lots: 'of', stuff } : shortThing + +const obj2 = conditionIsTruthy ? shortThing : { some: 'long', object: 'with', lots: 'of', stuff } + +const obj3 = conditionIsTruthy ? { some: 'eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger', object: 'with', lots: 'of', stuff } : shortThing + +const obj4 = conditionIsTruthy ? shortThing : { some: 'eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger', object: 'with', lots: 'of', stuff } + +const obj5 = conditionIsTruthy ? { some: 'long', object: 'with', lots: 'of', stuff } : { some: 'eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger', object: 'with', lots: 'of', stuff } + +=====================================output===================================== +const obj0 = conditionIsTruthy ? shortThing : otherShortThing; + +const obj1 = + conditionIsTruthy ? + { some: "long", object: "with", lots: "of", stuff } + : shortThing; + +const obj2 = + conditionIsTruthy ? shortThing : ( + { some: "long", object: "with", lots: "of", stuff } + ); + +const obj3 = + conditionIsTruthy ? + { + some: "eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger", + object: "with", + lots: "of", + stuff, + } + : shortThing; + +const obj4 = + conditionIsTruthy ? shortThing : ( + { + some: "eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger", + object: "with", + lots: "of", + stuff, + } + ); + +const obj5 = + conditionIsTruthy ? + { some: "long", object: "with", lots: "of", stuff } + : { + some: "eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger", + object: "with", + lots: "of", + stuff, + }; + +================================================================================ +`; + +exports[`test.js - {"experimentalTernaries":true} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +const obj0 = conditionIsTruthy ? shortThing : otherShortThing + +const obj1 = conditionIsTruthy ? { some: 'long', object: 'with', lots: 'of', stuff } : shortThing + +const obj2 = conditionIsTruthy ? shortThing : { some: 'long', object: 'with', lots: 'of', stuff } + +const obj3 = conditionIsTruthy ? { some: 'eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger', object: 'with', lots: 'of', stuff } : shortThing + +const obj4 = conditionIsTruthy ? shortThing : { some: 'eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger', object: 'with', lots: 'of', stuff } + +const obj5 = conditionIsTruthy ? { some: 'long', object: 'with', lots: 'of', stuff } : { some: 'eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger', object: 'with', lots: 'of', stuff } + +=====================================output===================================== +const obj0 = conditionIsTruthy ? shortThing : otherShortThing; + +const obj1 = + conditionIsTruthy ? + { some: "long", object: "with", lots: "of", stuff } + : shortThing; + +const obj2 = + conditionIsTruthy ? shortThing : ( + { some: "long", object: "with", lots: "of", stuff } + ); + +const obj3 = + conditionIsTruthy ? + { + some: "eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger", + object: "with", + lots: "of", + stuff, + } + : shortThing; + +const obj4 = + conditionIsTruthy ? shortThing : ( + { + some: "eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger", + object: "with", + lots: "of", + stuff, + } + ); + +const obj5 = + conditionIsTruthy ? + { some: "long", object: "with", lots: "of", stuff } + : { + some: "eeeeeeeeeeeeven looooooooooooooooooooooooooooooonger", + object: "with", + lots: "of", + stuff, + }; + +================================================================================ +`; + exports[`test.js - {"tabWidth":4} format 1`] = ` ====================================options===================================== parsers: ["babel", "flow", "typescript"] diff --git a/tests/format/js/ternaries/jsfmt.spec.js b/tests/format/js/ternaries/jsfmt.spec.js index b92a29be4..ff1e1b89f 100644 --- a/tests/format/js/ternaries/jsfmt.spec.js +++ b/tests/format/js/ternaries/jsfmt.spec.js @@ -5,3 +5,20 @@ run_spec(import.meta, ["babel", "flow", "typescript"], { useTabs: true, tabWidth: 4, }); + +run_spec(import.meta, ["babel", "flow", "typescript"], { + experimentalTernaries: true, +}); +run_spec(import.meta, ["babel", "flow", "typescript"], { + experimentalTernaries: true, + tabWidth: 4, +}); +run_spec(import.meta, ["babel", "flow", "typescript"], { + experimentalTernaries: true, + useTabs: true, +}); +run_spec(import.meta, ["babel", "flow", "typescript"], { + experimentalTernaries: true, + useTabs: true, + tabWidth: 4, +}); diff --git a/tests/format/typescript/conditional-types/__snapshots__/jsfmt.spec.js.snap b/tests/format/typescript/conditional-types/__snapshots__/jsfmt.spec.js.snap index bf39b4398..deb5f35f4 100644 --- a/tests/format/typescript/conditional-types/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/typescript/conditional-types/__snapshots__/jsfmt.spec.js.snap @@ -1,5 +1,166 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`comments.ts - {"experimentalTernaries":true} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +type A = B extends T + ? // comment + foo + : bar; + +type A = B extends test /* comment + comment + comment +*/ + ? foo + : bar; + +type T = test extends B + ? /* comment + comment + comment + comment + */ + foo + : bar; + +type T = test extends B + ? /* comment + comment + comment + comment + */ + foo + : test extends B + ? /* comment + comment + comment */ + foo + : bar; + +type T = test extends B + ? /* comment */ + foo + : bar; + +type T = test extends B + ? foo + : /* comment + comment + comment + comment + */ + bar; + +type T = test extends B + ? foo + : /* comment + comment + comment + comment + */ + test extends B + ? foo + : /* comment + comment + comment + */ + bar; + +type T = test extends B + ? foo + : /* comment */ + bar; + +type T = test extends B ? test extends B /* c +c */? foo : bar : bar; + +=====================================output===================================== +type A = + B extends T ? + // comment + foo + : bar; + +type A = + B extends ( + test /* comment + comment + comment +*/ + ) ? + foo + : bar; + +type T = + test extends B ? + /* comment + comment + comment + comment + */ + foo + : bar; + +type T = + test extends B ? + /* comment + comment + comment + comment + */ + foo + : test extends B ? + /* comment + comment + comment */ + foo + : bar; + +type T = test extends B ? /* comment */ foo : bar; + +type T = + test extends B ? foo + : /* comment + comment + comment + comment + */ + bar; + +type T = + test extends B ? foo + : /* comment + comment + comment + comment + */ + test extends B ? foo + : /* comment + comment + comment + */ + bar; + +type T = test extends B ? foo : /* comment */ bar; + +type T = + test extends B ? + test extends ( + B /* c +c */ + ) ? + foo + : bar + : bar; + +================================================================================ +`; + exports[`comments.ts format 1`] = ` ====================================options===================================== parsers: ["typescript"] @@ -152,6 +313,96 @@ c */ ================================================================================ `; +exports[`conditonal-types.ts - {"experimentalTernaries":true} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +export type DeepReadonly = T extends any[] ? DeepReadonlyArray : T extends object ? DeepReadonlyObject : T; + +type NonFunctionPropertyNames = { [K in keyof T]: T[K] extends Function ? never : K }[keyof T]; + +interface DeepReadonlyArray extends ReadonlyArray> {} + +type DeepReadonlyObject = { + readonly [P in NonFunctionPropertyNames]: DeepReadonly; +}; + +type TypeName = + T extends string ? "string" : + T extends number ? "number" : + T extends boolean ? "boolean" : + T extends undefined ? "undefined" : + T extends Function ? "function" : + "object"; + +type Type01 = 0 extends (1 extends 2 ? 3 : 4) ? 5 : 6; +type Type02 = 0 extends ((1 extends 2 ? 3 : 4)) ? 5 : 6; +type Type03 = 0 extends (((1 extends 2 ? 3 : 4))) ? 5 : 6; +type Type04 = 0 extends ((((1 extends 2 ? 3 : 4)))) ? 5 : 6; +type Type05 = (0 extends 1 ? 2 : 3) extends 4 ? 5 : 6; +type Type06 = ((0 extends 1 ? 2 : 3)) extends 4 ? 5 : 6; +type Type07 = (((0 extends 1 ? 2 : 3))) extends 4 ? 5 : 6; +type Type08 = ((((0 extends 1 ? 2 : 3)))) extends 4 ? 5 : 6; + +type T1 = () => void extends T ? U : V; +type T1a = () => (void extends T ? U : V); +type T1b = () => (void) extends T ? U : V; +type T2 = (() => void) extends T ? U : V; + +type U1 = new () => X extends T ? U : V; +type U1a = new () => (X extends T ? U : V); +type U1b = new () => (X) extends T ? U : V; +type U2 = (new () => X) extends T ? U : V; + +=====================================output===================================== +export type DeepReadonly = + T extends any[] ? DeepReadonlyArray + : T extends object ? DeepReadonlyObject + : T; + +type NonFunctionPropertyNames = { + [K in keyof T]: T[K] extends Function ? never : K; +}[keyof T]; + +interface DeepReadonlyArray extends ReadonlyArray> {} + +type DeepReadonlyObject = { + readonly [P in NonFunctionPropertyNames]: DeepReadonly; +}; + +type TypeName = + T extends string ? "string" + : T extends number ? "number" + : T extends boolean ? "boolean" + : T extends undefined ? "undefined" + : T extends Function ? "function" + : "object"; + +type Type01 = 0 extends (1 extends 2 ? 3 : 4) ? 5 : 6; +type Type02 = 0 extends (1 extends 2 ? 3 : 4) ? 5 : 6; +type Type03 = 0 extends (1 extends 2 ? 3 : 4) ? 5 : 6; +type Type04 = 0 extends (1 extends 2 ? 3 : 4) ? 5 : 6; +type Type05 = (0 extends 1 ? 2 : 3) extends 4 ? 5 : 6; +type Type06 = (0 extends 1 ? 2 : 3) extends 4 ? 5 : 6; +type Type07 = (0 extends 1 ? 2 : 3) extends 4 ? 5 : 6; +type Type08 = (0 extends 1 ? 2 : 3) extends 4 ? 5 : 6; + +type T1 = () => void extends T ? U : V; +type T1a = () => void extends T ? U : V; +type T1b = () => void extends T ? U : V; +type T2 = (() => void) extends T ? U : V; + +type U1 = new () => X extends T ? U : V; +type U1a = new () => X extends T ? U : V; +type U1b = new () => X extends T ? U : V; +type U2 = (new () => X) extends T ? U : V; + +================================================================================ +`; + exports[`conditonal-types.ts format 1`] = ` ====================================options===================================== parsers: ["typescript"] @@ -246,6 +497,34 @@ type U2 = (new () => X) extends T ? U : V; ================================================================================ `; +exports[`infer-type.ts - {"experimentalTernaries":true} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +type TestReturnType any> = T extends (...args: any[]) => infer R ? R : any; + +type Unpacked = + T extends (infer U)[] ? U : + T extends (...args: any[]) => infer U ? U : + T extends Promise ? U : + T; + +=====================================output===================================== +type TestReturnType any> = + T extends (...args: any[]) => infer R ? R : any; + +type Unpacked = + T extends (infer U)[] ? U + : T extends (...args: any[]) => infer U ? U + : T extends Promise ? U + : T; + +================================================================================ +`; + exports[`infer-type.ts format 1`] = ` ====================================options===================================== parsers: ["typescript"] @@ -278,6 +557,66 @@ type Unpacked = T extends (infer U)[] ================================================================================ `; +exports[`nested-in-condition.ts - {"experimentalTernaries":true} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +type Foo = + (ThingamabobberFactory extends AbstractThingamabobberFactory ? GobbledygookProvider : CompositeGobbledygookProvider) extends + DoubleGobbledygookProvider + ? UniqueDalgametreService + : CompositeZamazingoResolver; + +type Foo2 = + DoubleGobbledygookProvider extends + (ThingamabobberFactory extends AbstractThingamabobberFactory ? GobbledygookProvider : CompositeGobbledygookProvider) + ? UniqueDalgametreService + : CompositeZamazingoResolver; + +type Foo3 = + (ThingamabobberFactory extends AbstractThingamabobberFactory ? GobbledygookProvider : CompositeGobbledygookProvider) extends + (DoubleGobbledygookProvider extends MockGobbledygookProvider ? MockThingamabobberFactory : ThingamabobberFactory) + ? UniqueDalgametreService + : CompositeZamazingoResolver; + +=====================================output===================================== +type Foo = + ( + ThingamabobberFactory extends AbstractThingamabobberFactory ? + GobbledygookProvider + : CompositeGobbledygookProvider + ) extends DoubleGobbledygookProvider ? + UniqueDalgametreService + : CompositeZamazingoResolver; + +type Foo2 = + DoubleGobbledygookProvider extends ( + ThingamabobberFactory extends AbstractThingamabobberFactory ? + GobbledygookProvider + : CompositeGobbledygookProvider + ) ? + UniqueDalgametreService + : CompositeZamazingoResolver; + +type Foo3 = + ( + ThingamabobberFactory extends AbstractThingamabobberFactory ? + GobbledygookProvider + : CompositeGobbledygookProvider + ) extends ( + DoubleGobbledygookProvider extends MockGobbledygookProvider ? + MockThingamabobberFactory + : ThingamabobberFactory + ) ? + UniqueDalgametreService + : CompositeZamazingoResolver; + +================================================================================ +`; + exports[`nested-in-condition.ts format 1`] = ` ====================================options===================================== parsers: ["typescript"] @@ -334,6 +673,92 @@ type Foo3 = ( ================================================================================ `; +exports[`new-ternary-spec.ts - {"experimentalTernaries":true} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +// TypeScript has the same behavior, including a line break after =, but no parens around "conditional": +type KnownKeys = + { + [K in keyof T]: string extends K ? never + : number extends K ? never + : K; + } extends { [_ in keyof T]: infer U } ? + {} extends U ? never + : U + : never; + +type KnownKeysWithLongExtends = + { + [K in keyof T]: string extends K ? never + : number extends K ? never + : K; + } extends { + [_ in keyof T]: SomeReallyLongThingThatBreaksTheLine + } ? U + : never; + +// TypeScript examples: +type TypeName = + T extends string ? "string" + : T extends number ? "number" + : T extends boolean ? "boolean" + : T extends undefined ? "undefined" + : T extends Function ? "function" + : "object"; + +type Unpacked = + T extends (infer U)[] ? U + : T extends (...args: any[]) => infer U ? + SomeReallyLongThingThatBreaksTheLine + : T extends Promise ? U + : T; +=====================================output===================================== +// TypeScript has the same behavior, including a line break after =, but no parens around "conditional": +type KnownKeys = + { + [K in keyof T]: string extends K ? never + : number extends K ? never + : K; + } extends { [_ in keyof T]: infer U } ? + {} extends U ? + never + : U + : never; + +type KnownKeysWithLongExtends = + { + [K in keyof T]: string extends K ? never + : number extends K ? never + : K; + } extends { + [_ in keyof T]: SomeReallyLongThingThatBreaksTheLine; + } ? + U + : never; + +// TypeScript examples: +type TypeName = + T extends string ? "string" + : T extends number ? "number" + : T extends boolean ? "boolean" + : T extends undefined ? "undefined" + : T extends Function ? "function" + : "object"; + +type Unpacked = + T extends (infer U)[] ? U + : T extends (...args: any[]) => infer U ? + SomeReallyLongThingThatBreaksTheLine + : T extends Promise ? U + : T; + +================================================================================ +`; + exports[`new-ternary-spec.ts format 1`] = ` ====================================options===================================== parsers: ["typescript"] @@ -418,6 +843,63 @@ type Unpacked = T extends (infer U)[] ================================================================================ `; +exports[`parentheses.ts - {"experimentalTernaries":true} format 1`] = ` +====================================options===================================== +experimentalTernaries: true +parsers: ["typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +// #13275 +type Foo = T extends ((...a: any[]) => infer R extends string) ? R : never; +type Foo = T extends (new (...a: any[]) => infer R extends string) ? R : never; + +// #14275 +type Test = T extends (( + token: TSESTree.Token +) => token is infer U extends TSESTree.Token) + ? U + : TSESTree.Token; +type Test = T extends (( + token: TSESTree.Token +) => asserts token is infer U extends TSESTree.Token) + ? U + : TSESTree.Token; +type Test = T extends (new ( + token: TSESTree.Token +) => token is infer U extends TSESTree.Token) + ? U + : TSESTree.Token; + +=====================================output===================================== +// #13275 +type Foo = T extends ((...a: any[]) => infer R extends string) ? R : never; +type Foo = + T extends (new (...a: any[]) => infer R extends string) ? R : never; + +// #14275 +type Test = + T extends ( + ((token: TSESTree.Token) => token is infer U extends TSESTree.Token) + ) ? + U + : TSESTree.Token; +type Test = + T extends ( + ((token: TSESTree.Token) => asserts token is infer U extends TSESTree.Token) + ) ? + U + : TSESTree.Token; +type Test = + T extends ( + (new (token: TSESTree.Token) => token is infer U extends TSESTree.Token) + ) ? + U + : TSESTree.Token; + +================================================================================ +`; + exports[`parentheses.ts format 1`] = ` ====================================options===================================== parsers: ["typescript"] diff --git a/tests/format/typescript/conditional-types/jsfmt.spec.js b/tests/format/typescript/conditional-types/jsfmt.spec.js index 29084a9c8..e206f4645 100644 --- a/tests/format/typescript/conditional-types/jsfmt.spec.js +++ b/tests/format/typescript/conditional-types/jsfmt.spec.js @@ -1 +1,2 @@ run_spec(import.meta, ["typescript"]); +run_spec(import.meta, ["typescript"], { experimentalTernaries: true }); diff --git a/tests/integration/__tests__/__snapshots__/early-exit.js.snap b/tests/integration/__tests__/__snapshots__/early-exit.js.snap index f7f85b5d2..c75519ac4 100644 --- a/tests/integration/__tests__/__snapshots__/early-exit.js.snap +++ b/tests/integration/__tests__/__snapshots__/early-exit.js.snap @@ -53,6 +53,8 @@ Format options: --end-of-line Which end of line characters to apply. Defaults to lf. + --no-experimental-ternaries + Default behavior of ternaries; keep question marks on the same line as the consequent. --html-whitespace-sensitivity How to handle whitespaces in HTML. Defaults to css. @@ -218,6 +220,8 @@ Format options: --end-of-line Which end of line characters to apply. Defaults to lf. + --no-experimental-ternaries + Default behavior of ternaries; keep question marks on the same line as the consequent. --html-whitespace-sensitivity How to handle whitespaces in HTML. Defaults to css. diff --git a/tests/integration/__tests__/__snapshots__/help-options.js.snap b/tests/integration/__tests__/__snapshots__/help-options.js.snap index 9396d2ff6..960199f40 100644 --- a/tests/integration/__tests__/__snapshots__/help-options.js.snap +++ b/tests/integration/__tests__/__snapshots__/help-options.js.snap @@ -192,6 +192,18 @@ Default: lf" exports[`show detailed usage with --help end-of-line (write) 1`] = `[]`; +exports[`show detailed usage with --help experimental-ternaries (stderr) 1`] = `""`; + +exports[`show detailed usage with --help experimental-ternaries (stdout) 1`] = ` +"--experimental-ternaries + + Use curious ternaries, with the question mark after the condition. + +Default: false" +`; + +exports[`show detailed usage with --help experimental-ternaries (write) 1`] = `[]`; + exports[`show detailed usage with --help file-info (stderr) 1`] = `""`; exports[`show detailed usage with --help file-info (stdout) 1`] = ` @@ -370,6 +382,16 @@ exports[`show detailed usage with --help no-error-on-unmatched-pattern (stdout) exports[`show detailed usage with --help no-error-on-unmatched-pattern (write) 1`] = `[]`; +exports[`show detailed usage with --help no-experimental-ternaries (stderr) 1`] = `""`; + +exports[`show detailed usage with --help no-experimental-ternaries (stdout) 1`] = ` +"--no-experimental-ternaries + + Default behavior of ternaries; keep question marks on the same line as the consequent." +`; + +exports[`show detailed usage with --help no-experimental-ternaries (write) 1`] = `[]`; + exports[`show detailed usage with --help no-semi (stderr) 1`] = `""`; exports[`show detailed usage with --help no-semi (stdout) 1`] = ` diff --git a/tests/integration/__tests__/__snapshots__/plugin-options-string.js.snap b/tests/integration/__tests__/__snapshots__/plugin-options-string.js.snap index 5c6e9deba..149499c4b 100644 --- a/tests/integration/__tests__/__snapshots__/plugin-options-string.js.snap +++ b/tests/integration/__tests__/__snapshots__/plugin-options-string.js.snap @@ -17,12 +17,12 @@ exports[`show external options with \`--help\` 1`] = ` - First value + Second value -@@ -22,16 +22,18 @@ - Control how Prettier formats quoted code embedded in the file. - Defaults to auto. +@@ -24,16 +24,18 @@ --end-of-line Which end of line characters to apply. Defaults to lf. + --no-experimental-ternaries + Default behavior of ternaries; keep question marks on the same line as the consequent. + --foo-string foo description + Defaults to bar. --html-whitespace-sensitivity diff --git a/tests/integration/__tests__/__snapshots__/plugin-options.js.snap b/tests/integration/__tests__/__snapshots__/plugin-options.js.snap index e59649807..d4f522b35 100644 --- a/tests/integration/__tests__/__snapshots__/plugin-options.js.snap +++ b/tests/integration/__tests__/__snapshots__/plugin-options.js.snap @@ -59,12 +59,12 @@ exports[`show external options with \`--help\` 1`] = ` - First value + Second value -@@ -22,16 +22,18 @@ - Control how Prettier formats quoted code embedded in the file. - Defaults to auto. +@@ -24,16 +24,18 @@ --end-of-line Which end of line characters to apply. Defaults to lf. + --no-experimental-ternaries + Default behavior of ternaries; keep question marks on the same line as the consequent. + --foo-option foo description + Defaults to bar. --html-whitespace-sensitivity diff --git a/tests/integration/__tests__/__snapshots__/schema.js.snap b/tests/integration/__tests__/__snapshots__/schema.js.snap index 60091c856..971261fa8 100644 --- a/tests/integration/__tests__/__snapshots__/schema.js.snap +++ b/tests/integration/__tests__/__snapshots__/schema.js.snap @@ -89,6 +89,11 @@ This option cannot be used with --range-start and --range-end.", }, ], }, + "experimentalTernaries": { + "default": false, + "description": "Use curious ternaries, with the question mark after the condition.", + "type": "boolean", + }, "filepath": { "default": undefined, "description": "Specify the input filepath. This will be used to do parser inference.", diff --git a/tests/integration/__tests__/__snapshots__/support-info.js.snap b/tests/integration/__tests__/__snapshots__/support-info.js.snap index e65afbdb1..f1bb66336 100644 --- a/tests/integration/__tests__/__snapshots__/support-info.js.snap +++ b/tests/integration/__tests__/__snapshots__/support-info.js.snap @@ -130,6 +130,10 @@ exports[`API getSupportInfo() 1`] = ` "default": "lf", "type": "choice", }, + "experimentalTernaries": { + "default": false, + "type": "boolean", + }, "filepath": { "default": undefined, "type": "path", @@ -851,6 +855,15 @@ exports[`CLI --support-info (stdout) 1`] = ` "pluginDefaults": {}, "type": "choice" }, + { + "category": "JavaScript", + "default": false, + "description": "Use curious ternaries, with the question mark after the condition.", + "name": "experimentalTernaries", + "oppositeDescription": "Default behavior of ternaries; keep question marks on the same line as the consequent.", + "pluginDefaults": {}, + "type": "boolean" + }, { "category": "Special", "description": "Specify the input filepath. This will be used to do parser inference.",