@flarum/cli 3.0.4 → 3.0.5
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 +1 -1
- package/oclif.manifest.json +1 -1
- package/package.json +1 -1
- package/php-subsystem/composer.json +3 -0
- package/php-subsystem/composer.lock +76 -66
- package/php-subsystem/index.php +9 -0
- package/php-subsystem/vendor/composer/installed.json +63 -56
- package/php-subsystem/vendor/composer/installed.php +9 -9
- package/php-subsystem/vendor/composer/platform_check.php +2 -2
- package/php-subsystem/vendor/nikic/php-parser/README.md +1 -1
- package/php-subsystem/vendor/nikic/php-parser/composer.json +41 -41
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Builder/ClassConst.php +2 -2
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Builder/EnumCase.php +0 -1
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Builder/Param.php +22 -0
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Builder/Property.php +63 -1
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/BuilderFactory.php +1 -1
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/BuilderHelpers.php +6 -1
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Comment.php +2 -0
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Error.php +2 -0
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Internal/TokenStream.php +12 -5
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Lexer/Emulative.php +4 -4
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/AsymmetricVisibilityTokenEmulator.php +93 -0
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/KeywordEmulator.php +6 -2
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/PropertyTokenEmulator.php +19 -0
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Modifiers.php +42 -26
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/NameContext.php +1 -1
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Identifier.php +11 -1
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Name.php +10 -1
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Param.php +28 -2
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/PropertyHook.php +78 -0
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Property.php +15 -0
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Property.php +27 -2
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node.php +4 -0
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/NodeAbstract.php +3 -0
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/NodeDumper.php +9 -0
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php +6 -0
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Parser/Php7.php +1210 -1119
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Parser/Php8.php +1210 -1141
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/ParserAbstract.php +82 -57
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/PhpVersion.php +1 -1
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinter/Standard.php +17 -2
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php +49 -11
- package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/compatibility_tokens.php +5 -0
|
@@ -7,6 +7,7 @@ namespace PhpParser;
|
|
|
7
7
|
* turn is based on work by Masato Bito.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
use PhpParser\Node\Arg;
|
|
10
11
|
use PhpParser\Node\Expr;
|
|
11
12
|
use PhpParser\Node\Expr\Array_;
|
|
12
13
|
use PhpParser\Node\Expr\Cast\Double;
|
|
@@ -14,6 +15,7 @@ use PhpParser\Node\Identifier;
|
|
|
14
15
|
use PhpParser\Node\InterpolatedStringPart;
|
|
15
16
|
use PhpParser\Node\Name;
|
|
16
17
|
use PhpParser\Node\Param;
|
|
18
|
+
use PhpParser\Node\PropertyHook;
|
|
17
19
|
use PhpParser\Node\Scalar\InterpolatedString;
|
|
18
20
|
use PhpParser\Node\Scalar\Int_;
|
|
19
21
|
use PhpParser\Node\Scalar\String_;
|
|
@@ -1137,45 +1139,87 @@ abstract class ParserAbstract implements Parser {
|
|
|
1137
1139
|
}
|
|
1138
1140
|
|
|
1139
1141
|
protected function checkClassConst(ClassConst $node, int $modifierPos): void {
|
|
1140
|
-
|
|
1142
|
+
foreach ([Modifiers::STATIC, Modifiers::ABSTRACT, Modifiers::READONLY] as $modifier) {
|
|
1143
|
+
if ($node->flags & $modifier) {
|
|
1144
|
+
$this->emitError(new Error(
|
|
1145
|
+
"Cannot use '" . Modifiers::toString($modifier) . "' as constant modifier",
|
|
1146
|
+
$this->getAttributesAt($modifierPos)));
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
protected function checkUseUse(UseItem $node, int $namePos): void {
|
|
1152
|
+
if ($node->alias && $node->alias->isSpecialClassName()) {
|
|
1141
1153
|
$this->emitError(new Error(
|
|
1142
|
-
|
|
1143
|
-
|
|
1154
|
+
sprintf(
|
|
1155
|
+
'Cannot use %s as %s because \'%2$s\' is a special class name',
|
|
1156
|
+
$node->name, $node->alias
|
|
1157
|
+
),
|
|
1158
|
+
$this->getAttributesAt($namePos)
|
|
1159
|
+
));
|
|
1144
1160
|
}
|
|
1145
|
-
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
/** @param PropertyHook[] $hooks */
|
|
1164
|
+
protected function checkPropertyHookList(array $hooks, int $hookPos): void {
|
|
1165
|
+
if (empty($hooks)) {
|
|
1146
1166
|
$this->emitError(new Error(
|
|
1147
|
-
|
|
1148
|
-
$this->getAttributesAt($modifierPos)));
|
|
1167
|
+
'Property hook list cannot be empty', $this->getAttributesAt($hookPos)));
|
|
1149
1168
|
}
|
|
1150
|
-
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
protected function checkPropertyHook(PropertyHook $hook, ?int $paramListPos): void {
|
|
1172
|
+
$name = $hook->name->toLowerString();
|
|
1173
|
+
if ($name !== 'get' && $name !== 'set') {
|
|
1151
1174
|
$this->emitError(new Error(
|
|
1152
|
-
"
|
|
1153
|
-
$
|
|
1175
|
+
'Unknown hook "' . $hook->name . '", expected "get" or "set"',
|
|
1176
|
+
$hook->name->getAttributes()));
|
|
1177
|
+
}
|
|
1178
|
+
if ($name === 'get' && $paramListPos !== null) {
|
|
1179
|
+
$this->emitError(new Error(
|
|
1180
|
+
'get hook must not have a parameter list', $this->getAttributesAt($paramListPos)));
|
|
1154
1181
|
}
|
|
1155
1182
|
}
|
|
1156
1183
|
|
|
1157
|
-
protected function
|
|
1158
|
-
|
|
1159
|
-
$
|
|
1160
|
-
|
|
1184
|
+
protected function checkPropertyHookModifiers(int $a, int $b, int $modifierPos): void {
|
|
1185
|
+
try {
|
|
1186
|
+
Modifiers::verifyModifier($a, $b);
|
|
1187
|
+
} catch (Error $error) {
|
|
1188
|
+
$error->setAttributes($this->getAttributesAt($modifierPos));
|
|
1189
|
+
$this->emitError($error);
|
|
1161
1190
|
}
|
|
1162
1191
|
|
|
1163
|
-
if ($
|
|
1164
|
-
$this->emitError(new Error(
|
|
1192
|
+
if ($b != Modifiers::FINAL) {
|
|
1193
|
+
$this->emitError(new Error(
|
|
1194
|
+
'Cannot use the ' . Modifiers::toString($b) . ' modifier on a property hook',
|
|
1165
1195
|
$this->getAttributesAt($modifierPos)));
|
|
1166
1196
|
}
|
|
1167
1197
|
}
|
|
1168
1198
|
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1199
|
+
/** @param array<Node\Arg|Node\VariadicPlaceholder> $args */
|
|
1200
|
+
private function isSimpleExit(array $args): bool {
|
|
1201
|
+
if (\count($args) === 0) {
|
|
1202
|
+
return true;
|
|
1203
|
+
}
|
|
1204
|
+
if (\count($args) === 1) {
|
|
1205
|
+
$arg = $args[0];
|
|
1206
|
+
return $arg instanceof Arg && $arg->name === null &&
|
|
1207
|
+
$arg->byRef === false && $arg->unpack === false;
|
|
1208
|
+
}
|
|
1209
|
+
return false;
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
/**
|
|
1213
|
+
* @param array<Node\Arg|Node\VariadicPlaceholder> $args
|
|
1214
|
+
* @param array<string, mixed> $attrs
|
|
1215
|
+
*/
|
|
1216
|
+
protected function createExitExpr(string $name, int $namePos, array $args, array $attrs): Expr {
|
|
1217
|
+
if ($this->isSimpleExit($args)) {
|
|
1218
|
+
// Create Exit node for backwards compatibility.
|
|
1219
|
+
$attrs['kind'] = strtolower($name) === 'exit' ? Expr\Exit_::KIND_EXIT : Expr\Exit_::KIND_DIE;
|
|
1220
|
+
return new Expr\Exit_(\count($args) === 1 ? $args[0]->value : null, $attrs);
|
|
1178
1221
|
}
|
|
1222
|
+
return new Expr\FuncCall(new Name($name, $this->getAttributesAt($namePos)), $args, $attrs);
|
|
1179
1223
|
}
|
|
1180
1224
|
|
|
1181
1225
|
/**
|
|
@@ -1190,42 +1234,23 @@ abstract class ParserAbstract implements Parser {
|
|
|
1190
1234
|
protected function createTokenMap(): array {
|
|
1191
1235
|
$tokenMap = [];
|
|
1192
1236
|
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
// T_OPEN_TAG_WITH_ECHO with dropped T_OPEN_TAG results in T_ECHO
|
|
1202
|
-
$tokenMap[$i] = static::T_ECHO;
|
|
1203
|
-
} elseif (\T_CLOSE_TAG === $i) {
|
|
1204
|
-
// T_CLOSE_TAG is equivalent to ';'
|
|
1205
|
-
$tokenMap[$i] = ord(';');
|
|
1206
|
-
} elseif ('UNKNOWN' !== $name = token_name($i)) {
|
|
1207
|
-
if (defined($name = static::class . '::' . $name)) {
|
|
1208
|
-
// Other tokens can be mapped directly
|
|
1209
|
-
$tokenMap[$i] = constant($name);
|
|
1210
|
-
}
|
|
1237
|
+
// Single-char tokens use an identity mapping.
|
|
1238
|
+
for ($i = 0; $i < 256; ++$i) {
|
|
1239
|
+
$tokenMap[$i] = $i;
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
foreach ($this->symbolToName as $name) {
|
|
1243
|
+
if ($name[0] === 'T') {
|
|
1244
|
+
$tokenMap[\constant($name)] = constant(static::class . '::' . $name);
|
|
1211
1245
|
}
|
|
1212
1246
|
}
|
|
1213
1247
|
|
|
1214
|
-
//
|
|
1215
|
-
$tokenMap[\
|
|
1216
|
-
|
|
1217
|
-
$tokenMap[\
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
$tokenMap[\T_MATCH] = static::T_MATCH;
|
|
1221
|
-
$tokenMap[\T_NULLSAFE_OBJECT_OPERATOR] = static::T_NULLSAFE_OBJECT_OPERATOR;
|
|
1222
|
-
$tokenMap[\T_ATTRIBUTE] = static::T_ATTRIBUTE;
|
|
1223
|
-
$tokenMap[\T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG] = static::T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG;
|
|
1224
|
-
$tokenMap[\T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG] = static::T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG;
|
|
1225
|
-
$tokenMap[\T_ENUM] = static::T_ENUM;
|
|
1226
|
-
$tokenMap[\T_READONLY] = static::T_READONLY;
|
|
1227
|
-
|
|
1228
|
-
// We have create a map from PHP token IDs to external symbol IDs.
|
|
1248
|
+
// T_OPEN_TAG_WITH_ECHO with dropped T_OPEN_TAG results in T_ECHO
|
|
1249
|
+
$tokenMap[\T_OPEN_TAG_WITH_ECHO] = static::T_ECHO;
|
|
1250
|
+
// T_CLOSE_TAG is equivalent to ';'
|
|
1251
|
+
$tokenMap[\T_CLOSE_TAG] = ord(';');
|
|
1252
|
+
|
|
1253
|
+
// We have created a map from PHP token IDs to external symbol IDs.
|
|
1229
1254
|
// Now map them to the internal symbol ID.
|
|
1230
1255
|
$fullTokenMap = [];
|
|
1231
1256
|
foreach ($tokenMap as $phpToken => $extSymbol) {
|
|
@@ -23,7 +23,8 @@ class Standard extends PrettyPrinterAbstract {
|
|
|
23
23
|
. ($node->byRef ? '&' : '')
|
|
24
24
|
. ($node->variadic ? '...' : '')
|
|
25
25
|
. $this->p($node->var)
|
|
26
|
-
. ($node->default ? ' = ' . $this->p($node->default) : '')
|
|
26
|
+
. ($node->default ? ' = ' . $this->p($node->default) : '')
|
|
27
|
+
. ($node->hooks ? ' {' . $this->pStmts($node->hooks) . $this->nl . '}' : '');
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
protected function pArg(Node\Arg $node): string {
|
|
@@ -125,6 +126,10 @@ class Standard extends PrettyPrinterAbstract {
|
|
|
125
126
|
return '__TRAIT__';
|
|
126
127
|
}
|
|
127
128
|
|
|
129
|
+
protected function pScalar_MagicConst_Property(MagicConst\Property $node): string {
|
|
130
|
+
return '__PROPERTY__';
|
|
131
|
+
}
|
|
132
|
+
|
|
128
133
|
// Scalars
|
|
129
134
|
|
|
130
135
|
private function indentString(string $str): string {
|
|
@@ -827,7 +832,8 @@ class Standard extends PrettyPrinterAbstract {
|
|
|
827
832
|
return $this->pAttrGroups($node->attrGroups)
|
|
828
833
|
. (0 === $node->flags ? 'var ' : $this->pModifiers($node->flags))
|
|
829
834
|
. ($node->type ? $this->p($node->type) . ' ' : '')
|
|
830
|
-
. $this->pCommaSeparated($node->props)
|
|
835
|
+
. $this->pCommaSeparated($node->props)
|
|
836
|
+
. ($node->hooks ? ' {' . $this->pStmts($node->hooks) . $this->nl . '}' : ';');
|
|
831
837
|
}
|
|
832
838
|
|
|
833
839
|
protected function pPropertyItem(Node\PropertyItem $node): string {
|
|
@@ -835,6 +841,15 @@ class Standard extends PrettyPrinterAbstract {
|
|
|
835
841
|
. (null !== $node->default ? ' = ' . $this->p($node->default) : '');
|
|
836
842
|
}
|
|
837
843
|
|
|
844
|
+
protected function pPropertyHook(Node\PropertyHook $node): string {
|
|
845
|
+
return $this->pAttrGroups($node->attrGroups)
|
|
846
|
+
. $this->pModifiers($node->flags)
|
|
847
|
+
. ($node->byRef ? '&' : '') . $node->name
|
|
848
|
+
. ($node->params ? '(' . $this->pMaybeMultiline($node->params, $this->phpVersion->supportsTrailingCommaInParamList()) . ')' : '')
|
|
849
|
+
. (\is_array($node->body) ? ' {' . $this->pStmts($node->body) . $this->nl . '}'
|
|
850
|
+
: ($node->body !== null ? ' => ' . $this->p($node->body) : '') . ';');
|
|
851
|
+
}
|
|
852
|
+
|
|
838
853
|
protected function pStmt_ClassMethod(Stmt\ClassMethod $node): string {
|
|
839
854
|
return $this->pAttrGroups($node->attrGroups)
|
|
840
855
|
. $this->pModifiers($node->flags)
|
|
@@ -14,6 +14,7 @@ use PhpParser\Node\Expr\Cast;
|
|
|
14
14
|
use PhpParser\Node\IntersectionType;
|
|
15
15
|
use PhpParser\Node\MatchArm;
|
|
16
16
|
use PhpParser\Node\Param;
|
|
17
|
+
use PhpParser\Node\PropertyHook;
|
|
17
18
|
use PhpParser\Node\Scalar;
|
|
18
19
|
use PhpParser\Node\Stmt;
|
|
19
20
|
use PhpParser\Node\UnionType;
|
|
@@ -76,7 +77,7 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
|
|
|
76
77
|
BinaryOp\BooleanAnd::class => [120, 121, 120],
|
|
77
78
|
BinaryOp\BooleanOr::class => [130, 131, 130],
|
|
78
79
|
BinaryOp\Coalesce::class => [140, 140, 141],
|
|
79
|
-
Expr\Ternary::class => [150,
|
|
80
|
+
Expr\Ternary::class => [150, 150, 150],
|
|
80
81
|
Expr\Assign::class => [160, -1, -1],
|
|
81
82
|
Expr\AssignRef::class => [160, -1, -1],
|
|
82
83
|
AssignOp\Plus::class => [160, -1, -1],
|
|
@@ -105,6 +106,15 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
|
|
|
105
106
|
|
|
106
107
|
/** @var int Current indentation level. */
|
|
107
108
|
protected int $indentLevel;
|
|
109
|
+
/** @var string String for single level of indentation */
|
|
110
|
+
private string $indent;
|
|
111
|
+
/** @var int Width in spaces to indent by. */
|
|
112
|
+
private int $indentWidth;
|
|
113
|
+
/** @var bool Whether to use tab indentation. */
|
|
114
|
+
private bool $useTabs;
|
|
115
|
+
/** @var int Width in spaces of one tab. */
|
|
116
|
+
private int $tabWidth = 4;
|
|
117
|
+
|
|
108
118
|
/** @var string Newline style. Does not include current indentation. */
|
|
109
119
|
protected string $newline;
|
|
110
120
|
/** @var string Newline including current indentation. */
|
|
@@ -169,12 +179,14 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
|
|
|
169
179
|
* PHP version while specifying an older target (but the result will
|
|
170
180
|
* of course not be compatible with the older version in that case).
|
|
171
181
|
* * string $newline: The newline style to use. Should be "\n" (default) or "\r\n".
|
|
182
|
+
* * string $indent: The indentation to use. Should either be all spaces or a single
|
|
183
|
+
* tab. Defaults to four spaces (" ").
|
|
172
184
|
* * bool $shortArraySyntax: Whether to use [] instead of array() as the default array
|
|
173
185
|
* syntax, if the node does not specify a format. Defaults to whether
|
|
174
186
|
* the phpVersion support short array syntax.
|
|
175
187
|
*
|
|
176
188
|
* @param array{
|
|
177
|
-
* phpVersion?: PhpVersion, newline?: string, shortArraySyntax?: bool
|
|
189
|
+
* phpVersion?: PhpVersion, newline?: string, indent?: string, shortArraySyntax?: bool
|
|
178
190
|
* } $options Dictionary of formatting options
|
|
179
191
|
*/
|
|
180
192
|
public function __construct(array $options = []) {
|
|
@@ -189,6 +201,17 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
|
|
|
189
201
|
$options['shortArraySyntax'] ?? $this->phpVersion->supportsShortArraySyntax();
|
|
190
202
|
$this->docStringEndToken =
|
|
191
203
|
$this->phpVersion->supportsFlexibleHeredoc() ? null : '_DOC_STRING_END_' . mt_rand();
|
|
204
|
+
|
|
205
|
+
$this->indent = $indent = $options['indent'] ?? ' ';
|
|
206
|
+
if ($indent === "\t") {
|
|
207
|
+
$this->useTabs = true;
|
|
208
|
+
$this->indentWidth = $this->tabWidth;
|
|
209
|
+
} elseif ($indent === \str_repeat(' ', \strlen($indent))) {
|
|
210
|
+
$this->useTabs = false;
|
|
211
|
+
$this->indentWidth = \strlen($indent);
|
|
212
|
+
} else {
|
|
213
|
+
throw new \LogicException('Option "indent" must either be all spaces or a single tab');
|
|
214
|
+
}
|
|
192
215
|
}
|
|
193
216
|
|
|
194
217
|
/**
|
|
@@ -207,24 +230,29 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
|
|
|
207
230
|
*/
|
|
208
231
|
protected function setIndentLevel(int $level): void {
|
|
209
232
|
$this->indentLevel = $level;
|
|
210
|
-
|
|
233
|
+
if ($this->useTabs) {
|
|
234
|
+
$tabs = \intdiv($level, $this->tabWidth);
|
|
235
|
+
$spaces = $level % $this->tabWidth;
|
|
236
|
+
$this->nl = $this->newline . \str_repeat("\t", $tabs) . \str_repeat(' ', $spaces);
|
|
237
|
+
} else {
|
|
238
|
+
$this->nl = $this->newline . \str_repeat(' ', $level);
|
|
239
|
+
}
|
|
211
240
|
}
|
|
212
241
|
|
|
213
242
|
/**
|
|
214
243
|
* Increase indentation level.
|
|
215
244
|
*/
|
|
216
245
|
protected function indent(): void {
|
|
217
|
-
$this->indentLevel +=
|
|
218
|
-
$this->nl .=
|
|
246
|
+
$this->indentLevel += $this->indentWidth;
|
|
247
|
+
$this->nl .= $this->indent;
|
|
219
248
|
}
|
|
220
249
|
|
|
221
250
|
/**
|
|
222
251
|
* Decrease indentation level.
|
|
223
252
|
*/
|
|
224
253
|
protected function outdent(): void {
|
|
225
|
-
assert($this->indentLevel >=
|
|
226
|
-
$this->indentLevel
|
|
227
|
-
$this->nl = $this->newline . str_repeat(' ', $this->indentLevel);
|
|
254
|
+
assert($this->indentLevel >= $this->indentWidth);
|
|
255
|
+
$this->setIndentLevel($this->indentLevel - $this->indentWidth);
|
|
228
256
|
}
|
|
229
257
|
|
|
230
258
|
/**
|
|
@@ -536,7 +564,7 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
|
|
|
536
564
|
$this->initializeModifierChangeMap();
|
|
537
565
|
|
|
538
566
|
$this->resetState();
|
|
539
|
-
$this->origTokens = new TokenStream($origTokens);
|
|
567
|
+
$this->origTokens = new TokenStream($origTokens, $this->tabWidth);
|
|
540
568
|
|
|
541
569
|
$this->preprocessNodes($stmts);
|
|
542
570
|
|
|
@@ -708,7 +736,7 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
|
|
|
708
736
|
$result .= $extraLeft;
|
|
709
737
|
|
|
710
738
|
$origIndentLevel = $this->indentLevel;
|
|
711
|
-
$this->setIndentLevel($this->origTokens->getIndentationBefore($subStartPos) + $indentAdjustment);
|
|
739
|
+
$this->setIndentLevel(max($this->origTokens->getIndentationBefore($subStartPos) + $indentAdjustment, 0));
|
|
712
740
|
|
|
713
741
|
// If it's the same node that was previously in this position, it certainly doesn't
|
|
714
742
|
// need fixup. It's important to check this here, because our fixup checks are more
|
|
@@ -811,7 +839,7 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
|
|
|
811
839
|
\assert($itemStartPos >= 0 && $itemEndPos >= 0 && $itemStartPos >= $pos);
|
|
812
840
|
|
|
813
841
|
$origIndentLevel = $this->indentLevel;
|
|
814
|
-
$lastElemIndentLevel = $this->origTokens->getIndentationBefore($itemStartPos) + $indentAdjustment;
|
|
842
|
+
$lastElemIndentLevel = max($this->origTokens->getIndentationBefore($itemStartPos) + $indentAdjustment, 0);
|
|
815
843
|
$this->setIndentLevel($lastElemIndentLevel);
|
|
816
844
|
|
|
817
845
|
$comments = $arrItem->getComments();
|
|
@@ -1195,6 +1223,9 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
|
|
|
1195
1223
|
. ($modifiers & Modifiers::PUBLIC ? 'public ' : '')
|
|
1196
1224
|
. ($modifiers & Modifiers::PROTECTED ? 'protected ' : '')
|
|
1197
1225
|
. ($modifiers & Modifiers::PRIVATE ? 'private ' : '')
|
|
1226
|
+
. ($modifiers & Modifiers::PUBLIC_SET ? 'public(set) ' : '')
|
|
1227
|
+
. ($modifiers & Modifiers::PROTECTED_SET ? 'protected(set) ' : '')
|
|
1228
|
+
. ($modifiers & Modifiers::PRIVATE_SET ? 'private(set) ' : '')
|
|
1198
1229
|
. ($modifiers & Modifiers::STATIC ? 'static ' : '')
|
|
1199
1230
|
. ($modifiers & Modifiers::READONLY ? 'readonly ' : '');
|
|
1200
1231
|
}
|
|
@@ -1517,6 +1548,7 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
|
|
|
1517
1548
|
Stmt\UseUse::class . '->uses' => ', ',
|
|
1518
1549
|
MatchArm::class . '->conds' => ', ',
|
|
1519
1550
|
AttributeGroup::class . '->attrs' => ', ',
|
|
1551
|
+
PropertyHook::class . '->params' => ', ',
|
|
1520
1552
|
|
|
1521
1553
|
// statement lists
|
|
1522
1554
|
Expr\Closure::class . '->stmts' => "\n",
|
|
@@ -1554,10 +1586,15 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
|
|
|
1554
1586
|
Expr\Closure::class . '->attrGroups' => ' ',
|
|
1555
1587
|
Expr\ArrowFunction::class . '->attrGroups' => ' ',
|
|
1556
1588
|
Param::class . '->attrGroups' => ' ',
|
|
1589
|
+
PropertyHook::class . '->attrGroups' => ' ',
|
|
1590
|
+
|
|
1557
1591
|
Stmt\Switch_::class . '->cases' => "\n",
|
|
1558
1592
|
Stmt\TraitUse::class . '->adaptations' => "\n",
|
|
1559
1593
|
Stmt\TryCatch::class . '->stmts' => "\n",
|
|
1560
1594
|
Stmt\While_::class . '->stmts' => "\n",
|
|
1595
|
+
PropertyHook::class . '->body' => "\n",
|
|
1596
|
+
Stmt\Property::class . '->hooks' => "\n",
|
|
1597
|
+
Param::class . '->hooks' => "\n",
|
|
1561
1598
|
|
|
1562
1599
|
// dummy for top-level context
|
|
1563
1600
|
'File->stmts' => "\n",
|
|
@@ -1641,6 +1678,7 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
|
|
|
1641
1678
|
Stmt\Property::class . '->flags' => ['pModifiers', \T_VARIABLE],
|
|
1642
1679
|
PrintableNewAnonClassNode::class . '->flags' => ['pModifiers', \T_CLASS],
|
|
1643
1680
|
Param::class . '->flags' => ['pModifiers', \T_VARIABLE],
|
|
1681
|
+
PropertyHook::class . '->flags' => ['pModifiers', \T_STRING],
|
|
1644
1682
|
Expr\Closure::class . '->static' => ['pStatic', \T_FUNCTION],
|
|
1645
1683
|
Expr\ArrowFunction::class . '->static' => ['pStatic', \T_FN],
|
|
1646
1684
|
//Stmt\TraitUseAdaptation\Alias::class . '->newModifier' => 0, // TODO
|
|
@@ -17,6 +17,11 @@ if (!\function_exists('PhpParser\defineCompatibilityTokens')) {
|
|
|
17
17
|
'T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG',
|
|
18
18
|
'T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG',
|
|
19
19
|
'T_READONLY',
|
|
20
|
+
// PHP 8.4
|
|
21
|
+
'T_PROPERTY_C',
|
|
22
|
+
'T_PUBLIC_SET',
|
|
23
|
+
'T_PROTECTED_SET',
|
|
24
|
+
'T_PRIVATE_SET',
|
|
20
25
|
];
|
|
21
26
|
|
|
22
27
|
// PHP-Parser might be used together with another library that also emulates some or all
|