diff --git a/changelog_unreleased/javascript/18147.md b/changelog_unreleased/javascript/18147.md new file mode 100644 index 000000000..c0d4440dd --- /dev/null +++ b/changelog_unreleased/javascript/18147.md @@ -0,0 +1,48 @@ +#### Fix inconsistent comment print between class methods and object methods (#18147 by @fisker) + + +```jsx +// Input +class x { + method() // Class method + { + return 1 + } +} + +const object = { + method() // Object method + { + return 1 + } +} + +// Prettier stable +class x { + method() { // Class method + return 1; + } +} + +const object = { + method() { + // Object method + return 1; + }, +}; + +// Prettier main +class x { + method() { + // class method + return 1; + } +} + +const object = { + method() { + // object method + return 1; + }, +}; +``` diff --git a/src/language-js/comments/handle-comments.js b/src/language-js/comments/handle-comments.js index df4ae1ee8..8963f9cd5 100644 --- a/src/language-js/comments/handle-comments.js +++ b/src/language-js/comments/handle-comments.js @@ -694,19 +694,21 @@ function handleLastFunctionArgComments({ // Comment between function parameters parentheses and function body if ( !isBlockComment(comment) && - (enclosingNode?.type === "FunctionDeclaration" || - enclosingNode?.type === "FunctionExpression" || - enclosingNode?.type === "ObjectMethod") && followingNode?.type === "BlockStatement" && - enclosingNode.body === followingNode + isFunctionLikeNode(enclosingNode) ) { - const characterAfterCommentIndex = getNextNonSpaceNonCommentCharacterIndex( - text, - locEnd(comment), - ); - if (characterAfterCommentIndex === locStart(followingNode)) { - addBlockStatementFirstComment(followingNode, comment); - return true; + const functionBody = + enclosingNode.type === "MethodDefinition" + ? enclosingNode.value.body + : enclosingNode.body; + + if (functionBody === followingNode) { + const characterAfterCommentIndex = + getNextNonSpaceNonCommentCharacterIndex(text, locEnd(comment)); + if (characterAfterCommentIndex === locStart(followingNode)) { + addBlockStatementFirstComment(followingNode, comment); + return true; + } } } diff --git a/tests/config/run-format-test.js b/tests/config/run-format-test.js index e9e1cedce..9bac63e82 100644 --- a/tests/config/run-format-test.js +++ b/tests/config/run-format-test.js @@ -22,7 +22,6 @@ const RANGE_END_PLACEHOLDER = "<<>>"; // TODO: these test files need fix const unstableTests = new Map( [ - "js/class-comment/misc.js", ["js/comments/dangling_array.js", (options) => options.semi === false], ["js/comments/jsx.js", (options) => options.semi === false], "js/comments/return-statement.js", diff --git a/tests/format/js/class-comment/__snapshots__/format.test.js.snap b/tests/format/js/class-comment/__snapshots__/format.test.js.snap index d8badc054..89ece48df 100644 --- a/tests/format/js/class-comment/__snapshots__/format.test.js.snap +++ b/tests/format/js/class-comment/__snapshots__/format.test.js.snap @@ -41,7 +41,8 @@ class x { =====================================output===================================== class x { - focus() { // comment 1 + focus() { + // comment 1 // comment 2 } } diff --git a/tests/format/js/comments/function/18146.js b/tests/format/js/comments/function/18146.js new file mode 100644 index 000000000..0afc2e027 --- /dev/null +++ b/tests/format/js/comments/function/18146.js @@ -0,0 +1,70 @@ +class x { + a() // class 1 + { + } + + b() // class 2 + { + // comment + } + + c() // class 3 + { + call() + } + + constructor() // class constructor + {} + + static staticMethod() // class static + {} + + get getter() // class getter + {} +} + +const x2 = { + a() // object 1 + { + }, + + b() // object 2 + { + // comment + }, + + c() // object 3 + { + call() + } +} + +function a() // function declaration 1 +{ + // comment +} + +function b() // function declaration 1 +{ +} + +function c() // function declaration 1 +{ + call() +} + +a = [ + function a() // function expression 1 + { + // comment + }, + + function b() // function expression 1 + { + }, + + function c() // function expression 1 + { + call() + }, +] diff --git a/tests/format/js/comments/function/__snapshots__/format.test.js.snap b/tests/format/js/comments/function/__snapshots__/format.test.js.snap index 52d1837dd..ae6b4712e 100644 --- a/tests/format/js/comments/function/__snapshots__/format.test.js.snap +++ b/tests/format/js/comments/function/__snapshots__/format.test.js.snap @@ -1,5 +1,160 @@ // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing +exports[`18146.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +class x { + a() // class 1 + { + } + + b() // class 2 + { + // comment + } + + c() // class 3 + { + call() + } + + constructor() // class constructor + {} + + static staticMethod() // class static + {} + + get getter() // class getter + {} +} + +const x2 = { + a() // object 1 + { + }, + + b() // object 2 + { + // comment + }, + + c() // object 3 + { + call() + } +} + +function a() // function declaration 1 +{ + // comment +} + +function b() // function declaration 1 +{ +} + +function c() // function declaration 1 +{ + call() +} + +a = [ + function a() // function expression 1 + { + // comment + }, + + function b() // function expression 1 + { + }, + + function c() // function expression 1 + { + call() + }, +] + +=====================================output===================================== +class x { + a() { + // class 1 + } + + b() { + // class 2 + // comment + } + + c() { + // class 3 + call(); + } + + constructor() { + // class constructor + } + + static staticMethod() { + // class static + } + + get getter() { + // class getter + } +} + +const x2 = { + a() { + // object 1 + }, + + b() { + // object 2 + // comment + }, + + c() { + // object 3 + call(); + }, +}; + +function a() { + // function declaration 1 + // comment +} + +function b() { + // function declaration 1 +} + +function c() { + // function declaration 1 + call(); +} + +a = [ + function a() { + // function expression 1 + // comment + }, + + function b() { + // function expression 1 + }, + + function c() { + // function expression 1 + call(); + }, +]; + +================================================================================ +`; + exports[`between-parentheses-and-function-body.js format 1`] = ` ====================================options===================================== parsers: ["babel", "flow", "typescript"] @@ -42,6 +197,17 @@ a = { {}, } +class A { + + foo() + // this is a function + {} + + bar = function() + // this is a function + {} +} + =====================================output===================================== function function_declaration() { // this is a function @@ -74,5 +240,15 @@ a = { }, }; +class A { + foo() { + // this is a function + } + + bar = function () { + // this is a function + }; +} + ================================================================================ `; diff --git a/tests/format/js/comments/function/between-parentheses-and-function-body.js b/tests/format/js/comments/function/between-parentheses-and-function-body.js index c3553778f..e2d6bed46 100644 --- a/tests/format/js/comments/function/between-parentheses-and-function-body.js +++ b/tests/format/js/comments/function/between-parentheses-and-function-body.js @@ -33,3 +33,14 @@ a = { // this is a function {}, } + +class A { + + foo() + // this is a function + {} + + bar = function() + // this is a function + {} +}