diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index b215fa67..722bfde0 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -4874,11 +4874,9 @@ function printMemberChain(path, options, print) { printIndentedGroup(groups.slice(shouldMerge ? 2 : 1)) ]); - const callExpressionCount = printedNodes.filter( - tuple => - tuple.node.type === "CallExpression" || - tuple.node.type === "OptionalCallExpression" - ).length; + const callExpressions = printedNodes + .map(({ node }) => node) + .filter(isCallOrOptionalCallExpression); // We don't want to print in one line if there's: // * A comment. @@ -4887,8 +4885,21 @@ function printMemberChain(path, options, print) { // If the last group is a function it's okay to inline if it fits. if ( hasComment || - callExpressionCount >= 3 || - printedGroups.slice(0, -1).some(willBreak) + callExpressions.length >= 3 || + printedGroups.slice(0, -1).some(willBreak) || + /** + * scopes.filter(scope => scope.value !== '').map((scope, i) => { + * // multi line content + * }) + */ + (((lastGroupDoc, lastGroupNode) => + isCallOrOptionalCallExpression(lastGroupNode) && willBreak(lastGroupDoc))( + getLast(printedGroups), + getLast(getLast(groups)).node + ) && + callExpressions + .slice(0, -1) + .some(n => n.arguments.some(isFunctionOrArrowExpression))) ) { return group(expanded); } @@ -4902,6 +4913,12 @@ function printMemberChain(path, options, print) { ]); } +function isCallOrOptionalCallExpression(node) { + return ( + node.type === "CallExpression" || node.type === "OptionalCallExpression" + ); +} + function isJSXNode(node) { return ( node.type === "JSXElement" || @@ -5443,12 +5460,11 @@ function maybeWrapJSXElementInParens(path, elem) { return elem; } - const shouldBreak = - matchAncestorTypes(path, [ - "ArrowFunctionExpression", - "CallExpression", - "JSXExpressionContainer" - ]) && isMemberExpressionChain(path.getParentNode(1).callee); + const shouldBreak = matchAncestorTypes(path, [ + "ArrowFunctionExpression", + "CallExpression", + "JSXExpressionContainer" + ]); return group( concat([ @@ -6144,7 +6160,7 @@ function isTestCall(n, parent) { } if (n.arguments.length === 1) { if (isAngularTestWrapper(n) && parent && isTestCall(parent)) { - return isFunctionOrArrowExpression(n.arguments[0].type); + return isFunctionOrArrowExpression(n.arguments[0]); } if (isUnitTestSetUp(n)) { @@ -6161,7 +6177,7 @@ function isTestCall(n, parent) { return false; } return ( - (isFunctionOrArrowExpression(n.arguments[1].type) && + (isFunctionOrArrowExpression(n.arguments[1]) && n.arguments[1].params.length <= 1) || isAngularTestWrapper(n.arguments[1]) ); @@ -6199,8 +6215,11 @@ function isAngularTestWrapper(node) { ); } -function isFunctionOrArrowExpression(type) { - return type === "FunctionExpression" || type === "ArrowFunctionExpression"; +function isFunctionOrArrowExpression(node) { + return ( + node.type === "FunctionExpression" || + node.type === "ArrowFunctionExpression" + ); } function isUnitTestSetUp(n) { diff --git a/tests/jsx/__snapshots__/jsfmt.spec.js.snap b/tests/jsx/__snapshots__/jsfmt.spec.js.snap index 6554eb70..491a2f6d 100644 --- a/tests/jsx/__snapshots__/jsfmt.spec.js.snap +++ b/tests/jsx/__snapshots__/jsfmt.spec.js.snap @@ -1782,6 +1782,16 @@ exports[`expression.js - flow-verify 1`] = ` }); }} ; + + +
+ {Array(20) + .fill() + .map((_, i) => ( +

{i + 1}

+ ))} +
+
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; + +
+ {Array(20) + .fill() + .map((_, i) => ( +

{i + 1}

+ ))} +
+
; + `; exports[`expression.js - flow-verify 2`] = ` @@ -2041,6 +2061,16 @@ exports[`expression.js - flow-verify 2`] = ` }); }} ; + + +
+ {Array(20) + .fill() + .map((_, i) => ( +

{i + 1}

+ ))} +
+
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; + +
+ {Array(20) + .fill() + .map((_, i) => ( +

{i + 1}

+ ))} +
+
; + `; exports[`expression.js - flow-verify 3`] = ` @@ -2300,6 +2340,16 @@ exports[`expression.js - flow-verify 3`] = ` }); }} ; + + +
+ {Array(20) + .fill() + .map((_, i) => ( +

{i + 1}

+ ))} +
+
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; + +
+ {Array(20) + .fill() + .map((_, i) => ( +

{i + 1}

+ ))} +
+
; + `; exports[`expression.js - flow-verify 4`] = ` @@ -2559,6 +2619,16 @@ exports[`expression.js - flow-verify 4`] = ` }); }} ; + + +
+ {Array(20) + .fill() + .map((_, i) => ( +

{i + 1}

+ ))} +
+
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; + +
+ {Array(20) + .fill() + .map((_, i) => ( +

{i + 1}

+ ))} +
+
; + `; exports[`flow_fix_me.js - flow-verify 1`] = ` diff --git a/tests/jsx/expression.js b/tests/jsx/expression.js index 2276b7d6..ec999447 100644 --- a/tests/jsx/expression.js +++ b/tests/jsx/expression.js @@ -1,121 +1,131 @@ -; - -; - - - {() => ( - - - - )} -; - - - {items.map(item => ( - - - - ))} -; - - - {function() { - return ( - - - - ); - }} -; - -; - - - test - -}/>; - - doLogClick("short", "short", data)} -/>; - - - doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data) - } -/>; - - { - doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data) - }} -/>; - -, - ) => { - this.setState({ - updatedTask: this.state.updatedTask.set(key, value) - }); - }} -/>; - - - {data => doLogClick("short", "short", data)} -; - - - {data => - doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data) - } -; - - - {data => { - doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data) - }} -; - - - {( - key: "possible_key_1" | "possible_key_2" | "possible_key_3", - value: string | Immutable.List, - ) => { - this.setState({ - updatedTask: this.state.updatedTask.set(key, value) - }); - }} -; +; + +; + + + {() => ( + + + + )} +; + + + {items.map(item => ( + + + + ))} +; + + + {function() { + return ( + + + + ); + }} +; + +; + + + test + +}/>; + + doLogClick("short", "short", data)} +/>; + + + doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data) + } +/>; + + { + doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data) + }} +/>; + +, + ) => { + this.setState({ + updatedTask: this.state.updatedTask.set(key, value) + }); + }} +/>; + + + {data => doLogClick("short", "short", data)} +; + + + {data => + doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data) + } +; + + + {data => { + doLogClick("long_name_long_name_long_name", "long_name_long_name_long_name", data) + }} +; + + + {( + key: "possible_key_1" | "possible_key_2" | "possible_key_3", + value: string | Immutable.List, + ) => { + this.setState({ + updatedTask: this.state.updatedTask.set(key, value) + }); + }} +; + + +
+ {Array(20) + .fill() + .map((_, i) => ( +

{i + 1}

+ ))} +
+
;