diff --git a/src/language-js/comments/handle-comments.js b/src/language-js/comments/handle-comments.js index 1a5e63ddc..3f7c91b3a 100644 --- a/src/language-js/comments/handle-comments.js +++ b/src/language-js/comments/handle-comments.js @@ -83,6 +83,7 @@ function handleOwnLineComment(context) { handleCommentsInDestructuringPattern, handleTSMappedTypeComments, handleBinaryCastExpressionComment, + handleUnionTypeLeadingComments, ].some((fn) => fn(context)); } @@ -137,6 +138,7 @@ function handleRemainingComment(context) { handleTSFunctionTrailingComments, handleParenthesizedExpressionTrailingComment, handleBinaryCastExpressionComment, + handleUnionTypeLeadingComments, ].some((fn) => fn(context)); } @@ -1113,6 +1115,33 @@ function handleParenthesizedExpressionTrailingComment({ return false; } +/** + * @param {CommentContext} context + * @returns {boolean} + */ +function handleUnionTypeLeadingComments({ + followingNode, + comment, + text, + options, +}) { + if ( + isUnionType(followingNode) && + isBlockComment(comment) && + isSingleLineComment(comment, text) && + !isPrettierIgnoreComment(comment) + ) { + const text = stripComments(options); + const textBetween = text.slice(locEnd(comment), locStart(followingNode)); + if (/^[ \t]*$/.test(textBetween)) { + addLeadingComment(followingNode.types[0], comment); + return true; + } + } + + return false; +} + const isRealFunctionLikeNode = createTypeCheckFunction([ "ArrowFunctionExpression", "FunctionExpression", diff --git a/tests/config/format-test/failed-format-tests.js b/tests/config/format-test/failed-format-tests.js index a99242a90..9e5a66486 100644 --- a/tests/config/format-test/failed-format-tests.js +++ b/tests/config/format-test/failed-format-tests.js @@ -34,6 +34,7 @@ const unstableTests = new Map( "js/arrows/arrow-chain-with-trailing-comments.js", "typescript/as/comments/18160.ts", "js/sequence-expression/parenthesized-trailing-comment-unstable.js", + "typescript/union/consistent-with-flow/single-type.ts", ].map((fixture) => { const [file, isUnstable = () => true] = Array.isArray(fixture) ? fixture diff --git a/tests/format/flow/union/__snapshots__/format.test.js.snap b/tests/format/flow/union/__snapshots__/format.test.js.snap index 5096f672d..427fc17a9 100644 --- a/tests/format/flow/union/__snapshots__/format.test.js.snap +++ b/tests/format/flow/union/__snapshots__/format.test.js.snap @@ -22,6 +22,60 @@ const myValue = (callcallcallcallcallcall( ================================================================================ `; +exports[`issue-1197-2.js format 1`] = ` +====================================options===================================== +parsers: ["flow"] + printWidth: 80 (default) | +=====================================input====================================== +// https://github.com/prettier/prettier/issues/1197#issuecomment-496620145 + +type RecordDataType = {| + type: 'Record', + /** Fields */ + fields: {[string]: DataType}, + /** + * Meta + */ + meta?: /** + * Custom layouts allow you to provide your own layout. + * Example for conditionally showing the interface of one setting based on the value of another. + */ + | {| + layout: 'Custom', + |} + /** + * The None layout, embeds Record children directly with no wrapping layout. + */ + | {|layout: 'None'|}, +|}; + +=====================================output===================================== +// https://github.com/prettier/prettier/issues/1197#issuecomment-496620145 + +type RecordDataType = {| + type: "Record", + /** Fields */ + fields: { [string]: DataType }, + /** + * Meta + */ + meta?: + /** + * Custom layouts allow you to provide your own layout. + * Example for conditionally showing the interface of one setting based on the value of another. + */ + | {| + layout: "Custom", + |} + /** + * The None layout, embeds Record children directly with no wrapping layout. + */ + | {| layout: "None" |}, +|}; + +================================================================================ +`; + exports[`union.js format 1`] = ` ====================================options===================================== parsers: ["flow"] diff --git a/tests/format/flow/union/issue-1197-2.js b/tests/format/flow/union/issue-1197-2.js new file mode 100644 index 000000000..ee00bede0 --- /dev/null +++ b/tests/format/flow/union/issue-1197-2.js @@ -0,0 +1,21 @@ +// https://github.com/prettier/prettier/issues/1197#issuecomment-496620145 + +type RecordDataType = {| + type: 'Record', + /** Fields */ + fields: {[string]: DataType}, + /** + * Meta + */ + meta?: /** + * Custom layouts allow you to provide your own layout. + * Example for conditionally showing the interface of one setting based on the value of another. + */ + | {| + layout: 'Custom', + |} + /** + * The None layout, embeds Record children directly with no wrapping layout. + */ + | {|layout: 'None'|}, +|}; diff --git a/tests/format/typescript/union/13080.ts b/tests/format/typescript/union/13080.ts new file mode 100644 index 000000000..35eeee5db --- /dev/null +++ b/tests/format/typescript/union/13080.ts @@ -0,0 +1,7 @@ +type Foo = { + arg: + // comment + | string + // other + | number +} diff --git a/tests/format/typescript/union/__snapshots__/format.test.js.snap b/tests/format/typescript/union/__snapshots__/format.test.js.snap index f4e6a8989..7e53a5c56 100644 --- a/tests/format/typescript/union/__snapshots__/format.test.js.snap +++ b/tests/format/typescript/union/__snapshots__/format.test.js.snap @@ -163,6 +163,31 @@ export interface ProductStatus { ================================================================================ `; +exports[`13080.ts format 1`] = ` +====================================options===================================== +parsers: ["typescript"] + printWidth: 80 (default) | +=====================================input====================================== +type Foo = { + arg: + // comment + | string + // other + | number +} + +=====================================output===================================== +type Foo = { + arg: + // comment + | string + // other + | number; +}; + +================================================================================ +`; + exports[`inlining.ts format 1`] = ` ====================================options===================================== parsers: ["typescript"] diff --git a/tests/format/typescript/union/consistent-with-flow/__snapshots__/format.test.js.snap b/tests/format/typescript/union/consistent-with-flow/__snapshots__/format.test.js.snap index 4d5c070c5..a8bc55828 100644 --- a/tests/format/typescript/union/consistent-with-flow/__snapshots__/format.test.js.snap +++ b/tests/format/typescript/union/consistent-with-flow/__snapshots__/format.test.js.snap @@ -257,6 +257,86 @@ type A = T extends "arrow" ================================================================================ `; +exports[`leading-comments.ts format 1`] = ` +====================================options===================================== +parsers: ["typescript", "flow"] + printWidth: 80 (default) | +=====================================input====================================== +type T1 = + /* comment */ A + | /* A comment long enough to make the union type break into multiple lines */ B; +type T12 = + /* comment */ | A + | /* A comment long enough to make the union type break into multiple lines */ B; +type T13 = + | /* comment */ A + | /* A comment long enough to make the union type break into multiple lines */ B; + +type T2 = /* comment */ 'A' + | /* A comment long enough to make the union type break into multiple lines */ B; + +type T3 = // comment + 'A' + | /* A comment long enough to make the union type break into multiple lines */ B; + +type T4 = + // comment + 'A' + | /* A comment long enough to make the union type break into multiple lines */ B; + +type T5 = + /** + comment + */ 'A' + | /* A comment long enough to make the union type break into multiple lines */ B; + +type T6 = + /** + comment + */ + 'A' + | /* A comment long enough to make the union type break into multiple lines */ B; + +=====================================output===================================== +type T1 = + | /* comment */ A + | /* A comment long enough to make the union type break into multiple lines */ B; +type T12 = + | /* comment */ A + | /* A comment long enough to make the union type break into multiple lines */ B; +type T13 = + | /* comment */ A + | /* A comment long enough to make the union type break into multiple lines */ B; + +type T2 = + | /* comment */ "A" + | /* A comment long enough to make the union type break into multiple lines */ B; + +type T3 = // comment + | "A" + | /* A comment long enough to make the union type break into multiple lines */ B; + +type T4 = + // comment + | "A" + | /* A comment long enough to make the union type break into multiple lines */ B; + +type T5 = + /** + comment + */ | "A" + | /* A comment long enough to make the union type break into multiple lines */ B; + +type T6 = + /** + comment + */ + | "A" + | /* A comment long enough to make the union type break into multiple lines */ B; + +================================================================================ +`; + exports[`prettier-ignore.ts format 1`] = ` ====================================options===================================== parsers: ["typescript", "flow"] diff --git a/tests/format/typescript/union/consistent-with-flow/leading-comments.ts b/tests/format/typescript/union/consistent-with-flow/leading-comments.ts new file mode 100644 index 000000000..97943b20b --- /dev/null +++ b/tests/format/typescript/union/consistent-with-flow/leading-comments.ts @@ -0,0 +1,34 @@ +type T1 = + /* comment */ A + | /* A comment long enough to make the union type break into multiple lines */ B; +type T12 = + /* comment */ | A + | /* A comment long enough to make the union type break into multiple lines */ B; +type T13 = + | /* comment */ A + | /* A comment long enough to make the union type break into multiple lines */ B; + +type T2 = /* comment */ 'A' + | /* A comment long enough to make the union type break into multiple lines */ B; + +type T3 = // comment + 'A' + | /* A comment long enough to make the union type break into multiple lines */ B; + +type T4 = + // comment + 'A' + | /* A comment long enough to make the union type break into multiple lines */ B; + +type T5 = + /** + comment + */ 'A' + | /* A comment long enough to make the union type break into multiple lines */ B; + +type T6 = + /** + comment + */ + 'A' + | /* A comment long enough to make the union type break into multiple lines */ B;