diff --git a/package.json b/package.json index 3114d65eb..12f141ae7 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ ], "dependencies": { "linguist-languages": "^8.0.0", - "php-parser": "^3.4.0" + "php-parser": "https://github.com/glayzzle/php-parser.git#0b3dbe8833965ae14915e722a1b974e3616df78c" }, "devDependencies": { "@babel/preset-env": "^7.27.2", @@ -82,5 +82,6 @@ "include": [ "src/**" ] - } + }, + "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" } diff --git a/src/comments.mjs b/src/comments.mjs index 828fc0162..0e868ac1c 100644 --- a/src/comments.mjs +++ b/src/comments.mjs @@ -62,6 +62,7 @@ function handleOwnLineComment(comment, text, options) { options ) || handleTryComments(enclosingNode, followingNode, comment) || + handleClassMemberStatementComments(enclosingNode, followingNode, comment) || handleClassComments(enclosingNode, followingNode, comment) || handleFunctionParameter( text, @@ -201,6 +202,7 @@ function handleRemainingComment(comment, text, options) { handleGoto(enclosingNode, comment) || handleHalt(precedingNode, enclosingNode, followingNode, comment) || handleBreakAndContinueStatementComments(enclosingNode, comment) || + handleClassMemberStatementComments(enclosingNode, followingNode, comment) || handleInlineComments( enclosingNode, precedingNode, @@ -433,6 +435,32 @@ function handleTraitUseComments(enclosingNode, followingNode, comment) { return false; } +function handleClassMemberStatementComments( + enclosingNode, + followingNode, + comment +) { + if ( + enclosingNode && + enclosingNode.kind === "propertystatement" && + enclosingNode.properties?.includes(followingNode) + ) { + addLeadingComment(enclosingNode, comment); + return true; + } + + if ( + enclosingNode && + enclosingNode.kind === "classconstant" && + enclosingNode.constants?.includes(followingNode) + ) { + addLeadingComment(enclosingNode, comment); + return true; + } + + return false; +} + function handleClassComments(enclosingNode, followingNode, comment) { if ( enclosingNode && @@ -907,6 +935,24 @@ function getCommentChildNodes(node) { node.what.__parent_new_arguments = [...node.arguments]; return [node.what]; } + + if (node.attrGroups && node.attrGroups.length > 0) { + if (node.kind === "method" || node.kind === "function") { + return [ + ...node.attrGroups, + ...node.arguments, + ...(node.type ? [node.type] : []), + ]; + } + + if (node.kind === "classconstant") { + return [...node.attrGroups, ...node.constants]; + } + + if (node.kind === "enumcase") { + return node.attrGroups; + } + } } function canAttachComment(node) { diff --git a/src/printer.mjs b/src/printer.mjs index 9a1136c82..84e1dfcac 100644 --- a/src/printer.mjs +++ b/src/printer.mjs @@ -1199,31 +1199,16 @@ function printAttrs(path, options, print, { inline = false } = {}) { if (!path.node.attrGroups) { return []; } - path.each(() => { - const attrGroup = ["#["]; + path.each((attrGroupPath) => { if (!inline && allAttrs.length > 0) { allAttrs.push(hardline); } - attrGroup.push(softline); - path.each(() => { - const attrNode = path.node; - if (attrGroup.length > 2) { - attrGroup.push(",", line); - } - const attrStmt = [attrNode.name]; - if (attrNode.args.length > 0) { - attrStmt.push(printArgumentsList(path, options, print, "args")); - } - attrGroup.push(group(attrStmt)); - }, "attrs"); allAttrs.push( - group([ - indent(attrGroup), - ifBreak(shouldPrintComma(options, 8.0) ? "," : ""), - softline, - "]", - inline ? ifBreak(softline, " ") : "", - ]) + printAllComments( + attrGroupPath, + () => printAttrGroup(attrGroupPath, options, print, { inline }), + options + ) ); }, "attrGroups"); if (allAttrs.length === 0) { @@ -1232,6 +1217,134 @@ function printAttrs(path, options, print, { inline = false } = {}) { return [...allAttrs, inline ? "" : hardline]; } +function printAttrGroup(path, options, print, { inline = false } = {}) { + const attrGroup = ["#["]; + attrGroup.push(softline); + path.each(() => { + const attrNode = path.node; + if (attrGroup.length > 2) { + attrGroup.push(",", line); + } + const attrStmt = [attrNode.name]; + if (attrNode.args.length > 0) { + attrStmt.push(printArgumentsList(path, options, print, "args")); + } + attrGroup.push(group(attrStmt)); + }, "attrs"); + return group([ + indent(attrGroup), + ifBreak(shouldPrintComma(options, 8.0) ? "," : ""), + softline, + "]", + inline ? ifBreak(softline, " ") : "", + ]); +} + +function printFunction(path, options, print) { + const { node } = path; + const declAttrs = printAttrs(path, options, print, { + inline: node.kind === "closure", + }); + const declaration = []; + + if (node.isFinal) { + declaration.push("final "); + } + + if (node.isAbstract) { + declaration.push("abstract "); + } + + if (node.visibility) { + declaration.push(node.visibility, " "); + } + + if (node.isStatic) { + declaration.push("static "); + } + + declaration.push("function "); + + if (node.byref) { + declaration.push("&"); + } + + if (node.name) { + declaration.push(print("name")); + } + + declaration.push(printArgumentsList(path, options, print)); + + if (node.uses && node.uses.length > 0) { + declaration.push( + group([" use ", printArgumentsList(path, options, print, "uses")]) + ); + } + + if (node.type) { + declaration.push([ + ": ", + hasDanglingComments(node.type) + ? [ + path.call(() => printDanglingComments(path, options, true), "type"), + " ", + ] + : "", + node.nullable ? "?" : "", + print("type"), + ]); + } + + const printedDeclaration = declaration; + + if (!node.body) { + return [...declAttrs, printedDeclaration]; + } + + const printedBody = [ + "{", + indent([hasEmptyBody(path) ? "" : hardline, print("body")]), + hasEmptyBody(path) ? "" : hardline, + "}", + ]; + + const isClosure = node.kind === "closure"; + if (isClosure) { + return [...declAttrs, printedDeclaration, " ", printedBody]; + } + + if (node.arguments.length === 0) { + return [ + ...declAttrs, + printedDeclaration, + shouldPrintHardlineForOpenBrace(options) && !hasEmptyBody(path) + ? hardline + : " ", + printedBody, + ]; + } + + const willBreakDeclaration = declaration.some(willBreak); + + if (willBreakDeclaration) { + return [...declAttrs, printedDeclaration, " ", printedBody]; + } + + return [ + ...declAttrs, + conditionalGroup([ + [ + printedDeclaration, + shouldPrintHardlineForOpenBrace(options) && !hasEmptyBody(path) + ? hardline + : " ", + printedBody, + ], + [printedDeclaration, " ", printedBody], + ]), + ]; +} + function printClass(path, options, print) { const { node } = path; const isAnonymousClass = node.kind === "class" && node.isAnonymous; @@ -1353,111 +1466,6 @@ function printClass(path, options, print) { return [printedDeclaration, printedBody]; } -function printFunction(path, options, print) { - const { node } = path; - const declAttrs = printAttrs(path, options, print, { - inline: node.kind === "closure", - }); - const declaration = []; - - if (node.isFinal) { - declaration.push("final "); - } - - if (node.isAbstract) { - declaration.push("abstract "); - } - - if (node.visibility) { - declaration.push(node.visibility, " "); - } - - if (node.isStatic) { - declaration.push("static "); - } - - declaration.push("function "); - - if (node.byref) { - declaration.push("&"); - } - - if (node.name) { - declaration.push(print("name")); - } - - declaration.push(printArgumentsList(path, options, print)); - - if (node.uses && node.uses.length > 0) { - declaration.push( - group([" use ", printArgumentsList(path, options, print, "uses")]) - ); - } - - if (node.type) { - declaration.push([ - ": ", - hasDanglingComments(node.type) - ? [ - path.call(() => printDanglingComments(path, options, true), "type"), - " ", - ] - : "", - node.nullable ? "?" : "", - print("type"), - ]); - } - - const printedDeclaration = declaration; - - if (!node.body) { - return [...declAttrs, printedDeclaration]; - } - - const printedBody = [ - "{", - indent([hasEmptyBody(path) ? "" : hardline, print("body")]), - hasEmptyBody(path) ? "" : hardline, - "}", - ]; - - const isClosure = node.kind === "closure"; - if (isClosure) { - return [...declAttrs, printedDeclaration, " ", printedBody]; - } - - if (node.arguments.length === 0) { - return [ - ...declAttrs, - printedDeclaration, - shouldPrintHardlineForOpenBrace(options) && !hasEmptyBody(path) - ? hardline - : " ", - printedBody, - ]; - } - - const willBreakDeclaration = declaration.some(willBreak); - - if (willBreakDeclaration) { - return [...declAttrs, printedDeclaration, " ", printedBody]; - } - - return [ - ...declAttrs, - conditionalGroup([ - [ - printedDeclaration, - shouldPrintHardlineForOpenBrace(options) && !hasEmptyBody(path) - ? hardline - : " ", - printedBody, - ], - [printedDeclaration, " ", printedBody], - ]), - ]; -} - function printBodyControlStructure( path, options, @@ -2909,6 +2917,7 @@ function printNode(path, options, print) { case "enumcase": return group([ + ...printAttrs(path, options, print), "case ", print("name"), node.value diff --git a/tests/attributes/__snapshots__/jsfmt.spec.mjs.snap b/tests/attributes/__snapshots__/jsfmt.spec.mjs.snap index c2b776223..70e63d888 100644 --- a/tests/attributes/__snapshots__/jsfmt.spec.mjs.snap +++ b/tests/attributes/__snapshots__/jsfmt.spec.mjs.snap @@ -134,12 +134,12 @@ class D function k(#[L] int $m): callable { return #[N, O] #[P] fn(#[Q] int $r) => $r * 2; - } //Testing T + } // Testing S - //Testing S-T #[S] - #[T] + //Testing S-T + #[T] //Testing T private function u() { return #[V] function () { diff --git a/tests/comments/__snapshots__/jsfmt.spec.mjs.snap b/tests/comments/__snapshots__/jsfmt.spec.mjs.snap index 2d311f8a6..5adfe5f8c 100644 --- a/tests/comments/__snapshots__/jsfmt.spec.mjs.snap +++ b/tests/comments/__snapshots__/jsfmt.spec.mjs.snap @@ -4922,9 +4922,9 @@ class Foo public function emptyMethod(/* comments */) {} - abstract public function sortByName(/* bool $useNaturalSort = false */); /* comment */ + abstract public function sortByName(/* bool $useNaturalSort = false */); - /* comment */ /* comment */ protected static $foo; /* comment */ + /* comment */ /* comment */ /* comment */ protected static $foo; /* comment */ public function foo() {} // Comment diff --git a/tests/enum/__snapshots__/jsfmt.spec.mjs.snap b/tests/enum/__snapshots__/jsfmt.spec.mjs.snap index 3d304160f..799a6ed24 100644 --- a/tests/enum/__snapshots__/jsfmt.spec.mjs.snap +++ b/tests/enum/__snapshots__/jsfmt.spec.mjs.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing exports[`enum.php 1`] = ` ====================================options===================================== @@ -143,3 +143,49 @@ class Enum extends Foo {} ================================================================================ `; + +exports[`enum-case-attributes.php 1`] = ` +====================================options===================================== +parsers: ["php"] +printWidth: 80 + | printWidth +=====================================input====================================== +