diff --git a/changelog_unreleased/javascript/12075.md b/changelog_unreleased/javascript/12075.md new file mode 100644 index 000000000..4b136d048 --- /dev/null +++ b/changelog_unreleased/javascript/12075.md @@ -0,0 +1,18 @@ +#### Print end-of-line comment for `continue`/`break` statements (#12075 by @sosukesuzuki) + + + + +```jsx +// Input +for (;;) continue // comment +; + +// Prettier stable +Error: Comment "comment" was not printed. Please report this error! + +// Prettier main +for (;;) + continue; // comment + +``` diff --git a/src/language-js/comments.js b/src/language-js/comments.js index f908647ac..eef7a99c4 100644 --- a/src/language-js/comments.js +++ b/src/language-js/comments.js @@ -68,6 +68,7 @@ function handleOwnLineComment(context) { handleAssignmentPatternComments, handleMethodNameComments, handleLabeledStatementComments, + handleBreakAndContinueStatementComments, ].some((fn) => fn(context)); } @@ -91,6 +92,7 @@ function handleEndOfLineComment(context) { handleOnlyComments, handleTypeAliasComments, handleVariableDeclaratorComments, + handleBreakAndContinueStatementComments, ].some((fn) => fn(context)); } diff --git a/tests/config/format-test.js b/tests/config/format-test.js index 41d5091fc..93fbaff04 100644 --- a/tests/config/format-test.js +++ b/tests/config/format-test.js @@ -39,6 +39,7 @@ const unstableTests = new Map( ["flow/no-semi/comments.js", (options) => options.semi === false], "typescript/prettier-ignore/mapped-types.ts", "js/comments/html-like/comment.js", + "js/for/continue-and-break-comment-without-blocks.js", ].map((fixture) => { const [file, isUnstable = () => true] = Array.isArray(fixture) ? fixture diff --git a/tests/format/js/for/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/for/__snapshots__/jsfmt.spec.js.snap index 376878d65..69f2556fe 100644 --- a/tests/format/js/for/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/js/for/__snapshots__/jsfmt.spec.js.snap @@ -74,6 +74,709 @@ for (x of y); ================================================================================ `; +exports[`continue-and-break-comment-1.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +for(;;) { + continue // comment + ; +} + +for (;;) { + break // comment + ; +} + +for (const f of []) { + continue // comment + ; +} + +for (const f of []) { + break // comment + ; +} + +for (const f in {}) { + continue // comment + ; +} + +for (const f in {}) { + break // comment + ; +} + +while(true) { + continue // comment + ; +} + +while (true) { + break // comment + ; +} + +do { + continue // comment + ; +} while(true); + + +do { + break // comment + ; +} while(true); + +label1: for (;;) { + continue label1 // comment + ; +} + +label2: { + break label2 // comment + ; +}; + +for(;;) { + continue /* comment */ + ; +} + +for (;;) { + break /* comment */ + ; +} + +for (const f of []) { + continue /* comment */ + ; +} + +for (const f of []) { + break /* comment */ + ; +} + +for (const f in {}) { + continue /* comment */ + ; +} + +for (const f in {}) { + break /* comment */ + ; +} + +while(true) { + continue /* comment */ + ; +} + +while (true) { + break /* comment */ + ; +} + +do { + continue /* comment */ + ; +} while(true); + + +do { + break /* comment */ + ; +} while(true); + +label1: for (;;) { + continue label1 /* comment */ + ; +} + +label2: { + break label2 /* comment */ + ; +}; + +=====================================output===================================== +for (;;) { + continue; // comment +} + +for (;;) { + break; // comment +} + +for (const f of []) { + continue; // comment +} + +for (const f of []) { + break; // comment +} + +for (const f in {}) { + continue; // comment +} + +for (const f in {}) { + break; // comment +} + +while (true) { + continue; // comment +} + +while (true) { + break; // comment +} + +do { + continue; // comment +} while (true); + +do { + break; // comment +} while (true); + +label1: for (;;) { + continue label1; // comment +} + +label2: { + break label2; // comment +} + +for (;;) { + continue; /* comment */ +} + +for (;;) { + break; /* comment */ +} + +for (const f of []) { + continue; /* comment */ +} + +for (const f of []) { + break; /* comment */ +} + +for (const f in {}) { + continue; /* comment */ +} + +for (const f in {}) { + break; /* comment */ +} + +while (true) { + continue; /* comment */ +} + +while (true) { + break; /* comment */ +} + +do { + continue; /* comment */ +} while (true); + +do { + break; /* comment */ +} while (true); + +label1: for (;;) { + continue label1 /* comment */; +} + +label2: { + break label2 /* comment */; +} + +================================================================================ +`; + +exports[`continue-and-break-comment-2.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +for(;;) { + continue + // comment + ; +} + +for (;;) { + break + // comment + ; +} + +for (const f of []) { + continue + // comment + ; +} + +for (const f of []) { + break + // comment + ; +} + +for (const f in {}) { + continue + // comment + ; +} + +for (const f in {}) { + break + // comment + ; +} + +while(true) { + continue + // comment + ; +} + +while (true) { + break + // comment + ; +} + +do { + continue + // comment + ; +} while(true); + + +do { + break + // comment + ; +} while(true); + +label1: for (;;) { + continue label1 + // comment + ; +} + +label2: { + break label2 + // comment + ; +}; + +for(;;) { + continue + /* comment */ + ; +} + +for (;;) { + break + /* comment */ + ; +} + +for (const f of []) { + continue + /* comment */ + ; +} + +for (const f of []) { + break + /* comment */ + ; +} + +for (const f in {}) { + continue + /* comment */ + ; +} + +for (const f in {}) { + break + /* comment */ + ; +} + +while(true) { + continue + /* comment */ + ; +} + +while (true) { + break + /* comment */ + ; +} + +do { + continue + /* comment */ + ; +} while(true); + + +do { + break + /* comment */ + ; +} while(true); + +label1: for (;;) { + continue label1 + /* comment */ + ; +} + +label2: { + break label2 + /* comment */ + ; +}; + +=====================================output===================================== +for (;;) { + continue; + // comment +} + +for (;;) { + break; + // comment +} + +for (const f of []) { + continue; + // comment +} + +for (const f of []) { + break; + // comment +} + +for (const f in {}) { + continue; + // comment +} + +for (const f in {}) { + break; + // comment +} + +while (true) { + continue; + // comment +} + +while (true) { + break; + // comment +} + +do { + continue; + // comment +} while (true); + +do { + break; + // comment +} while (true); + +label1: for (;;) { + continue label1; + // comment +} + +label2: { + break label2; + // comment +} + +for (;;) { + continue; + /* comment */ +} + +for (;;) { + break; + /* comment */ +} + +for (const f of []) { + continue; + /* comment */ +} + +for (const f of []) { + break; + /* comment */ +} + +for (const f in {}) { + continue; + /* comment */ +} + +for (const f in {}) { + break; + /* comment */ +} + +while (true) { + continue; + /* comment */ +} + +while (true) { + break; + /* comment */ +} + +do { + continue; + /* comment */ +} while (true); + +do { + break; + /* comment */ +} while (true); + +label1: for (;;) { + continue label1; + /* comment */ +} + +label2: { + break label2; + /* comment */ +} + +================================================================================ +`; + +exports[`continue-and-break-comment-without-blocks.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +for(;;) continue +// comment +; + +for (;;) break +// comment +; + +for (const f of []) continue +// comment +; + +for (const f of []) break +// comment +; + +for (const f in {}) continue +// comment +; + +for (const f in {}) break +// comment +; + +for(;;) continue // comment +; + +for (;;) break // comment +; + +for (const f of []) continue // comment +; + +for (const f of []) break // comment +; + +for (const f in {}) continue // comment +; + +for (const f in {}) break // comment +; + +for(;;) continue /* comment */ +; + +for (;;) break /* comment */ +; + +for (const f of []) continue /* comment */ +; + +for (const f of []) break /* comment */ +; + +for (const f in {}) continue /* comment */ +; + +for (const f in {}) break /* comment */ +; + +for(;;) continue +/* comment */ +; + +for (;;) break +/* comment */ +; + +for (const f of []) continue +/* comment */ +; + +for (const f of []) break +/* comment */ +; + +for (const f in {}) continue +/* comment */ +; + +for (const f in {}) break +/* comment */ +; + +label1: for (;;) continue label1 /* comment */ +; + +label1: for (;;) continue label1 +/* comment */ +; + +label1: for (;;) continue label1 // comment +; + +label1: for (;;) continue label1 +// comment +; + +=====================================output===================================== +for (;;) + continue; + // comment + +for (;;) + break; + // comment + +for (const f of []) + continue; + // comment + +for (const f of []) + break; + // comment + +for (const f in {}) + continue; + // comment + +for (const f in {}) + break; + // comment + +for (;;) + continue; // comment + +for (;;) + break; // comment + +for (const f of []) + continue; // comment + +for (const f of []) + break; // comment + +for (const f in {}) + continue; // comment + +for (const f in {}) + break; // comment + +for (;;) continue; /* comment */ + +for (;;) break; /* comment */ + +for (const f of []) continue; /* comment */ + +for (const f of []) break; /* comment */ + +for (const f in {}) continue; /* comment */ + +for (const f in {}) break; /* comment */ + +for (;;) + continue; + /* comment */ + +for (;;) + break; + /* comment */ + +for (const f of []) + continue; + /* comment */ + +for (const f of []) + break; + /* comment */ + +for (const f in {}) + continue; + /* comment */ + +for (const f in {}) + break; + /* comment */ + +label1: for (;;) continue label1 /* comment */; + +label1: for (;;) + continue label1; + /* comment */ + +label1: for (;;) + continue label1; // comment + +label1: for (;;) + continue label1; + // comment + +================================================================================ +`; + exports[`for.js format 1`] = ` ====================================options===================================== parsers: ["babel", "flow", "typescript"] diff --git a/tests/format/js/for/continue-and-break-comment-1.js b/tests/format/js/for/continue-and-break-comment-1.js new file mode 100644 index 000000000..bd83a9f64 --- /dev/null +++ b/tests/format/js/for/continue-and-break-comment-1.js @@ -0,0 +1,121 @@ +for(;;) { + continue // comment + ; +} + +for (;;) { + break // comment + ; +} + +for (const f of []) { + continue // comment + ; +} + +for (const f of []) { + break // comment + ; +} + +for (const f in {}) { + continue // comment + ; +} + +for (const f in {}) { + break // comment + ; +} + +while(true) { + continue // comment + ; +} + +while (true) { + break // comment + ; +} + +do { + continue // comment + ; +} while(true); + + +do { + break // comment + ; +} while(true); + +label1: for (;;) { + continue label1 // comment + ; +} + +label2: { + break label2 // comment + ; +}; + +for(;;) { + continue /* comment */ + ; +} + +for (;;) { + break /* comment */ + ; +} + +for (const f of []) { + continue /* comment */ + ; +} + +for (const f of []) { + break /* comment */ + ; +} + +for (const f in {}) { + continue /* comment */ + ; +} + +for (const f in {}) { + break /* comment */ + ; +} + +while(true) { + continue /* comment */ + ; +} + +while (true) { + break /* comment */ + ; +} + +do { + continue /* comment */ + ; +} while(true); + + +do { + break /* comment */ + ; +} while(true); + +label1: for (;;) { + continue label1 /* comment */ + ; +} + +label2: { + break label2 /* comment */ + ; +}; diff --git a/tests/format/js/for/continue-and-break-comment-2.js b/tests/format/js/for/continue-and-break-comment-2.js new file mode 100644 index 000000000..49d46016f --- /dev/null +++ b/tests/format/js/for/continue-and-break-comment-2.js @@ -0,0 +1,145 @@ +for(;;) { + continue + // comment + ; +} + +for (;;) { + break + // comment + ; +} + +for (const f of []) { + continue + // comment + ; +} + +for (const f of []) { + break + // comment + ; +} + +for (const f in {}) { + continue + // comment + ; +} + +for (const f in {}) { + break + // comment + ; +} + +while(true) { + continue + // comment + ; +} + +while (true) { + break + // comment + ; +} + +do { + continue + // comment + ; +} while(true); + + +do { + break + // comment + ; +} while(true); + +label1: for (;;) { + continue label1 + // comment + ; +} + +label2: { + break label2 + // comment + ; +}; + +for(;;) { + continue + /* comment */ + ; +} + +for (;;) { + break + /* comment */ + ; +} + +for (const f of []) { + continue + /* comment */ + ; +} + +for (const f of []) { + break + /* comment */ + ; +} + +for (const f in {}) { + continue + /* comment */ + ; +} + +for (const f in {}) { + break + /* comment */ + ; +} + +while(true) { + continue + /* comment */ + ; +} + +while (true) { + break + /* comment */ + ; +} + +do { + continue + /* comment */ + ; +} while(true); + + +do { + break + /* comment */ + ; +} while(true); + +label1: for (;;) { + continue label1 + /* comment */ + ; +} + +label2: { + break label2 + /* comment */ + ; +}; diff --git a/tests/format/js/for/continue-and-break-comment-without-blocks.js b/tests/format/js/for/continue-and-break-comment-without-blocks.js new file mode 100644 index 000000000..d68bba16e --- /dev/null +++ b/tests/format/js/for/continue-and-break-comment-without-blocks.js @@ -0,0 +1,97 @@ +for(;;) continue +// comment +; + +for (;;) break +// comment +; + +for (const f of []) continue +// comment +; + +for (const f of []) break +// comment +; + +for (const f in {}) continue +// comment +; + +for (const f in {}) break +// comment +; + +for(;;) continue // comment +; + +for (;;) break // comment +; + +for (const f of []) continue // comment +; + +for (const f of []) break // comment +; + +for (const f in {}) continue // comment +; + +for (const f in {}) break // comment +; + +for(;;) continue /* comment */ +; + +for (;;) break /* comment */ +; + +for (const f of []) continue /* comment */ +; + +for (const f of []) break /* comment */ +; + +for (const f in {}) continue /* comment */ +; + +for (const f in {}) break /* comment */ +; + +for(;;) continue +/* comment */ +; + +for (;;) break +/* comment */ +; + +for (const f of []) continue +/* comment */ +; + +for (const f of []) break +/* comment */ +; + +for (const f in {}) continue +/* comment */ +; + +for (const f in {}) break +/* comment */ +; + +label1: for (;;) continue label1 /* comment */ +; + +label1: for (;;) continue label1 +/* comment */ +; + +label1: for (;;) continue label1 // comment +; + +label1: for (;;) continue label1 +// comment +; diff --git a/tests/format/misc/errors/typescript/__snapshots__/jsfmt.spec.js.snap b/tests/format/misc/errors/typescript/__snapshots__/jsfmt.spec.js.snap index b0f014358..842ce1a00 100644 --- a/tests/format/misc/errors/typescript/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/misc/errors/typescript/__snapshots__/jsfmt.spec.js.snap @@ -23,8 +23,6 @@ exports[`invalid-jsx-1.ts [typescript] format 1`] = ` 4 |" `; -exports[`issue-8773.ts [typescript] format 1`] = `"Comment \\"comment\\" was not printed. Please report this error!"`; - exports[`module-attributes-static.ts [typescript] format 1`] = ` "';' expected. (1:28) > 1 | import foo from \\"foo.json\\" with type: \\"json\\"; diff --git a/tests/format/misc/errors/typescript/issue-8773.ts b/tests/format/misc/errors/typescript/issue-8773.ts deleted file mode 100644 index d844c2f19..000000000 --- a/tests/format/misc/errors/typescript/issue-8773.ts +++ /dev/null @@ -1,5 +0,0 @@ -// prettier-ignore -foo + foo; - -continue // comment -;