@prettier/plugin-php 0.23.0 → 0.24.0

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 CHANGED
@@ -176,17 +176,33 @@ await prettier.format(YOUR_CODE, {
176
176
 
177
177
  Prettier for PHP supports the following options. We recommend that all users set the `phpVersion` option.
178
178
 
179
- | Name | Default | Description |
180
- | ------------------ | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
181
- | `phpVersion` | `"7.0"` | Allows specifying the PHP version you're using. If you're using PHP 7.1 or later, setting this option will make use of modern language features in the printed output. If you're using PHP lower than 7.0, you'll have to set this option or Prettier will generate incompatible code. |
182
- | `printWidth` | `80` | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#print-width)) |
183
- | `tabWidth` | `4` | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#tab-width)), The default is `4` based on the `PSR-2` coding standard. |
184
- | `useTabs` | `false` | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#tabs)) |
185
- | `singleQuote` | `false` | If set to `"true"`, strings that use double quotes but do not rely on the features they add, will be reformatted. Example: `"foo" -> 'foo'`, `"foo $bar" -> "foo $bar"`. |
186
- | `trailingCommaPHP` | `true` | If set to `true`, trailing commas will be added wherever possible. <br> If set to `false`, no trailing commas are printed. |
187
- | `braceStyle` | `"per-cs"` | If set to `"per-cs"`, prettier will move open brace for code blocks (classes, functions and methods) onto new line. <br> If set to `"1tbs"`, prettier will move open brace for code blocks (classes, functions and methods) onto same line. |
188
- | `requirePragma` | `false` | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#require-pragma)) |
189
- | `insertPragma` | `false` | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#insert-pragma)) |
179
+ | Name | Default | Description |
180
+ | ------------------ | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
181
+ | `phpVersion` | `"auto"` \* | Allows specifying the PHP version you're using. (See Notes Below) |
182
+ | `printWidth` | `80` | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#print-width)) |
183
+ | `tabWidth` | `4` | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#tab-width)), The default is `4` based on the `PSR-2` coding standard. |
184
+ | `useTabs` | `false` | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#tabs)) |
185
+ | `singleQuote` | `false` | If set to `"true"`, strings that use double quotes but do not rely on the features they add, will be reformatted. Example: `"foo" -> 'foo'`, `"foo $bar" -> "foo $bar"`. |
186
+ | `trailingCommaPHP` | `true` | If set to `true`, trailing commas will be added wherever possible. <br> If set to `false`, no trailing commas are printed. |
187
+ | `braceStyle` | `"per-cs"` | If set to `"per-cs"`, prettier will move open brace for code blocks (classes, functions and methods) onto new line. <br> If set to `"1tbs"`, prettier will move open brace for code blocks (classes, functions and methods) onto same line. |
188
+ | `requirePragma` | `false` | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#require-pragma)) |
189
+ | `insertPragma` | `false` | Same as in Prettier ([see prettier docs](https://prettier.io/docs/en/options.html#insert-pragma)) |
190
+
191
+ ### \* `phpVersion` Configuration Notes :
192
+
193
+ The default setting `auto`, attempts to auto-detect your supported php versions from a `composer.json` with in the
194
+ current directory or any parent directory, the plugin will use a minimum supported php version from
195
+ `{"require":{"php":"..."}}` to set the phpVersion. If not found or not able to be parsed, it will default to latest
196
+ supported PHP version.
197
+
198
+ You set the `phpVersion` to `composer` and this will only use the `composer.json` file to determine the php
199
+ version, prettier will crash if the PHP cannot be determined.
200
+
201
+ You can also set the `phpVersion` to a specific version, such as `7.4`, `8.0`, `8.1`, `8.2`, or `8.3`.
202
+
203
+ **Please Note:** If the phpVersion is not set correctly for your environment, this plugin will produce code that could
204
+ be incompatible with your PHP runtime. For example, if you are using PHP 7.4, but the plugin is set to PHP 8.3, it will
205
+ produce code that uses features not available in PHP 7.4.
190
206
 
191
207
  ## Ignoring code
192
208
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prettier/plugin-php",
3
- "version": "0.23.0",
3
+ "version": "0.24.0",
4
4
  "description": "Prettier PHP Plugin",
5
5
  "repository": "prettier/prettier-php",
6
6
  "author": "Lucas Azzola <@azz>",
@@ -1,9 +1,4 @@
1
- import {
2
- getPrecedence,
3
- shouldFlatten,
4
- isBitwiseOperator,
5
- isMinVersion,
6
- } from "./util.mjs";
1
+ import { getPrecedence, shouldFlatten, isBitwiseOperator } from "./util.mjs";
7
2
 
8
3
  function needsParens(path, options) {
9
4
  const { parent } = path;
@@ -135,7 +130,7 @@ function needsParens(path, options) {
135
130
  case "new": {
136
131
  const requiresParens =
137
132
  node.kind === "clone" ||
138
- (node.kind === "new" && !isMinVersion(options.phpVersion, "8.4"));
133
+ (node.kind === "new" && options.phpVersion < 8.4);
139
134
  switch (parent.kind) {
140
135
  case "propertylookup":
141
136
  case "nullsafepropertylookup":
package/src/options.mjs CHANGED
@@ -1,30 +1,124 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+
1
4
  const CATEGORY_PHP = "PHP";
2
5
 
6
+ // prettier-ignore
7
+ const SUPPORTED_PHP_VERSIONS = [
8
+ 5.0, 5.1, 5.2, 5.3, 5.4, 5.5, 5.6,
9
+ 7.0, 7.1, 7.2, 7.3, 7.4,
10
+ 8.0, 8.1, 8.2, 8.3, 8.4,
11
+ ];
12
+
13
+ export const LATEST_SUPPORTED_PHP_VERSION = Math.max(...SUPPORTED_PHP_VERSIONS);
14
+
15
+ let getComposerError = "";
16
+
17
+ /**
18
+ * Detect the minimum PHP version from the composer.json file
19
+ * @return {number|null} The PHP version to use in the composer.json file, null when not found
20
+ */
21
+ function getComposerPhpVersion() {
22
+ // Try to find composer.json
23
+ const currentDir = process.cwd();
24
+ let composerPath = null;
25
+
26
+ const directComposerPath = path.join(currentDir, "composer.json");
27
+ if (fs.existsSync(directComposerPath)) {
28
+ composerPath = directComposerPath;
29
+ }
30
+
31
+ if (!composerPath) {
32
+ let searchDir = path.dirname(currentDir);
33
+ while (searchDir !== path.parse(searchDir).root) {
34
+ const potentialComposerPath = path.join(searchDir, "composer.json");
35
+ if (fs.existsSync(potentialComposerPath)) {
36
+ composerPath = potentialComposerPath;
37
+ break;
38
+ }
39
+ searchDir = path.dirname(searchDir);
40
+ }
41
+ }
42
+
43
+ if (composerPath) {
44
+ try {
45
+ const fileContent = fs.readFileSync(composerPath, "utf8");
46
+ const composerJson = JSON.parse(fileContent);
47
+
48
+ if (composerJson.require && composerJson.require.php) {
49
+ // Check for a wildcard pattern like "7.*"
50
+ const wildcardMatch = composerJson.require.php.match(
51
+ /^(?:[^0-9]*)?([0-9]+)\.\*/
52
+ );
53
+ if (wildcardMatch) {
54
+ return parseFloat(`${wildcardMatch[1]}.0`);
55
+ }
56
+
57
+ // Extract version from composer semver format
58
+ const versionMatch = composerJson.require.php.match(
59
+ /^(?:[^0-9]*)?([0-9]+)\.([0-9]+)/
60
+ );
61
+
62
+ if (versionMatch) {
63
+ return parseFloat(`${versionMatch[1]}.${versionMatch[2]}`);
64
+ } else {
65
+ getComposerError = `Could not decode PHP version (${composerJson.require.php}})`;
66
+ return null;
67
+ }
68
+ }
69
+ } catch (e) {
70
+ getComposerError = `Error reading composer.json: ${e.message}`;
71
+ }
72
+ } else {
73
+ getComposerError = "Could not find composer.json";
74
+ }
75
+
76
+ return null;
77
+ }
78
+
79
+ export { getComposerPhpVersion };
80
+
81
+ /**
82
+ * Resolve the PHP version to a number based on the provided options.
83
+ *
84
+ */
85
+ export function resolvePhpVersion(options) {
86
+ if (!options) {
87
+ return;
88
+ }
89
+ if (options.phpVersion === "auto") {
90
+ options.phpVersion =
91
+ getComposerPhpVersion() ?? LATEST_SUPPORTED_PHP_VERSION;
92
+ } else if (options.phpVersion === "composer") {
93
+ const v = getComposerPhpVersion();
94
+ if (v === null) {
95
+ throw new Error(
96
+ `Could not determine PHP version from composer; ${getComposerError}`
97
+ );
98
+ }
99
+ options.phpVersion = v;
100
+ } else {
101
+ options.phpVersion = parseFloat(options.phpVersion);
102
+ }
103
+ }
104
+
3
105
  export default {
4
106
  phpVersion: {
5
107
  since: "0.13.0",
6
108
  category: CATEGORY_PHP,
7
109
  type: "choice",
8
- default: "7.0",
110
+ default: "auto",
9
111
  description: "Minimum target PHP version.",
10
112
  choices: [
11
- { value: "5.0" },
12
- { value: "5.1" },
13
- { value: "5.2" },
14
- { value: "5.3" },
15
- { value: "5.4" },
16
- { value: "5.5" },
17
- { value: "5.6" },
18
- { value: "7.0" },
19
- { value: "7.1" },
20
- { value: "7.2" },
21
- { value: "7.3" },
22
- { value: "7.4" },
23
- { value: "8.0" },
24
- { value: "8.1" },
25
- { value: "8.2" },
26
- { value: "8.3" },
27
- { value: "8.4" },
113
+ ...SUPPORTED_PHP_VERSIONS.map((v) => ({ value: v.toFixed(1) })),
114
+ {
115
+ value: "composer",
116
+ description: "Use the PHP version defined in composer.json",
117
+ },
118
+ {
119
+ value: "auto",
120
+ description: `Try composer.json, else latest PHP Version (${LATEST_SUPPORTED_PHP_VERSION})`,
121
+ },
28
122
  ],
29
123
  },
30
124
  trailingCommaPHP: {
package/src/parser.mjs CHANGED
@@ -1,5 +1,6 @@
1
1
  import engine from "php-parser";
2
- import options from "./options.mjs";
2
+ import { LATEST_SUPPORTED_PHP_VERSION } from "./options.mjs";
3
+ import { resolvePhpVersion } from "./options.mjs";
3
4
 
4
5
  function parse(text, opts) {
5
6
  const inMarkdown = opts && opts.parentParser === "markdown";
@@ -7,19 +8,16 @@ function parse(text, opts) {
7
8
  if (!text && inMarkdown) {
8
9
  return "";
9
10
  }
11
+ resolvePhpVersion(opts);
10
12
 
11
13
  // Todo https://github.com/glayzzle/php-parser/issues/170
12
14
  text = text.replace(/\?>\n<\?/g, "?>\n___PSEUDO_INLINE_PLACEHOLDER___<?");
13
15
 
14
- const latestSupportedPhpVersion = Math.max(
15
- ...options.phpVersion.choices.map((c) => parseFloat(c.value))
16
- );
17
-
18
16
  // initialize a new parser instance
19
17
  const parser = new engine({
20
18
  parser: {
21
19
  extractDoc: true,
22
- version: `${latestSupportedPhpVersion}`,
20
+ version: `${LATEST_SUPPORTED_PHP_VERSION}`,
23
21
  },
24
22
  ast: {
25
23
  withPositions: true,
package/src/printer.mjs CHANGED
@@ -37,7 +37,6 @@ import {
37
37
  isReferenceLikeNode,
38
38
  normalizeMagicMethodName,
39
39
  isSimpleCallArgument,
40
- isMinVersion,
41
40
  } from "./util.mjs";
42
41
 
43
42
  const {
@@ -66,12 +65,19 @@ const {
66
65
  isPreviousLineEmpty,
67
66
  } = prettierUtil;
68
67
 
68
+ /**
69
+ * Determine if we should print a trailing comma based on the config & php version
70
+ *
71
+ * @param options {object} Prettier Options
72
+ * @param requiredVersion {number}
73
+ * @returns {boolean}
74
+ */
69
75
  function shouldPrintComma(options, requiredVersion) {
70
76
  if (!options.trailingCommaPHP) {
71
77
  return false;
72
78
  }
73
79
 
74
- return isMinVersion(options.phpVersion, requiredVersion);
80
+ return options.phpVersion >= requiredVersion;
75
81
  }
76
82
 
77
83
  function shouldPrintHardlineForOpenBrace(options) {
@@ -612,9 +618,9 @@ function printArgumentsList(path, options, print, argumentsKey = "arguments") {
612
618
  const lastArg = getLast(args);
613
619
 
614
620
  const maybeTrailingComma =
615
- (shouldPrintComma(options, "7.3") &&
621
+ (shouldPrintComma(options, 7.3) &&
616
622
  ["call", "new", "unset", "isset"].includes(node.kind)) ||
617
- (shouldPrintComma(options, "8.0") &&
623
+ (shouldPrintComma(options, 8.0) &&
618
624
  ["function", "closure", "method", "arrowfunc", "attribute"].includes(
619
625
  node.kind
620
626
  ))
@@ -1186,7 +1192,7 @@ function printAttrs(path, options, print, { inline = false } = {}) {
1186
1192
  allAttrs.push(
1187
1193
  group([
1188
1194
  indent(attrGroup),
1189
- ifBreak(shouldPrintComma(options, "8.0") ? "," : ""),
1195
+ ifBreak(shouldPrintComma(options, 8.0) ? "," : ""),
1190
1196
  softline,
1191
1197
  "]",
1192
1198
  inline ? ifBreak(softline, " ") : "",
@@ -1658,11 +1664,7 @@ function printNode(path, options, print) {
1658
1664
  join([",", line], path.map(print, "items")),
1659
1665
  ]),
1660
1666
  node.name
1661
- ? [
1662
- ifBreak(shouldPrintComma(options, "7.2") ? "," : ""),
1663
- softline,
1664
- "}",
1665
- ]
1667
+ ? [ifBreak(shouldPrintComma(options, 7.2) ? "," : ""), softline, "}"]
1666
1668
  : "",
1667
1669
  ]);
1668
1670
  case "useitem":
@@ -2356,9 +2358,8 @@ function printNode(path, options, print) {
2356
2358
  case "list":
2357
2359
  case "array": {
2358
2360
  const useShortForm =
2359
- (node.kind === "array" && isMinVersion(options.phpVersion, "5.4")) ||
2360
- (node.kind === "list" &&
2361
- (node.shortForm || isMinVersion(options.phpVersion, "7.1")));
2361
+ (node.kind === "array" && options.phpVersion >= 5.4) ||
2362
+ (node.kind === "list" && (node.shortForm || options.phpVersion >= 7.1));
2362
2363
  const open = useShortForm ? "[" : [node.kind, "("];
2363
2364
  const close = useShortForm ? "]" : ")";
2364
2365
 
@@ -2408,7 +2409,7 @@ function printNode(path, options, print) {
2408
2409
  indent([softline, printArrayItems(path, options, print)]),
2409
2410
  needsForcedTrailingComma ? "," : "",
2410
2411
  ifBreak(
2411
- !needsForcedTrailingComma && shouldPrintComma(options, "5.0")
2412
+ !needsForcedTrailingComma && shouldPrintComma(options, 5.0)
2412
2413
  ? [
2413
2414
  lastElem && shouldPrintHardlineBeforeTrailingComma(lastElem)
2414
2415
  ? hardline
@@ -2675,7 +2676,7 @@ function printNode(path, options, print) {
2675
2676
  if (parent.kind === "encapsedpart") {
2676
2677
  const parentParent = path.grandparent;
2677
2678
  let closingTagIndentation = 0;
2678
- const flexible = isMinVersion(options.phpVersion, "7.3");
2679
+ const flexible = options.phpVersion >= 7.3;
2679
2680
  let linebreak = literalline;
2680
2681
  if (parentParent.type === "heredoc") {
2681
2682
  linebreak = flexible ? hardline : literalline;
@@ -2744,7 +2745,7 @@ function printNode(path, options, print) {
2744
2745
  case "string":
2745
2746
  case "shell":
2746
2747
  case "heredoc": {
2747
- const flexible = isMinVersion(options.phpVersion, "7.3");
2748
+ const flexible = options.phpVersion >= 7.3;
2748
2749
  const linebreak = flexible ? hardline : literalline;
2749
2750
  return [
2750
2751
  getEncapsedQuotes(node),
@@ -2769,7 +2770,7 @@ function printNode(path, options, print) {
2769
2770
  case "magic":
2770
2771
  return node.value;
2771
2772
  case "nowdoc": {
2772
- const flexible = isMinVersion(options.phpVersion, "7.3");
2773
+ const flexible = options.phpVersion >= 7.3;
2773
2774
  const linebreak = flexible ? hardline : literalline;
2774
2775
  return [
2775
2776
  "<<<'",
package/src/util.mjs CHANGED
@@ -709,10 +709,6 @@ function memoize(fn) {
709
709
  };
710
710
  }
711
711
 
712
- function isMinVersion(actualVersion, requiredVersion) {
713
- return parseFloat(actualVersion) >= parseFloat(requiredVersion);
714
- }
715
-
716
712
  export {
717
713
  printNumber,
718
714
  getPrecedence,
@@ -744,5 +740,4 @@ export {
744
740
  normalizeMagicMethodName,
745
741
  isSimpleCallArgument,
746
742
  memoize,
747
- isMinVersion,
748
743
  };