← All changes
|
vendor/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php
+82
-12
3.3
→
3.5.9
View file →
| @@ -20,8 +20,10 @@ | ||
| 20 | 20 | const FIXUP_DEREF_LHS = 3; // LHS of dereferencing operation |
| 21 | 21 | const FIXUP_BRACED_NAME = 4; // Name operand that may require bracing |
| 22 | 22 | const FIXUP_VAR_BRACED_NAME = 5; // Name operand that may require ${} bracing |
| 23 | 23 | const FIXUP_ENCAPSED = 6; // Encapsed string part |
| 24 | + const FIXUP_NEW = 7; // New/instanceof operand | |
| 25 | + const FIXUP_STATIC_DEREF_LHS = 8; // LHS of static dereferencing operation | |
| 24 | 26 | |
| 25 | 27 | protected $precedenceMap = [ |
| 26 | 28 | // [precedence, associativity] |
| 27 | 29 | // where for precedence -1 is %left, 0 is %nonassoc and 1 is %right |
| @@ -655,9 +657,9 @@ | ||
| 655 | 657 | if (null !== $subNode) { |
| 656 | 658 | $result .= $extraLeft; |
| 657 | 659 | |
| 658 | 660 | $origIndentLevel = $this->indentLevel; |
| 659 | - $this->setIndentLevel($this->origTokens->getIndentationBefore($subStartPos) + $indentAdjustment); | |
| 661 | + $this->setIndentLevel(max($this->origTokens->getIndentationBefore($subStartPos) + $indentAdjustment, 0)); | |
| 660 | 662 | |
| 661 | 663 | // If it's the same node that was previously in this position, it certainly doesn't |
| 662 | 664 | // need fixup. It's important to check this here, because our fixup checks are more |
| 663 | 665 | // conservative than strictly necessary. |
| @@ -758,9 +760,9 @@ | ||
| 758 | 760 | $itemEndPos = $origArrItem->getEndTokenPos(); |
| 759 | 761 | \assert($itemStartPos >= 0 && $itemEndPos >= 0 && $itemStartPos >= $pos); |
| 760 | 762 | |
| 761 | 763 | $origIndentLevel = $this->indentLevel; |
| 762 | - $lastElemIndentLevel = $this->origTokens->getIndentationBefore($itemStartPos) + $indentAdjustment; | |
| 764 | + $lastElemIndentLevel = max($this->origTokens->getIndentationBefore($itemStartPos) + $indentAdjustment, 0); | |
| 763 | 765 | $this->setIndentLevel($lastElemIndentLevel); |
| 764 | 766 | |
| 765 | 767 | $comments = $arrItem->getComments(); |
| 766 | 768 | $origComments = $origArrItem->getComments(); |
| @@ -773,9 +775,10 @@ | ||
| 773 | 775 | $commentStartPos = $itemStartPos; |
| 774 | 776 | } |
| 775 | 777 | |
| 776 | 778 | if ($skipRemovedNode) { |
| 777 | - if ($isStmtList && $this->origTokens->haveBracesInRange($pos, $itemStartPos)) { | |
| 779 | + if ($isStmtList && ($this->origTokens->haveBracesInRange($pos, $itemStartPos) || | |
| 780 | + $this->origTokens->haveTagInRange($pos, $itemStartPos))) { | |
| 778 | 781 | // We'd remove the brace of a code block. |
| 779 | 782 | // TODO: Preserve formatting. |
| 780 | 783 | $this->setIndentLevel($origIndentLevel); |
| 781 | 784 | return null; |
| @@ -876,9 +879,10 @@ | ||
| 876 | 879 | $result .= $this->origTokens->getTokenCode( |
| 877 | 880 | $pos, $itemStartPos, $indentAdjustment); |
| 878 | 881 | $skipRemovedNode = true; |
| 879 | 882 | } else { |
| 880 | - if ($isStmtList && $this->origTokens->haveBracesInRange($pos, $itemStartPos)) { | |
| 883 | + if ($isStmtList && ($this->origTokens->haveBracesInRange($pos, $itemStartPos) || | |
| 884 | + $this->origTokens->haveTagInRange($pos, $itemStartPos))) { | |
| 881 | 885 | // We'd remove the brace of a code block. |
| 882 | 886 | // TODO: Preserve formatting. |
| 883 | 887 | return null; |
| 884 | 888 | } |
| @@ -922,13 +926,16 @@ | ||
| 922 | 926 | $result .= $extraLeft; |
| 923 | 927 | foreach ($delayedAdd as $delayedAddNode) { |
| 924 | 928 | if (!$first) { |
| 925 | 929 | $result .= $insertStr; |
| 930 | + if ($insertNewline) { | |
| 931 | + $result .= $this->nl; | |
| 932 | + } | |
| 926 | 933 | } |
| 927 | 934 | $result .= $this->p($delayedAddNode, true); |
| 928 | 935 | $first = false; |
| 929 | 936 | } |
| 930 | - $result .= $extraRight; | |
| 937 | + $result .= $extraRight === "\n" ? $this->nl : $extraRight; | |
| 931 | 938 | } |
| 932 | 939 | |
| 933 | 940 | return $result; |
| 934 | 941 | } |
| @@ -971,8 +978,21 @@ | ||
| 971 | 978 | ) { |
| 972 | 979 | return '(' . $this->p($subNode) . ')'; |
| 973 | 980 | } |
| 974 | 981 | break; |
| 982 | + case self::FIXUP_STATIC_DEREF_LHS: | |
| 983 | + if ($this->staticDereferenceLhsRequiresParens($subNode) | |
| 984 | + && !$this->origTokens->haveParens($subStartPos, $subEndPos) | |
| 985 | + ) { | |
| 986 | + return '(' . $this->p($subNode) . ')'; | |
| 987 | + } | |
| 988 | + break; | |
| 989 | + case self::FIXUP_NEW: | |
| 990 | + if ($this->newOperandRequiresParens($subNode) | |
| 991 | + && !$this->origTokens->haveParens($subStartPos, $subEndPos)) { | |
| 992 | + return '(' . $this->p($subNode) . ')'; | |
| 993 | + } | |
| 994 | + break; | |
| 975 | 995 | case self::FIXUP_BRACED_NAME: |
| 976 | 996 | case self::FIXUP_VAR_BRACED_NAME: |
| 977 | 997 | if ($subNode instanceof Expr |
| 978 | 998 | && !$this->origTokens->haveBraces($subStartPos, $subEndPos) |
| @@ -1041,9 +1061,9 @@ | ||
| 1041 | 1061 | || $node instanceof Expr\Array_); |
| 1042 | 1062 | } |
| 1043 | 1063 | |
| 1044 | 1064 | /** |
| 1045 | - * Determines whether the LHS of a dereferencing operation must be wrapped in parenthesis. | |
| 1065 | + * Determines whether the LHS of an array/object operation must be wrapped in parentheses. | |
| 1046 | 1066 | * |
| 1047 | 1067 | * @param Node $node LHS of dereferencing operation |
| 1048 | 1068 | * |
| 1049 | 1069 | * @return bool Whether parentheses are required |
| @@ -1048,8 +1068,21 @@ | ||
| 1048 | 1068 | * |
| 1049 | 1069 | * @return bool Whether parentheses are required |
| 1050 | 1070 | */ |
| 1051 | 1071 | protected function dereferenceLhsRequiresParens(Node $node) : bool { |
| 1072 | + // A constant can occur on the LHS of an array/object deref, but not a static deref. | |
| 1073 | + return $this->staticDereferenceLhsRequiresParens($node) | |
| 1074 | + && !$node instanceof Expr\ConstFetch; | |
| 1075 | + } | |
| 1076 | + | |
| 1077 | + /** | |
| 1078 | + * Determines whether the LHS of a static operation must be wrapped in parentheses. | |
| 1079 | + * | |
| 1080 | + * @param Node $node LHS of dereferencing operation | |
| 1081 | + * | |
| 1082 | + * @return bool Whether parentheses are required | |
| 1083 | + */ | |
| 1084 | + protected function staticDereferenceLhsRequiresParens(Node $node): bool { | |
| 1052 | 1085 | return !($node instanceof Expr\Variable |
| 1053 | 1086 | || $node instanceof Node\Name |
| 1054 | 1087 | || $node instanceof Expr\ArrayDimFetch |
| 1055 | 1088 | || $node instanceof Expr\PropertyFetch |
| @@ -1060,13 +1093,34 @@ | ||
| 1060 | 1093 | || $node instanceof Expr\NullsafeMethodCall |
| 1061 | 1094 | || $node instanceof Expr\StaticCall |
| 1062 | 1095 | || $node instanceof Expr\Array_ |
| 1063 | 1096 | || $node instanceof Scalar\String_ |
| 1064 | - || $node instanceof Expr\ConstFetch | |
| 1065 | 1097 | || $node instanceof Expr\ClassConstFetch); |
| 1066 | 1098 | } |
| 1067 | 1099 | |
| 1068 | 1100 | /** |
| 1101 | + * Determines whether an expression used in "new" or "instanceof" requires parentheses. | |
| 1102 | + * | |
| 1103 | + * @param Node $node New or instanceof operand | |
| 1104 | + * | |
| 1105 | + * @return bool Whether parentheses are required | |
| 1106 | + */ | |
| 1107 | + protected function newOperandRequiresParens(Node $node): bool { | |
| 1108 | + if ($node instanceof Node\Name || $node instanceof Expr\Variable) { | |
| 1109 | + return false; | |
| 1110 | + } | |
| 1111 | + if ($node instanceof Expr\ArrayDimFetch || $node instanceof Expr\PropertyFetch || | |
| 1112 | + $node instanceof Expr\NullsafePropertyFetch | |
| 1113 | + ) { | |
| 1114 | + return $this->newOperandRequiresParens($node->var); | |
| 1115 | + } | |
| 1116 | + if ($node instanceof Expr\StaticPropertyFetch) { | |
| 1117 | + return $this->newOperandRequiresParens($node->class); | |
| 1118 | + } | |
| 1119 | + return true; | |
| 1120 | + } | |
| 1121 | + | |
| 1122 | + /** | |
| 1069 | 1123 | * Print modifiers, including trailing whitespace. |
| 1070 | 1124 | * |
| 1071 | 1125 | * @param int $modifiers Modifier mask to print |
| 1072 | 1126 | * |
| @@ -1165,9 +1219,9 @@ | ||
| 1165 | 1219 | Expr\PostInc::class => ['var' => self::FIXUP_PREC_LEFT], |
| 1166 | 1220 | Expr\PostDec::class => ['var' => self::FIXUP_PREC_LEFT], |
| 1167 | 1221 | Expr\Instanceof_::class => [ |
| 1168 | 1222 | 'expr' => self::FIXUP_PREC_LEFT, |
| 1169 | - 'class' => self::FIXUP_PREC_RIGHT, // TODO: FIXUP_NEW_VARIABLE | |
| 1223 | + 'class' => self::FIXUP_NEW, | |
| 1170 | 1224 | ], |
| 1171 | 1225 | Expr\Ternary::class => [ |
| 1172 | 1226 | 'cond' => self::FIXUP_PREC_LEFT, |
| 1173 | 1227 | 'else' => self::FIXUP_PREC_RIGHT, |
| @@ -1173,12 +1227,15 @@ | ||
| 1173 | 1227 | 'else' => self::FIXUP_PREC_RIGHT, |
| 1174 | 1228 | ], |
| 1175 | 1229 | |
| 1176 | 1230 | Expr\FuncCall::class => ['name' => self::FIXUP_CALL_LHS], |
| 1177 | - Expr\StaticCall::class => ['class' => self::FIXUP_DEREF_LHS], | |
| 1231 | + Expr\StaticCall::class => ['class' => self::FIXUP_STATIC_DEREF_LHS], | |
| 1178 | 1232 | Expr\ArrayDimFetch::class => ['var' => self::FIXUP_DEREF_LHS], |
| 1179 | - Expr\ClassConstFetch::class => ['var' => self::FIXUP_DEREF_LHS], | |
| 1180 | - Expr\New_::class => ['class' => self::FIXUP_DEREF_LHS], // TODO: FIXUP_NEW_VARIABLE | |
| 1233 | + Expr\ClassConstFetch::class => [ | |
| 1234 | + 'class' => self::FIXUP_STATIC_DEREF_LHS, | |
| 1235 | + 'name' => self::FIXUP_BRACED_NAME, | |
| 1236 | + ], | |
| 1237 | + Expr\New_::class => ['class' => self::FIXUP_NEW], | |
| 1181 | 1238 | Expr\MethodCall::class => [ |
| 1182 | 1239 | 'var' => self::FIXUP_DEREF_LHS, |
| 1183 | 1240 | 'name' => self::FIXUP_BRACED_NAME, |
| 1184 | 1241 | ], |
| @@ -1186,9 +1243,9 @@ | ||
| 1186 | 1243 | 'var' => self::FIXUP_DEREF_LHS, |
| 1187 | 1244 | 'name' => self::FIXUP_BRACED_NAME, |
| 1188 | 1245 | ], |
| 1189 | 1246 | Expr\StaticPropertyFetch::class => [ |
| 1190 | - 'class' => self::FIXUP_DEREF_LHS, | |
| 1247 | + 'class' => self::FIXUP_STATIC_DEREF_LHS, | |
| 1191 | 1248 | 'name' => self::FIXUP_VAR_BRACED_NAME, |
| 1192 | 1249 | ], |
| 1193 | 1250 | Expr\PropertyFetch::class => [ |
| 1194 | 1251 | 'var' => self::FIXUP_DEREF_LHS, |
| @@ -1272,8 +1329,9 @@ | ||
| 1272 | 1329 | 'Param->type' => $stripRight, |
| 1273 | 1330 | 'Param->default' => $stripEquals, |
| 1274 | 1331 | 'Stmt_Break->num' => $stripBoth, |
| 1275 | 1332 | 'Stmt_Catch->var' => $stripLeft, |
| 1333 | + 'Stmt_ClassConst->type' => $stripRight, | |
| 1276 | 1334 | 'Stmt_ClassMethod->returnType' => $stripColon, |
| 1277 | 1335 | 'Stmt_Class->extends' => ['left' => \T_EXTENDS], |
| 1278 | 1336 | 'Stmt_Enum->scalarType' => $stripColon, |
| 1279 | 1337 | 'Stmt_EnumCase->expr' => $stripEquals, |
| @@ -1313,8 +1371,9 @@ | ||
| 1313 | 1371 | 'Param->default' => [null, false, ' = ', null], |
| 1314 | 1372 | 'Stmt_Break->num' => [\T_BREAK, false, ' ', null], |
| 1315 | 1373 | 'Stmt_Catch->var' => [null, false, ' ', null], |
| 1316 | 1374 | 'Stmt_ClassMethod->returnType' => [')', false, ' : ', null], |
| 1375 | + 'Stmt_ClassConst->type' => [\T_CONST, false, ' ', null], | |
| 1317 | 1376 | 'Stmt_Class->extends' => [null, false, ' extends ', null], |
| 1318 | 1377 | 'Stmt_Enum->scalarType' => [null, false, ' : ', null], |
| 1319 | 1378 | 'Stmt_EnumCase->expr' => [null, false, ' = ', null], |
| 1320 | 1379 | 'Expr_PrintableNewAnonClass->extends' => [null, ' extends ', null], |
| @@ -1453,8 +1512,18 @@ | ||
| 1453 | 1512 | 'Stmt_Enum->implements' => [null, ' implements ', ''], |
| 1454 | 1513 | 'Stmt_ClassMethod->params' => ['(', '', ''], |
| 1455 | 1514 | 'Stmt_Interface->extends' => [null, ' extends ', ''], |
| 1456 | 1515 | 'Stmt_Function->params' => ['(', '', ''], |
| 1516 | + 'Stmt_Interface->attrGroups' => [null, '', "\n"], | |
| 1517 | + 'Stmt_Class->attrGroups' => [null, '', "\n"], | |
| 1518 | + 'Stmt_ClassConst->attrGroups' => [null, '', "\n"], | |
| 1519 | + 'Stmt_ClassMethod->attrGroups' => [null, '', "\n"], | |
| 1520 | + 'Stmt_Function->attrGroups' => [null, '', "\n"], | |
| 1521 | + 'Stmt_Property->attrGroups' => [null, '', "\n"], | |
| 1522 | + 'Stmt_Trait->attrGroups' => [null, '', "\n"], | |
| 1523 | + 'Expr_ArrowFunction->attrGroups' => [null, '', ' '], | |
| 1524 | + 'Expr_Closure->attrGroups' => [null, '', ' '], | |
| 1525 | + 'Expr_PrintableNewAnonClass->attrGroups' => [\T_NEW, ' ', ''], | |
| 1457 | 1526 | |
| 1458 | 1527 | /* These cannot be empty to start with: |
| 1459 | 1528 | * Expr_Isset->vars |
| 1460 | 1529 | * Stmt_Catch->types |
| @@ -1492,8 +1561,9 @@ | ||
| 1492 | 1561 | 'Stmt_ClassConst->flags' => \T_CONST, |
| 1493 | 1562 | 'Stmt_ClassMethod->flags' => \T_FUNCTION, |
| 1494 | 1563 | 'Stmt_Class->flags' => \T_CLASS, |
| 1495 | 1564 | 'Stmt_Property->flags' => \T_VARIABLE, |
| 1565 | + 'Expr_PrintableNewAnonClass->flags' => \T_CLASS, | |
| 1496 | 1566 | 'Param->flags' => \T_VARIABLE, |
| 1497 | 1567 | //'Stmt_TraitUseAdaptation_Alias->newModifier' => 0, // TODO |
| 1498 | 1568 | ]; |
| 1499 | 1569 | |