fix(javascript): no regression for jsx in arrow function in jsx (#5343)

master
Ika 2018-11-06 15:38:30 +08:00 committed by GitHub
parent dbe86abc24
commit b6691ba615
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 247 additions and 138 deletions

View File

@ -4874,11 +4874,9 @@ function printMemberChain(path, options, print) {
printIndentedGroup(groups.slice(shouldMerge ? 2 : 1)) printIndentedGroup(groups.slice(shouldMerge ? 2 : 1))
]); ]);
const callExpressionCount = printedNodes.filter( const callExpressions = printedNodes
tuple => .map(({ node }) => node)
tuple.node.type === "CallExpression" || .filter(isCallOrOptionalCallExpression);
tuple.node.type === "OptionalCallExpression"
).length;
// We don't want to print in one line if there's: // We don't want to print in one line if there's:
// * A comment. // * 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 the last group is a function it's okay to inline if it fits.
if ( if (
hasComment || hasComment ||
callExpressionCount >= 3 || callExpressions.length >= 3 ||
printedGroups.slice(0, -1).some(willBreak) 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); 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) { function isJSXNode(node) {
return ( return (
node.type === "JSXElement" || node.type === "JSXElement" ||
@ -5443,12 +5460,11 @@ function maybeWrapJSXElementInParens(path, elem) {
return elem; return elem;
} }
const shouldBreak = const shouldBreak = matchAncestorTypes(path, [
matchAncestorTypes(path, [ "ArrowFunctionExpression",
"ArrowFunctionExpression", "CallExpression",
"CallExpression", "JSXExpressionContainer"
"JSXExpressionContainer" ]);
]) && isMemberExpressionChain(path.getParentNode(1).callee);
return group( return group(
concat([ concat([
@ -6144,7 +6160,7 @@ function isTestCall(n, parent) {
} }
if (n.arguments.length === 1) { if (n.arguments.length === 1) {
if (isAngularTestWrapper(n) && parent && isTestCall(parent)) { if (isAngularTestWrapper(n) && parent && isTestCall(parent)) {
return isFunctionOrArrowExpression(n.arguments[0].type); return isFunctionOrArrowExpression(n.arguments[0]);
} }
if (isUnitTestSetUp(n)) { if (isUnitTestSetUp(n)) {
@ -6161,7 +6177,7 @@ function isTestCall(n, parent) {
return false; return false;
} }
return ( return (
(isFunctionOrArrowExpression(n.arguments[1].type) && (isFunctionOrArrowExpression(n.arguments[1]) &&
n.arguments[1].params.length <= 1) || n.arguments[1].params.length <= 1) ||
isAngularTestWrapper(n.arguments[1]) isAngularTestWrapper(n.arguments[1])
); );
@ -6199,8 +6215,11 @@ function isAngularTestWrapper(node) {
); );
} }
function isFunctionOrArrowExpression(type) { function isFunctionOrArrowExpression(node) {
return type === "FunctionExpression" || type === "ArrowFunctionExpression"; return (
node.type === "FunctionExpression" ||
node.type === "ArrowFunctionExpression"
);
} }
function isUnitTestSetUp(n) { function isUnitTestSetUp(n) {

View File

@ -1782,6 +1782,16 @@ exports[`expression.js - flow-verify 1`] = `
}); });
}} }}
</Component>; </Component>;
<SuspendyTree>
<div style={{ height: 200, overflow: "scroll" }}>
{Array(20)
.fill()
.map((_, i) => (
<h2 key={i}>{i + 1}</h2>
))}
</div>
</SuspendyTree>;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<View <View
style={{ style={{
@ -1917,6 +1927,16 @@ exports[`expression.js - flow-verify 1`] = `
}} }}
</Component>; </Component>;
<SuspendyTree>
<div style={{ height: 200, overflow: "scroll" }}>
{Array(20)
.fill()
.map((_, i) => (
<h2 key={i}>{i + 1}</h2>
))}
</div>
</SuspendyTree>;
`; `;
exports[`expression.js - flow-verify 2`] = ` exports[`expression.js - flow-verify 2`] = `
@ -2041,6 +2061,16 @@ exports[`expression.js - flow-verify 2`] = `
}); });
}} }}
</Component>; </Component>;
<SuspendyTree>
<div style={{ height: 200, overflow: "scroll" }}>
{Array(20)
.fill()
.map((_, i) => (
<h2 key={i}>{i + 1}</h2>
))}
</div>
</SuspendyTree>;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<View <View
style={{ style={{
@ -2176,6 +2206,16 @@ exports[`expression.js - flow-verify 2`] = `
}} }}
</Component>; </Component>;
<SuspendyTree>
<div style={{ height: 200, overflow: "scroll" }}>
{Array(20)
.fill()
.map((_, i) => (
<h2 key={i}>{i + 1}</h2>
))}
</div>
</SuspendyTree>;
`; `;
exports[`expression.js - flow-verify 3`] = ` exports[`expression.js - flow-verify 3`] = `
@ -2300,6 +2340,16 @@ exports[`expression.js - flow-verify 3`] = `
}); });
}} }}
</Component>; </Component>;
<SuspendyTree>
<div style={{ height: 200, overflow: "scroll" }}>
{Array(20)
.fill()
.map((_, i) => (
<h2 key={i}>{i + 1}</h2>
))}
</div>
</SuspendyTree>;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<View <View
style={{ style={{
@ -2435,6 +2485,16 @@ exports[`expression.js - flow-verify 3`] = `
}} }}
</Component>; </Component>;
<SuspendyTree>
<div style={{ height: 200, overflow: 'scroll' }}>
{Array(20)
.fill()
.map((_, i) => (
<h2 key={i}>{i + 1}</h2>
))}
</div>
</SuspendyTree>;
`; `;
exports[`expression.js - flow-verify 4`] = ` exports[`expression.js - flow-verify 4`] = `
@ -2559,6 +2619,16 @@ exports[`expression.js - flow-verify 4`] = `
}); });
}} }}
</Component>; </Component>;
<SuspendyTree>
<div style={{ height: 200, overflow: "scroll" }}>
{Array(20)
.fill()
.map((_, i) => (
<h2 key={i}>{i + 1}</h2>
))}
</div>
</SuspendyTree>;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<View <View
style={{ style={{
@ -2694,6 +2764,16 @@ exports[`expression.js - flow-verify 4`] = `
}} }}
</Component>; </Component>;
<SuspendyTree>
<div style={{ height: 200, overflow: 'scroll' }}>
{Array(20)
.fill()
.map((_, i) => (
<h2 key={i}>{i + 1}</h2>
))}
</div>
</SuspendyTree>;
`; `;
exports[`flow_fix_me.js - flow-verify 1`] = ` exports[`flow_fix_me.js - flow-verify 1`] = `

