diff --git a/src/language-js/location/overrides.js b/src/language-js/location/overrides.js index 41a2f351d..82ef7fdcb 100644 --- a/src/language-js/location/overrides.js +++ b/src/language-js/location/overrides.js @@ -51,12 +51,39 @@ const overrides = const shouldAddContentEnd = createTypeCheckFunction(nodeTypesWithContentEnd); -const shouldIgnoredNodePrintSemicolon = (node) => - node.type === "BreakStatement" || - node.type === "ContinueStatement" || - node.type === "DebuggerStatement" || - node.type === "VariableDeclaration" || - (shouldAddContentEnd(node) && node.__contentEnd); +const shouldIgnoredNodePrintSemicolon = (node) => { + if (shouldAddContentEnd(node) && node.__contentEnd) { + return true; + } + + const { type } = node; + + if ( + type === "BreakStatement" || + type === "ContinueStatement" || + type === "DebuggerStatement" || + type === "VariableDeclaration" + ) { + return true; + } + + if (type === "IfStatement") { + return shouldIgnoredNodePrintSemicolon(node.alternate ?? node.consequent); + } + + if ( + type === "ForInStatement" || + type === "ForOfStatement" || + type === "ForStatement" || + type === "LabeledStatement" || + type === "WithStatement" || + type === "WhileStatement" + ) { + return shouldIgnoredNodePrintSemicolon(node.body); + } + + return false; +}; /** @param {Node | Comment} node @@ -66,11 +93,21 @@ function locEnd(node) { const { type } = node; // Effected by children - // TODO[@fisker]: Add more types if (type === "IfStatement") { return locEnd(node.alternate ?? node.consequent); } + if ( + type === "ForInStatement" || + type === "ForOfStatement" || + type === "ForStatement" || + type === "LabeledStatement" || + type === "WithStatement" || + type === "WhileStatement" + ) { + return locEnd(node.body); + } + return ( overrides.get(type)?.( // @ts-expect-error -- Comment types diff --git a/tests/config/format-test/failed-format-tests.js b/tests/config/format-test/failed-format-tests.js index f9deae1a2..614c85619 100644 --- a/tests/config/format-test/failed-format-tests.js +++ b/tests/config/format-test/failed-format-tests.js @@ -19,7 +19,6 @@ const unstableTests = new Map( "flow/hook/hook-type-annotation.js", "typescript/prettier-ignore/mapped-types.ts", "typescript/prettier-ignore/issue-14238.ts", - "js/for/continue-and-break-comment-without-blocks.js", "js/for-of/comments.js", "js/sequence-expression/parenthesized.js", "typescript/satisfies-operators/comments-unstable.ts", diff --git a/tests/format/js/for/__snapshots__/format.test.js.snap b/tests/format/js/for/__snapshots__/format.test.js.snap index 43aabf0f1..c1538ee2c 100644 --- a/tests/format/js/for/__snapshots__/format.test.js.snap +++ b/tests/format/js/for/__snapshots__/format.test.js.snap @@ -754,47 +754,35 @@ label1: for (;;) continue label1 ; =====================================output===================================== -for (;;) - continue; - // comment +for (;;) continue; -for (;;) - break; - // comment +// comment +for (;;) break; -for (const f of []) - continue; - // comment3 +// comment +for (const f of []) continue; -for (const f of []) - break; - // comment4 +// comment3 +for (const f of []) break; -for (const f in {}) - continue; - // comment5 +// comment4 +for (const f in {}) continue; -for (const f in {}) - break; - // comment6 +// comment5 +for (const f in {}) break; -for (;;) - continue; // comment +// comment6 +for (;;) continue; // comment -for (;;) - break; // comment +for (;;) break; // comment -for (const f of []) - continue; // comment +for (const f of []) continue; // comment -for (const f of []) - break; // comment +for (const f of []) break; // comment -for (const f in {}) - continue; // comment +for (const f in {}) continue; // comment -for (const f in {}) - break; // comment +for (const f in {}) break; // comment for (;;) continue; /* comment */ @@ -808,42 +796,33 @@ for (const f in {}) continue; /* comment */ for (const f in {}) break; /* comment */ -for (;;) - continue; - /* comment */ +for (;;) continue; -for (;;) - break; - /* comment */ +/* comment */ +for (;;) break; -for (const f of []) - continue; - /* comment 33 */ +/* comment */ +for (const f of []) continue; -for (const f of []) - break; - /* comment 34 */ +/* comment 33 */ +for (const f of []) break; -for (const f in {}) - continue; - /* comment 35 */ +/* comment 34 */ +for (const f in {}) continue; -for (const f in {}) - break; - /* comment 36 */ +/* comment 35 */ +for (const f in {}) break; +/* comment 36 */ label1: for (;;) continue label1; /* comment */ -label1: for (;;) - continue label1; - /* comment */ +label1: for (;;) continue label1; -label1: for (;;) - continue label1; // comment +/* comment */ +label1: for (;;) continue label1; // comment -label1: for (;;) - continue label1; - // comment +label1: for (;;) continue label1; +// comment ================================================================================ `; diff --git a/tests/format/js/no-semi/__snapshots__/format.test.js.snap b/tests/format/js/no-semi/__snapshots__/format.test.js.snap index ecc524b4a..f7c851cf4 100644 --- a/tests/format/js/no-semi/__snapshots__/format.test.js.snap +++ b/tests/format/js/no-semi/__snapshots__/format.test.js.snap @@ -796,6 +796,448 @@ while (1); /* comment */ ================================================================================ `; +exports[`for-in-statement.js - {"semi":false} format 1`] = ` +====================================options===================================== +parsers: ["babel", "typescript", "flow"] +semi: false + printWidth: 80 (default) | +=====================================input====================================== +for (a in b) foo + +// 11 +;[] + +for (a in b) foo + +// 21 +;foo + +// prettier-ignore +for ( a in b) foo ( ) + +;[] + +for (a in b) foo /* comment */ ; + +=====================================output===================================== +for (a in b) foo + +// 11 +;[] + +for (a in b) foo + +// 21 +foo + +// prettier-ignore +for ( a in b) foo ( ) + +;[] + +for (a in b) foo /* comment */ + +================================================================================ +`; + +exports[`for-in-statement.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "typescript", "flow"] + printWidth: 80 (default) | +=====================================input====================================== +for (a in b) foo + +// 11 +;[] + +for (a in b) foo + +// 21 +;foo + +// prettier-ignore +for ( a in b) foo ( ) + +;[] + +for (a in b) foo /* comment */ ; + +=====================================output===================================== +for (a in b) foo; + +// 11 +[]; + +for (a in b) foo; + +// 21 +foo; + +// prettier-ignore +for ( a in b) foo ( ); + +[]; + +for (a in b) foo; /* comment */ + +================================================================================ +`; + +exports[`for-of-statement.js - {"semi":false} format 1`] = ` +====================================options===================================== +parsers: ["babel", "typescript", "flow"] +semi: false + printWidth: 80 (default) | +=====================================input====================================== +for (a of b) foo + +// 11 +;[] + +for (a of b) foo + +// 21 +;foo + +// prettier-ignore +for ( a of b) foo ( ) + +;[] + +for (a of b) foo /* comment */ ; + +// prettier-ignore +for ( a of b) while ( 1) foo ( ) + +;[] + +=====================================output===================================== +for (a of b) foo + +// 11 +;[] + +for (a of b) foo + +// 21 +foo + +// prettier-ignore +for ( a of b) foo ( ) + +;[] + +for (a of b) foo /* comment */ + +// prettier-ignore +for ( a of b) while ( 1) foo ( ) + +;[] + +================================================================================ +`; + +exports[`for-of-statement.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "typescript", "flow"] + printWidth: 80 (default) | +=====================================input====================================== +for (a of b) foo + +// 11 +;[] + +for (a of b) foo + +// 21 +;foo + +// prettier-ignore +for ( a of b) foo ( ) + +;[] + +for (a of b) foo /* comment */ ; + +// prettier-ignore +for ( a of b) while ( 1) foo ( ) + +;[] + +=====================================output===================================== +for (a of b) foo; + +// 11 +[]; + +for (a of b) foo; + +// 21 +foo; + +// prettier-ignore +for ( a of b) foo ( ); + +[]; + +for (a of b) foo; /* comment */ + +// prettier-ignore +for ( a of b) while ( 1) foo ( ); + +[]; + +================================================================================ +`; + +exports[`for-statement.js - {"semi":false} format 1`] = ` +====================================options===================================== +parsers: ["babel", "typescript", "flow"] +semi: false + printWidth: 80 (default) | +=====================================input====================================== +for (;;) foo + +// 11 +;[] + +for (;;) foo + +// 21 +;foo + +// prettier-ignore +for ( ; ;) foo ( ) + +;[] + +for (;;) foo /* comment */ ; + +=====================================output===================================== +for (;;) foo + +// 11 +;[] + +for (;;) foo + +// 21 +foo + +// prettier-ignore +for ( ; ;) foo ( ) + +;[] + +for (;;) foo /* comment */ + +================================================================================ +`; + +exports[`for-statement.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "typescript", "flow"] + printWidth: 80 (default) | +=====================================input====================================== +for (;;) foo + +// 11 +;[] + +for (;;) foo + +// 21 +;foo + +// prettier-ignore +for ( ; ;) foo ( ) + +;[] + +for (;;) foo /* comment */ ; + +=====================================output===================================== +for (;;) foo; + +// 11 +[]; + +for (;;) foo; + +// 21 +foo; + +// prettier-ignore +for ( ; ;) foo ( ); + +[]; + +for (;;) foo; /* comment */ + +================================================================================ +`; + +exports[`if-statement.js - {"semi":false} format 1`] = ` +====================================options===================================== +parsers: ["babel", "typescript", "flow"] +semi: false + printWidth: 80 (default) | +=====================================input====================================== +if (1) foo + +// 11 +;[] + +if (1) foo + +// 21 +;foo + +// prettier-ignore +if ( 1) foo + +;[] + +if (1) foo /* comment */ ; + +if (1) ; else foo + +// 11 +;[] + +if (1) ; else foo + +// 21 +;foo + +// prettier-ignore +if ( 1) ; else foo + +;[] + +if (1) ; else foo /* comment */ ; + +=====================================output===================================== +if (1) foo + +// 11 +;[] + +if (1) foo + +// 21 +foo + +// prettier-ignore +if ( 1) foo + +;[] + +if (1) foo /* comment */ + +if (1); +else foo + +// 11 +;[] + +if (1); +else foo + +// 21 +foo + +// prettier-ignore +if ( 1) ; else foo + +;[] + +if (1); +else foo /* comment */ + +================================================================================ +`; + +exports[`if-statement.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "typescript", "flow"] + printWidth: 80 (default) | +=====================================input====================================== +if (1) foo + +// 11 +;[] + +if (1) foo + +// 21 +;foo + +// prettier-ignore +if ( 1) foo + +;[] + +if (1) foo /* comment */ ; + +if (1) ; else foo + +// 11 +;[] + +if (1) ; else foo + +// 21 +;foo + +// prettier-ignore +if ( 1) ; else foo + +;[] + +if (1) ; else foo /* comment */ ; + +=====================================output===================================== +if (1) foo; + +// 11 +[]; + +if (1) foo; + +// 21 +foo; + +// prettier-ignore +if ( 1) foo; + +[]; + +if (1) foo; /* comment */ + +if (1); +else foo; + +// 11 +[]; + +if (1); +else foo; + +// 21 +foo; + +// prettier-ignore +if ( 1) ; else foo; + +[]; + +if (1); +else foo; /* comment */ + +================================================================================ +`; + exports[`imports.js - {"semi":false} format 1`] = ` ====================================options===================================== parsers: ["babel", "typescript", "flow"] @@ -1045,6 +1487,93 @@ var c = a.e; ================================================================================ `; +exports[`labeled-statement.js - {"semi":false} format 1`] = ` +====================================options===================================== +parsers: ["babel", "typescript", "flow"] +semi: false + printWidth: 80 (default) | +=====================================input====================================== +label: while(1) foo + +// 11 +;[] + +label: while(1) foo + +// 21 +;foo + +// prettier-ignore +label: while ( 1) foo ( ) + +;[] + +label: while(1) foo /* comment */ ; + +=====================================output===================================== +label: while (1) foo + +// 11 +;[] + +label: while (1) foo + +// 21 +foo + +// prettier-ignore +label: while ( 1) foo ( ) + +;[] + +label: while (1) foo /* comment */ + +================================================================================ +`; + +exports[`labeled-statement.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "typescript", "flow"] + printWidth: 80 (default) | +=====================================input====================================== +label: while(1) foo + +// 11 +;[] + +label: while(1) foo + +// 21 +;foo + +// prettier-ignore +label: while ( 1) foo ( ) + +;[] + +label: while(1) foo /* comment */ ; + +=====================================output===================================== +label: while (1) foo; + +// 11 +[]; + +label: while (1) foo; + +// 21 +foo; + +// prettier-ignore +label: while ( 1) foo ( ); + +[]; + +label: while (1) foo; /* comment */ + +================================================================================ +`; + exports[`no-semi.js - {"semi":false} format 1`] = ` ====================================options===================================== parsers: ["babel", "typescript", "flow"] @@ -1543,3 +2072,177 @@ function a() { ================================================================================ `; + +exports[`while-statement.js - {"semi":false} format 1`] = ` +====================================options===================================== +parsers: ["babel", "typescript", "flow"] +semi: false + printWidth: 80 (default) | +=====================================input====================================== +while(1) foo + +// 11 +;[] + +while(1) foo + +// 21 +;foo + +// prettier-ignore +while ( 1) foo ( ) + +;[] + +while(1) foo /* comment */ ; + +=====================================output===================================== +while (1) foo + +// 11 +;[] + +while (1) foo + +// 21 +foo + +// prettier-ignore +while ( 1) foo ( ) + +;[] + +while (1) foo /* comment */ + +================================================================================ +`; + +exports[`while-statement.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "typescript", "flow"] + printWidth: 80 (default) | +=====================================input====================================== +while(1) foo + +// 11 +;[] + +while(1) foo + +// 21 +;foo + +// prettier-ignore +while ( 1) foo ( ) + +;[] + +while(1) foo /* comment */ ; + +=====================================output===================================== +while (1) foo; + +// 11 +[]; + +while (1) foo; + +// 21 +foo; + +// prettier-ignore +while ( 1) foo ( ); + +[]; + +while (1) foo; /* comment */ + +================================================================================ +`; + +exports[`with-statement.js - {"semi":false} format 1`] = ` +====================================options===================================== +parsers: ["babel", "typescript", "flow"] +semi: false + printWidth: 80 (default) | +=====================================input====================================== +with(1) foo + +// 11 +;[] + +with(1) foo + +// 21 +;foo + +// prettier-ignore +with ( 1) foo ( ) + +;[] + +with(1) foo /* comment */ ; + +=====================================output===================================== +with (1) foo + +// 11 +;[] + +with (1) foo + +// 21 +foo + +// prettier-ignore +with ( 1) foo ( ) + +;[] + +with (1) foo /* comment */ + +================================================================================ +`; + +exports[`with-statement.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "typescript", "flow"] + printWidth: 80 (default) | +=====================================input====================================== +with(1) foo + +// 11 +;[] + +with(1) foo + +// 21 +;foo + +// prettier-ignore +with ( 1) foo ( ) + +;[] + +with(1) foo /* comment */ ; + +=====================================output===================================== +with (1) foo; + +// 11 +[]; + +with (1) foo; + +// 21 +foo; + +// prettier-ignore +with ( 1) foo ( ); + +[]; + +with (1) foo; /* comment */ + +================================================================================ +`; diff --git a/tests/format/js/no-semi/for-in-statement.js b/tests/format/js/no-semi/for-in-statement.js new file mode 100644 index 000000000..a5b8105e5 --- /dev/null +++ b/tests/format/js/no-semi/for-in-statement.js @@ -0,0 +1,16 @@ +for (a in b) foo + +// 11 +;[] + +for (a in b) foo + +// 21 +;foo + +// prettier-ignore +for ( a in b) foo ( ) + +;[] + +for (a in b) foo /* comment */ ; diff --git a/tests/format/js/no-semi/for-of-statement.js b/tests/format/js/no-semi/for-of-statement.js new file mode 100644 index 000000000..c30ca1622 --- /dev/null +++ b/tests/format/js/no-semi/for-of-statement.js @@ -0,0 +1,21 @@ +for (a of b) foo + +// 11 +;[] + +for (a of b) foo + +// 21 +;foo + +// prettier-ignore +for ( a of b) foo ( ) + +;[] + +for (a of b) foo /* comment */ ; + +// prettier-ignore +for ( a of b) while ( 1) foo ( ) + +;[] diff --git a/tests/format/js/no-semi/for-statement.js b/tests/format/js/no-semi/for-statement.js new file mode 100644 index 000000000..f7db57110 --- /dev/null +++ b/tests/format/js/no-semi/for-statement.js @@ -0,0 +1,16 @@ +for (;;) foo + +// 11 +;[] + +for (;;) foo + +// 21 +;foo + +// prettier-ignore +for ( ; ;) foo ( ) + +;[] + +for (;;) foo /* comment */ ; diff --git a/tests/format/js/no-semi/if-statement.js b/tests/format/js/no-semi/if-statement.js new file mode 100644 index 000000000..661c914b1 --- /dev/null +++ b/tests/format/js/no-semi/if-statement.js @@ -0,0 +1,33 @@ +if (1) foo + +// 11 +;[] + +if (1) foo + +// 21 +;foo + +// prettier-ignore +if ( 1) foo + +;[] + +if (1) foo /* comment */ ; + +if (1) ; else foo + +// 11 +;[] + +if (1) ; else foo + +// 21 +;foo + +// prettier-ignore +if ( 1) ; else foo + +;[] + +if (1) ; else foo /* comment */ ; diff --git a/tests/format/js/no-semi/labeled-statement.js b/tests/format/js/no-semi/labeled-statement.js new file mode 100644 index 000000000..89aa02ff1 --- /dev/null +++ b/tests/format/js/no-semi/labeled-statement.js @@ -0,0 +1,16 @@ +label: while(1) foo + +// 11 +;[] + +label: while(1) foo + +// 21 +;foo + +// prettier-ignore +label: while ( 1) foo ( ) + +;[] + +label: while(1) foo /* comment */ ; diff --git a/tests/format/js/no-semi/while-statement.js b/tests/format/js/no-semi/while-statement.js new file mode 100644 index 000000000..bb6ae1536 --- /dev/null +++ b/tests/format/js/no-semi/while-statement.js @@ -0,0 +1,16 @@ +while(1) foo + +// 11 +;[] + +while(1) foo + +// 21 +;foo + +// prettier-ignore +while ( 1) foo ( ) + +;[] + +while(1) foo /* comment */ ; diff --git a/tests/format/js/no-semi/with-statement.js b/tests/format/js/no-semi/with-statement.js new file mode 100644 index 000000000..5e8da30a4 --- /dev/null +++ b/tests/format/js/no-semi/with-statement.js @@ -0,0 +1,16 @@ +with(1) foo + +// 11 +;[] + +with(1) foo + +// 21 +;foo + +// prettier-ignore +with ( 1) foo ( ) + +;[] + +with(1) foo /* comment */ ;