@prettier/plugin-php 0.22.1 → 0.22.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -3
- package/package.json +5 -6
- package/src/options.mjs +7 -0
- package/src/pragma.mjs +1 -1
- package/src/printer.mjs +28 -19
- package/src/util.mjs +99 -0
- package/standalone.js +1 -1
package/README.md
CHANGED
|
@@ -37,6 +37,10 @@ Prettier is an opinionated code formatter. It enforces a consistent style by par
|
|
|
37
37
|
|
|
38
38
|
This plugin adds support for the PHP language to Prettier.
|
|
39
39
|
|
|
40
|
+
> [!NOTE]
|
|
41
|
+
>
|
|
42
|
+
> This plugin uses PSR / PER as guidance when making formatting decisions, but does not aim to be fully PSR / PER compliant. The idea is to stay reasonably close to how Prettier for JS works.
|
|
43
|
+
|
|
40
44
|
### Can this be used in production?
|
|
41
45
|
|
|
42
46
|
We're considering the plugin to be stable when pure PHP files are formatted. Formatting of files that contain mixed PHP and HTML is still considered unstable - please see [open issues with the tag "inline"](https://github.com/prettier/plugin-php/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Ainline) for details.
|
|
@@ -85,7 +89,7 @@ yarn:
|
|
|
85
89
|
|
|
86
90
|
```bash
|
|
87
91
|
yarn add --dev prettier @prettier/plugin-php
|
|
88
|
-
# or globally
|
|
92
|
+
# or globally (pending https://github.com/prettier/prettier/issues/15141)
|
|
89
93
|
yarn global add prettier @prettier/plugin-php
|
|
90
94
|
```
|
|
91
95
|
|
|
@@ -93,7 +97,7 @@ npm:
|
|
|
93
97
|
|
|
94
98
|
```bash
|
|
95
99
|
npm install --save-dev prettier @prettier/plugin-php
|
|
96
|
-
# or globally
|
|
100
|
+
# or globally (pending https://github.com/prettier/prettier/issues/15141)
|
|
97
101
|
npm install --global prettier @prettier/plugin-php
|
|
98
102
|
```
|
|
99
103
|
|
|
@@ -270,7 +274,7 @@ Sublime Text support is available through Package Control and the [JsPrettier](h
|
|
|
270
274
|
|
|
271
275
|
### Vim
|
|
272
276
|
|
|
273
|
-
|
|
277
|
+
The official [prettier plugin for vim](https://github.com/prettier/vim-prettier) has built-in support for plugin-php since 1.0.
|
|
274
278
|
|
|
275
279
|
#### ALE
|
|
276
280
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prettier/plugin-php",
|
|
3
|
-
"version": "0.22.
|
|
3
|
+
"version": "0.22.3",
|
|
4
4
|
"description": "Prettier PHP Plugin",
|
|
5
5
|
"repository": "prettier/prettier-php",
|
|
6
6
|
"author": "Lucas Azzola <@azz>",
|
|
@@ -21,7 +21,6 @@
|
|
|
21
21
|
],
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"linguist-languages": "^7.27.0",
|
|
24
|
-
"mem": "^9.0.2",
|
|
25
24
|
"php-parser": "^3.1.5"
|
|
26
25
|
},
|
|
27
26
|
"devDependencies": {
|
|
@@ -34,13 +33,13 @@
|
|
|
34
33
|
"@rollup/plugin-node-resolve": "^15.2.1",
|
|
35
34
|
"@rollup/plugin-replace": "^5.0.5",
|
|
36
35
|
"@rollup/plugin-terser": "^0.4.3",
|
|
37
|
-
"c8": "^
|
|
36
|
+
"c8": "^9.1.0",
|
|
38
37
|
"cross-env": "^7.0.2",
|
|
39
|
-
"eslint": "8.
|
|
38
|
+
"eslint": "8.57.0",
|
|
40
39
|
"eslint-config-prettier": "9.1.0",
|
|
41
40
|
"eslint-plugin-import": "2.29.1",
|
|
42
|
-
"eslint-plugin-jest": "27.6.
|
|
43
|
-
"eslint-plugin-prettier": "5.
|
|
41
|
+
"eslint-plugin-jest": "27.6.3",
|
|
42
|
+
"eslint-plugin-prettier": "5.1.3",
|
|
44
43
|
"eslint-plugin-prettier-doc": "^1.1.0",
|
|
45
44
|
"jest": "29.7.0",
|
|
46
45
|
"jest-environment-jsdom": "29.7.0",
|
package/src/options.mjs
CHANGED
|
@@ -45,4 +45,11 @@ export default {
|
|
|
45
45
|
{ value: "1tbs", description: "Use 1tbs brace style." },
|
|
46
46
|
],
|
|
47
47
|
},
|
|
48
|
+
singleQuote: {
|
|
49
|
+
since: "0.0.0",
|
|
50
|
+
category: CATEGORY_PHP,
|
|
51
|
+
type: "boolean",
|
|
52
|
+
default: false,
|
|
53
|
+
description: "Use single quotes instead of double quotes.",
|
|
54
|
+
},
|
|
48
55
|
};
|
package/src/pragma.mjs
CHANGED
package/src/printer.mjs
CHANGED
|
@@ -36,6 +36,7 @@ import {
|
|
|
36
36
|
getAncestorNode,
|
|
37
37
|
isReferenceLikeNode,
|
|
38
38
|
normalizeMagicMethodName,
|
|
39
|
+
isSimpleCallArgument,
|
|
39
40
|
} from "./util.mjs";
|
|
40
41
|
|
|
41
42
|
const {
|
|
@@ -508,9 +509,9 @@ function printMemberChain(path, options, print) {
|
|
|
508
509
|
printIndentedGroup(groups.slice(shouldMerge ? 2 : 1)),
|
|
509
510
|
];
|
|
510
511
|
|
|
511
|
-
const
|
|
512
|
+
const callExpressions = printedNodes.filter(
|
|
512
513
|
(tuple) => tuple.node.kind === "call"
|
|
513
|
-
)
|
|
514
|
+
);
|
|
514
515
|
|
|
515
516
|
// We don't want to print in one line if there's:
|
|
516
517
|
// * A comment.
|
|
@@ -519,7 +520,10 @@ function printMemberChain(path, options, print) {
|
|
|
519
520
|
// If the last group is a function it's okay to inline if it fits.
|
|
520
521
|
if (
|
|
521
522
|
hasComment ||
|
|
522
|
-
|
|
523
|
+
(callExpressions.length > 2 &&
|
|
524
|
+
callExpressions.some(
|
|
525
|
+
(exp) => !exp.node.arguments.every((arg) => isSimpleCallArgument(arg))
|
|
526
|
+
)) ||
|
|
523
527
|
printedGroups.slice(0, -1).some(willBreak)
|
|
524
528
|
) {
|
|
525
529
|
return group(expanded);
|
|
@@ -1014,8 +1018,8 @@ function printLines(path, options, print, childrenAttribute = "children") {
|
|
|
1014
1018
|
"?>",
|
|
1015
1019
|
]
|
|
1016
1020
|
: isProgramLikeNode(node) && isFirstNode && node.kind !== "namespace"
|
|
1017
|
-
|
|
1018
|
-
|
|
1021
|
+
? ""
|
|
1022
|
+
: [beforeCloseTagInlineNode, "?>"];
|
|
1019
1023
|
|
|
1020
1024
|
//FIXME getNode is used to get ancestors, but it seems this means to get next sibling?
|
|
1021
1025
|
const nextV = path.getNode(index + 1);
|
|
@@ -1030,8 +1034,8 @@ function printLines(path, options, print, childrenAttribute = "children") {
|
|
|
1030
1034
|
hardline,
|
|
1031
1035
|
]
|
|
1032
1036
|
: isProgramLikeNode(node) && isLastNode
|
|
1033
|
-
|
|
1034
|
-
|
|
1037
|
+
? ""
|
|
1038
|
+
: [openTag, " "];
|
|
1035
1039
|
|
|
1036
1040
|
printed = [beforeInline, printed, afterInline];
|
|
1037
1041
|
}
|
|
@@ -1087,8 +1091,8 @@ function printLines(path, options, print, childrenAttribute = "children") {
|
|
|
1087
1091
|
: "",
|
|
1088
1092
|
]
|
|
1089
1093
|
: node.comments
|
|
1090
|
-
|
|
1091
|
-
|
|
1094
|
+
? hardline
|
|
1095
|
+
: "";
|
|
1092
1096
|
|
|
1093
1097
|
parts.push(lineSuffix([beforeCloseTag, "?>"]));
|
|
1094
1098
|
}
|
|
@@ -1293,17 +1297,18 @@ function printClass(path, options, print) {
|
|
|
1293
1297
|
}
|
|
1294
1298
|
}
|
|
1295
1299
|
|
|
1300
|
+
const hasEmptyClassBody =
|
|
1301
|
+
node.body && node.body.length === 0 && !hasDanglingComments(node);
|
|
1302
|
+
|
|
1296
1303
|
const printedDeclaration = group([
|
|
1297
1304
|
group(declaration),
|
|
1298
|
-
shouldPrintHardlineForOpenBrace(options)
|
|
1305
|
+
shouldPrintHardlineForOpenBrace(options) && !hasEmptyClassBody
|
|
1299
1306
|
? isAnonymousClass
|
|
1300
1307
|
? line
|
|
1301
1308
|
: hardline
|
|
1302
1309
|
: " ",
|
|
1303
1310
|
]);
|
|
1304
1311
|
|
|
1305
|
-
const hasEmptyClassBody =
|
|
1306
|
-
node.body && node.body.length === 0 && !hasDanglingComments(node);
|
|
1307
1312
|
const printedBody = [
|
|
1308
1313
|
"{",
|
|
1309
1314
|
indent([
|
|
@@ -1311,7 +1316,7 @@ function printClass(path, options, print) {
|
|
|
1311
1316
|
printStatements(path, options, print, "body"),
|
|
1312
1317
|
]),
|
|
1313
1318
|
printDanglingComments(path, options, true),
|
|
1314
|
-
|
|
1319
|
+
hasEmptyClassBody ? "" : hardline,
|
|
1315
1320
|
"}",
|
|
1316
1321
|
];
|
|
1317
1322
|
|
|
@@ -1379,14 +1384,14 @@ function printFunction(path, options, print) {
|
|
|
1379
1384
|
return [...declAttrs, printedDeclaration];
|
|
1380
1385
|
}
|
|
1381
1386
|
|
|
1382
|
-
const isClosure = node.kind === "closure";
|
|
1383
1387
|
const printedBody = [
|
|
1384
1388
|
"{",
|
|
1385
1389
|
indent([hasEmptyBody(path) ? "" : hardline, print("body")]),
|
|
1386
|
-
|
|
1390
|
+
hasEmptyBody(path) ? "" : hardline,
|
|
1387
1391
|
"}",
|
|
1388
1392
|
];
|
|
1389
1393
|
|
|
1394
|
+
const isClosure = node.kind === "closure";
|
|
1390
1395
|
if (isClosure) {
|
|
1391
1396
|
return [...declAttrs, printedDeclaration, " ", printedBody];
|
|
1392
1397
|
}
|
|
@@ -1395,7 +1400,9 @@ function printFunction(path, options, print) {
|
|
|
1395
1400
|
return [
|
|
1396
1401
|
...declAttrs,
|
|
1397
1402
|
printedDeclaration,
|
|
1398
|
-
shouldPrintHardlineForOpenBrace(options)
|
|
1403
|
+
shouldPrintHardlineForOpenBrace(options) && !hasEmptyBody(path)
|
|
1404
|
+
? hardline
|
|
1405
|
+
: " ",
|
|
1399
1406
|
printedBody,
|
|
1400
1407
|
];
|
|
1401
1408
|
}
|
|
@@ -1411,7 +1418,9 @@ function printFunction(path, options, print) {
|
|
|
1411
1418
|
conditionalGroup([
|
|
1412
1419
|
[
|
|
1413
1420
|
printedDeclaration,
|
|
1414
|
-
shouldPrintHardlineForOpenBrace(options)
|
|
1421
|
+
shouldPrintHardlineForOpenBrace(options) && !hasEmptyBody(path)
|
|
1422
|
+
? hardline
|
|
1423
|
+
: " ",
|
|
1415
1424
|
printedBody,
|
|
1416
1425
|
],
|
|
1417
1426
|
[printedDeclaration, " ", printedBody],
|
|
@@ -1707,8 +1716,8 @@ function printNode(path, options, print) {
|
|
|
1707
1716
|
hardline,
|
|
1708
1717
|
]
|
|
1709
1718
|
: hasDanglingComments(node)
|
|
1710
|
-
|
|
1711
|
-
|
|
1719
|
+
? [line, printDanglingComments(path, options, true), line]
|
|
1720
|
+
: "",
|
|
1712
1721
|
"}",
|
|
1713
1722
|
]
|
|
1714
1723
|
: "",
|
package/src/util.mjs
CHANGED
|
@@ -612,6 +612,103 @@ function normalizeMagicMethodName(name) {
|
|
|
612
612
|
return name;
|
|
613
613
|
}
|
|
614
614
|
|
|
615
|
+
/**
|
|
616
|
+
* @param {string[]} kindsArray
|
|
617
|
+
* @returns {(node: Node | Comment) => Boolean}
|
|
618
|
+
*/
|
|
619
|
+
function createTypeCheckFunction(kindsArray) {
|
|
620
|
+
const kinds = new Set(kindsArray);
|
|
621
|
+
return (node) => kinds.has(node?.kind);
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
const isSingleWordType = createTypeCheckFunction([
|
|
625
|
+
"variadicplaceholder",
|
|
626
|
+
"namedargument",
|
|
627
|
+
"nullkeyword",
|
|
628
|
+
"identifier",
|
|
629
|
+
"parameter",
|
|
630
|
+
"variable",
|
|
631
|
+
"variadic",
|
|
632
|
+
"boolean",
|
|
633
|
+
"literal",
|
|
634
|
+
"number",
|
|
635
|
+
"string",
|
|
636
|
+
"clone",
|
|
637
|
+
"cast",
|
|
638
|
+
]);
|
|
639
|
+
|
|
640
|
+
const isArrayExpression = createTypeCheckFunction(["array"]);
|
|
641
|
+
const isCallLikeExpression = createTypeCheckFunction([
|
|
642
|
+
"nullsafepropertylookup",
|
|
643
|
+
"propertylookup",
|
|
644
|
+
"staticlookup",
|
|
645
|
+
"offsetlookup",
|
|
646
|
+
"call",
|
|
647
|
+
"new",
|
|
648
|
+
]);
|
|
649
|
+
const isArrowFuncExpression = createTypeCheckFunction(["arrowfunc"]);
|
|
650
|
+
|
|
651
|
+
function getChainParts(node, prev = []) {
|
|
652
|
+
const parts = prev;
|
|
653
|
+
if (isCallLikeExpression(node)) {
|
|
654
|
+
parts.push(node);
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
if (!node.what) {
|
|
658
|
+
return parts;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
return getChainParts(node.what, parts);
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
function isSimpleCallArgument(node, depth = 2) {
|
|
665
|
+
if (depth <= 0) {
|
|
666
|
+
return false;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
const isChildSimple = (child) => isSimpleCallArgument(child, depth - 1);
|
|
670
|
+
|
|
671
|
+
if (isSingleWordType(node)) {
|
|
672
|
+
return true;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
if (isArrayExpression(node)) {
|
|
676
|
+
return node.items.every((x) => x === null || isChildSimple(x));
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
if (isCallLikeExpression(node)) {
|
|
680
|
+
const parts = getChainParts(node);
|
|
681
|
+
parts.unshift();
|
|
682
|
+
|
|
683
|
+
return (
|
|
684
|
+
parts.length <= depth &&
|
|
685
|
+
parts.every((node) =>
|
|
686
|
+
isLookupNode(node)
|
|
687
|
+
? isChildSimple(node.offset)
|
|
688
|
+
: node.arguments.every(isChildSimple)
|
|
689
|
+
)
|
|
690
|
+
);
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
if (isArrowFuncExpression(node)) {
|
|
694
|
+
return (
|
|
695
|
+
node.arguments.length <= depth && node.arguments.every(isChildSimple)
|
|
696
|
+
);
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
return false;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
function memoize(fn) {
|
|
703
|
+
const cache = new Map();
|
|
704
|
+
return (key) => {
|
|
705
|
+
if (!cache.has(key)) {
|
|
706
|
+
cache.set(key, fn(key));
|
|
707
|
+
}
|
|
708
|
+
return cache.get(key);
|
|
709
|
+
};
|
|
710
|
+
}
|
|
711
|
+
|
|
615
712
|
export {
|
|
616
713
|
printNumber,
|
|
617
714
|
getPrecedence,
|
|
@@ -641,4 +738,6 @@ export {
|
|
|
641
738
|
isDocNode,
|
|
642
739
|
getAncestorNode,
|
|
643
740
|
normalizeMagicMethodName,
|
|
741
|
+
isSimpleCallArgument,
|
|
742
|
+
memoize,
|
|
644
743
|
};
|