View File

@ -1,121 +1,131 @@
<View <View
style={ style={
{ {
someVeryLongStyle1: "true", someVeryLongStyle1: "true",
someVeryLongStyle2: "true", someVeryLongStyle2: "true",
someVeryLongStyle3: "true", someVeryLongStyle3: "true",
someVeryLongStyle4: "true" someVeryLongStyle4: "true"
} }
} }
/>; />;
<View <View
style={ style={
[ [
{ {
someVeryLongStyle1: "true", someVeryLongStyle1: "true",
someVeryLongStyle2: "true", someVeryLongStyle2: "true",
someVeryLongStyle3: "true", someVeryLongStyle3: "true",
someVeryLongStyle4: "true" someVeryLongStyle4: "true"
} }
] ]
} }
/>; />;
<Something> <Something>
{() => ( {() => (
<SomethingElse> <SomethingElse>
<span /> <span />
</SomethingElse> </SomethingElse>
)} )}
</Something>; </Something>;
<Something> <Something>
{items.map(item => ( {items.map(item => (
<SomethingElse> <SomethingElse>
<span /> <span />
</SomethingElse> </SomethingElse>
))} ))}
</Something>; </Something>;
<Something> <Something>
{function() { {function() {
return ( return (
<SomethingElse> <SomethingElse>
<span /> <span />
</SomethingElse> </SomethingElse>
); );
}} }}
</Something>; </Something>;
<RadioListItem <RadioListItem
key={option} key={option}
imageSource={this.props.veryBigItemImageSourceFunc && imageSource={this.props.veryBigItemImageSourceFunc &&
this.props.veryBigItemImageSourceFunc(option)} this.props.veryBigItemImageSourceFunc(option)}
imageSize={this.props.veryBigItemImageSize} imageSize={this.props.veryBigItemImageSize}
imageView={this.props.veryBigItemImageViewFunc && imageView={this.props.veryBigItemImageViewFunc &&
this.props.veryBigItemImageViewFunc(option)} this.props.veryBigItemImageViewFunc(option)}
heading={this.props.displayTextFunc(option)} heading={this.props.displayTextFunc(option)}
value={option} value={option}
/>; />;
<ParentComponent prop={ <ParentComponent prop={
<Child> <Child>
test test
</Child> </Child>
}/>; }/>;
<BookingIntroPanel <BookingIntroPanel
prop="long_string_make_to_force_break" prop="long_string_make_to_force_break"
logClick={data => doLogClick("short", "short", data)} logClick={data => doLogClick("short", "short", data)}
/>; />;
<BookingIntroPanel <BookingIntroPanel
logClick={data => logClick={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)
} }
/>; />;
<BookingIntroPanel <BookingIntroPanel
logClick={data => { logClick={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)
}} }}
/>; />;
<Component <Component
onChange={( onChange={(
key: "possible_key_1" | "possible_key_2" | "possible_key_3", key: "possible_key_1" | "possible_key_2" | "possible_key_3",
value: string | Immutable.List<string>, value: string | Immutable.List<string>,
) => { ) => {
this.setState({ this.setState({
updatedTask: this.state.updatedTask.set(key, value) updatedTask: this.state.updatedTask.set(key, value)
}); });
}} }}
/>; />;
<BookingIntroPanel> <BookingIntroPanel>
{data => doLogClick("short", "short", data)} {data => doLogClick("short", "short", data)}
</BookingIntroPanel>; </BookingIntroPanel>;
<BookingIntroPanel> <BookingIntroPanel>
{data => {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)
} }
</BookingIntroPanel>; </BookingIntroPanel>;
<BookingIntroPanel> <BookingIntroPanel>
{data => { {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)
}} }}
</BookingIntroPanel>; </BookingIntroPanel>;
<Component> <Component>
{( {(
key: "possible_key_1" | "possible_key_2" | "possible_key_3", key: "possible_key_1" | "possible_key_2" | "possible_key_3",
value: string | Immutable.List<string>, value: string | Immutable.List<string>,
) => { ) => {
this.setState({ this.setState({
updatedTask: this.state.updatedTask.set(key, value) updatedTask: this.state.updatedTask.set(key, value)
}); });
}} }}
</Component>; </Component>;
<SuspendyTree>
<div style={{ height: 200, overflow: "scroll" }}>
{Array(20)
.fill()
.map((_, i) => (
<h2 key={i}>{i + 1}</h2>
))}
</div>
</SuspendyTree>;