diff --git a/src/printer.js b/src/printer.js index 272c6f42..c8448ee8 100644 --- a/src/printer.js +++ b/src/printer.js @@ -737,7 +737,7 @@ function genericPrintNoParens(path, options, print, args) { case "ObjectPattern": case "ObjectTypeAnnotation": case "TSInterfaceDeclaration": - case "TSTypeLiteral": + case "TSTypeLiteral": { var isTypeAnnotation = n.type === "ObjectTypeAnnotation"; var isTypeScriptTypeAnnotaion = n.type === "TSTypeLiteral"; var isTypeScriptInterfaceDeclaration = n.type === "TSInterfaceDeclaration"; @@ -849,11 +849,16 @@ function genericPrintNoParens(path, options, print, args) { // If we inline the object as first argument of the parent, we don't want // to create another group so that the object breaks before the return // type + const parentParentParent = path.getParentNode(2); if ( - n.type === "ObjectPattern" && - parent.params && - parent.params.length === 1 && - parent.params[0] === n + (n.type === "ObjectPattern" && + parent && + shouldHugArguments(parent) && + parent.params[0] === n) || + (n.type === "ObjectTypeAnnotation" && + parentParentParent && + shouldHugArguments(parentParentParent) && + parentParentParent.params[0].typeAnnotation.typeAnnotation === n) ) { return content; } @@ -867,7 +872,7 @@ function genericPrintNoParens(path, options, print, args) { ); return group(content, { shouldBreak }); - + } case "PropertyPattern": return concat([ path.call(print, "key"), @@ -2636,15 +2641,7 @@ function printFunctionParams(path, print, options, expandArg) { // b, // c // }) {} - if ( - fun.params && - fun.params.length === 1 && - !fun.params[0].comments && - (fun.params[0].type === "ObjectPattern" || - (fun.params[0].type === "FunctionTypeParam" && - fun.params[0].typeAnnotation.type === "ObjectTypeAnnotation")) && - !fun.rest - ) { + if (shouldHugArguments(fun)) { return concat(["(", join(", ", printed), ")"]); } @@ -3912,6 +3909,23 @@ function isNodeStartingWithDeclare(node, options) { ); } +function shouldHugArguments(fun) { + return ( + fun && + fun.params && + fun.params.length === 1 && + !fun.params[0].comments && + (fun.params[0].type === "ObjectPattern" || + (fun.params[0].type === "Identifier" && + fun.params[0].typeAnnotation && + fun.params[0].typeAnnotation.type === "TypeAnnotation" && + fun.params[0].typeAnnotation.typeAnnotation.type === "ObjectTypeAnnotation") || + fun.params[0].type === "FunctionTypeParam" && + fun.params[0].typeAnnotation.type === "ObjectTypeAnnotation") && + !fun.rest + ); +} + function printArrayItems(path, options, printPath, print) { const printedElements = []; let separatorParts = []; diff --git a/tests/flow/dictionary/__snapshots__/jsfmt.spec.js.snap b/tests/flow/dictionary/__snapshots__/jsfmt.spec.js.snap index d615ad39..63af8160 100644 --- a/tests/flow/dictionary/__snapshots__/jsfmt.spec.js.snap +++ b/tests/flow/dictionary/__snapshots__/jsfmt.spec.js.snap @@ -43,9 +43,9 @@ function foo0( return x; } -function foo2( - x: { [key: string]: number } -): { [key: string]: number, +toString: () => string } { +function foo2(x: { + [key: string]: number +}): { [key: string]: number, +toString: () => string } { // x's prototype has a toString method return x; } @@ -448,9 +448,9 @@ function mix_with_declared_props(o: { [k: number]: X, p: Y }, x: X, y: Y) { } // Indeed, dict types are still Objects and have Object.prototype stuff -function object_prototype( - o: { [k: string]: number } -): { [k: string]: number, +toString: () => string } { +function object_prototype(o: { + [k: string]: number +}): { [k: string]: number, +toString: () => string } { (o.toString(): boolean); // error: string ~> boolean return o; // ok } @@ -458,9 +458,10 @@ function object_prototype( // **UNSOUND** // Because we support non-string props w/ bracket notation, it's possible to // write into a declared prop unsoundly. -function unsound_string_conversion_alias_declared_prop( - o: { [k: number]: any, "0": X } -) { +function unsound_string_conversion_alias_declared_prop(o: { + [k: number]: any, + "0": X +}) { o[0] = "not-x"; // a["0"] no longer X } @@ -748,9 +749,9 @@ function foo3(x: { [key: string]: number }): { foo: number } { } // error: foo can't exist in x -function foo4( - x: { [key: string]: number } -): { [key: string]: number, foo: string } { +function foo4(x: { + [key: string]: number +}): { [key: string]: number, foo: string } { return x; } diff --git a/tests/flow/enumerror/__snapshots__/jsfmt.spec.js.snap b/tests/flow/enumerror/__snapshots__/jsfmt.spec.js.snap index 882eb7c0..a1d5b174 100644 --- a/tests/flow/enumerror/__snapshots__/jsfmt.spec.js.snap +++ b/tests/flow/enumerror/__snapshots__/jsfmt.spec.js.snap @@ -30,15 +30,13 @@ function union2keys(s: Union): Keys { return s; } // ok ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /** @flow */ -function isActive( - ad: { - state: $Keys<{ - PAUSED: string, - ACTIVE: string, - DELETED: string - }> - } -): boolean { +function isActive(ad: { + state: $Keys<{ + PAUSED: string, + ACTIVE: string, + DELETED: string + }> +}): boolean { return ad.state === "ACTIVE"; } isActive({ state: "PAUSE" }); diff --git a/tests/function_single_destructuring/__snapshots__/jsfmt.spec.js.snap b/tests/function_single_destructuring/__snapshots__/jsfmt.spec.js.snap index 75fc1e01..fb8784d4 100644 --- a/tests/function_single_destructuring/__snapshots__/jsfmt.spec.js.snap +++ b/tests/function_single_destructuring/__snapshots__/jsfmt.spec.js.snap @@ -61,6 +61,11 @@ type T = ({ title: number, items: number, }) => void; + +const X = (props: { + a: boolean, +}) => + ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ function StatelessFunctionalComponent({ isActive, @@ -123,4 +128,6 @@ type T = ({ items: number }) => void; +const X = (props: { a: boolean }) => ; + `; diff --git a/tests/function_single_destructuring/test.js b/tests/function_single_destructuring/test.js index 0ef346de..10137b48 100644 --- a/tests/function_single_destructuring/test.js +++ b/tests/function_single_destructuring/test.js @@ -58,3 +58,8 @@ type T = ({ title: number, items: number, }) => void; + +const X = (props: { + a: boolean, +}) => + ;