Skip to content

Commit

Permalink
Hug object types in function parameters in Flow like in TS (prettier#…
Browse files Browse the repository at this point in the history
  • Loading branch information
thorn0 authored and medikoo committed Jan 31, 2024
1 parent 26bc7d9 commit 44827b6
Show file tree
Hide file tree
Showing 7 changed files with 158 additions and 25 deletions.
21 changes: 21 additions & 0 deletions changelog_unreleased/flow/13396.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#### An object type in a `declare function` signature now breaks before the return type (#13396 by @thorn0)

This behavior has been unified with how TypeScript is formatted.

<!-- prettier-ignore -->
```jsx
// Input
declare function bla (props: { a: boolean, b: string, c: number }): Promise<Array<foo>>

// Prettier stable
declare function bla(props: { a: boolean, b: string, c: number }): Promise<
Array<foo>
>;

// Prettier main
declare function bla(props: {
a: boolean;
b: string;
c: number;
}): Promise<Array<foo>>;
```
9 changes: 5 additions & 4 deletions src/language-js/print/function-parameters.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ function printFunctionParameters(

const parent = path.getParentNode();
const isParametersInTestCall = isTestCall(parent);
const shouldHugParameters = shouldHugFunctionParameters(functionNode);
const shouldHugParameters = shouldHugTheOnlyFunctionParameter(functionNode);
const printed = [];
iterateFunctionParametersPath(path, (parameterPath, index) => {
const isLastParameter = index === parameters.length - 1;
Expand Down Expand Up @@ -157,7 +157,7 @@ function printFunctionParameters(
];
}

function shouldHugFunctionParameters(node) {
function shouldHugTheOnlyFunctionParameter(node) {
if (!node) {
return false;
}
Expand All @@ -176,7 +176,8 @@ function shouldHugFunctionParameters(node) {
parameter.typeAnnotation.type === "TSTypeAnnotation") &&
isObjectType(parameter.typeAnnotation.typeAnnotation)) ||
(parameter.type === "FunctionTypeParam" &&
isObjectType(parameter.typeAnnotation)) ||
isObjectType(parameter.typeAnnotation) &&
parameter !== node.rest) ||
(parameter.type === "AssignmentPattern" &&
(parameter.left.type === "ObjectPattern" ||
parameter.left.type === "ArrayPattern") &&
Expand Down Expand Up @@ -283,6 +284,6 @@ function isDecoratedFunction(path) {

export {
printFunctionParameters,
shouldHugFunctionParameters,
shouldHugTheOnlyFunctionParameter,
shouldGroupFunctionParameters,
};
47 changes: 26 additions & 21 deletions src/language-js/print/object.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ import {
getComments,
CommentCheckFlags,
isNextLineEmpty,
isObjectType,
} from "../utils/index.js";
import { locStart, locEnd } from "../loc.js";

const isIdentifierName = esutils.keyword.isIdentifierNameES5;
import { printOptionalToken, printTypeAnnotation } from "./misc.js";
import { shouldHugFunctionParameters } from "./function-parameters.js";
import { shouldHugType } from "./type-annotation.js";
import { shouldHugTheOnlyFunctionParameter } from "./function-parameters.js";
import { printHardlineAfterHeritage } from "./class.js";

/** @typedef {import("../../document/builders.js").Doc} Doc */
Expand Down Expand Up @@ -179,26 +179,21 @@ function printObject(path, options, print) {
if (
path.match(
(node) => node.type === "ObjectPattern" && !node.decorators,
(node, name, number) =>
shouldHugFunctionParameters(node) &&
(name === "params" ||
name === "parameters" ||
name === "this" ||
name === "rest") &&
number === 0
) ||
path.match(
shouldHugType,
(node, name) => name === "typeAnnotation",
(node, name) => name === "typeAnnotation",
(node, name, number) =>
shouldHugFunctionParameters(node) &&
(name === "params" ||
name === "parameters" ||
name === "this" ||
name === "rest") &&
number === 0
shouldHugTheOnlyParameter
) ||
(isObjectType(node) &&
(path.match(
undefined,
(node, name) => name === "typeAnnotation",
(node, name) => name === "typeAnnotation",
shouldHugTheOnlyParameter
) ||
path.match(
undefined,
(node, name) =>
node.type === "FunctionTypeParam" && name === "typeAnnotation",
shouldHugTheOnlyParameter
))) ||
// Assignment printing logic (printAssignment) is responsible
// for adding a group if needed
(!shouldBreak &&
Expand All @@ -215,4 +210,14 @@ function printObject(path, options, print) {
return group(content, { shouldBreak });
}

function shouldHugTheOnlyParameter(node, name) {
return (
(name === "params" ||
name === "parameters" ||
name === "this" ||
name === "rest") &&
shouldHugTheOnlyFunctionParameter(node)
);
}

export { printObject };
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,45 @@ const X = (props: { a: boolean }) => <A />;
================================================================================
`;

exports[`object-type-in-declare-function.js format 1`] = `
====================================options=====================================
parsers: ["flow", "babel"]
printWidth: 80
| printWidth
=====================================input======================================
declare function foo(this: { a: boolean, b: string, c: number }):
Promise<Array<foo>>
declare function bazFlip({ a: boolean, b: string, c: number }):
Promise<Array<foo>>
declare function bar(...{ a: boolean, b: string, c: number }):
Promise<Array<foo>>
declare function bar(...x: { a: boolean, b: string, c: number }):
Promise<Array<foo>>
=====================================output=====================================
declare function foo(this: {
a: boolean,
b: string,
c: number,
}): Promise<Array<foo>>;
declare function bazFlip({
a: boolean,
b: string,
c: number,
}): Promise<Array<foo>>;
declare function bar(
...{ a: boolean, b: string, c: number }
): Promise<Array<foo>>;
declare function bar(
...x: { a: boolean, b: string, c: number }
): Promise<Array<foo>>;
================================================================================
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
declare function foo(this: { a: boolean, b: string, c: number }):
Promise<Array<foo>>

declare function bazFlip({ a: boolean, b: string, c: number }):
Promise<Array<foo>>

declare function bar(...{ a: boolean, b: string, c: number }):
Promise<Array<foo>>

declare function bar(...x: { a: boolean, b: string, c: number }):
Promise<Array<foo>>
42 changes: 42 additions & 0 deletions tests/format/typescript/declare/__snapshots__/jsfmt.spec.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -213,3 +213,45 @@ class C {
================================================================================
`;
exports[`object-type-in-declare-function.ts format 1`] = `
====================================options=====================================
parsers: ["typescript"]
printWidth: 80
| printWidth
=====================================input======================================
declare function foo(this: { a: boolean, b: string, c: number }):
Promise<Array<foo>>
declare function bazFlip({ a: boolean, b: string, c: number }):
Promise<Array<foo>>
declare function bar(...{ a: boolean, b: string, c: number }):
Promise<Array<foo>>
declare function bar(...x: { a: boolean, b: string, c: number }):
Promise<Array<foo>>
=====================================output=====================================
declare function foo(this: {
a: boolean;
b: string;
c: number;
}): Promise<Array<foo>>;
declare function bazFlip({
a: boolean,
b: string,
c: number,
}): Promise<Array<foo>>;
declare function bar(
...{ a: boolean, b: string, c: number }
): Promise<Array<foo>>;
declare function bar(
...x: { a: boolean; b: string; c: number }
): Promise<Array<foo>>;
================================================================================
`;
11 changes: 11 additions & 0 deletions tests/format/typescript/declare/object-type-in-declare-function.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
declare function foo(this: { a: boolean, b: string, c: number }):
Promise<Array<foo>>

declare function bazFlip({ a: boolean, b: string, c: number }):
Promise<Array<foo>>

declare function bar(...{ a: boolean, b: string, c: number }):
Promise<Array<foo>>

declare function bar(...x: { a: boolean, b: string, c: number }):
Promise<Array<foo>>

0 comments on commit 44827b6

Please sign in to comment.