879 Commits

Author SHA1 Message Date
Nikita Popov
c62dda9507 Strip trailing doc string newline before parsing escape sequences
If the doc string ends on an escaped \r, it should not get eaten
as the "last newline".
2023-03-01 21:05:55 +01:00
Nikita Popov
57d4a02659 Handle isolated \r in doc string
Doc strings have a trailing \n and these will get interpreted as
\r\n and removed from the string contents.

For nowdoc, fall back to single quote if there's a trailing \r.
For heredoc, escape all isolated \r -- unlike \n and \r\n this is
really a special character, because this is no longer relevant as
an actual newline character.
2023-02-27 22:00:49 +01:00
Nikita Popov
8e100f1e69 Handle another yield edge case
match also uses =>, so we need to make sure that a trailing yield
is wrapped in parentheses.
2023-02-27 21:36:36 +01:00
Nikita Popov
fcd5934dae Prevent merging of consecutive -/+ more thoroughly
The unary -/+ or --/++ might not be the direct child. Instead
determine this by actually printing the operand and checking
whether it starts with -/+.
2023-02-27 19:07:44 +01:00
Nikita Popov
cc34c2450c Fix logic for new operand parentheses requirement
We need to perform this check recursively.
2023-02-27 19:00:33 +01:00
Nikita Popov
cb60eda774 Support yield precedence
Since PHP 7.0 yield is a proper expression, so print it with
proper precedence. If the pretty printer is configured for
older version (non-default), then always print parentheses.

There is an interesting interaction here, in that => is resolved
in favor of yield if the yield occurs as part of an array (or
outer yield). This kind of bypasses the entire precedence hierarchy
and *only* affects yield expressions. For the sake of simplicity
this is modeled via normal LHS precedence, because this will only
add unnecessary parentheses to a handful of low precedence unary
operators. If desired, a special marker for this purpose could be
added though.
2023-02-26 22:58:53 +01:00
Nikita Popov
1cb460ae38 Handle throw precedence
Now that this is an expression, we also need to handle precedence.
2023-02-26 18:33:24 +01:00
Nikita Popov
3bd38c5b2c Properly support prefix operator precedence printing
The pretty printer is supposed to produce a minimal-parentheses
printing for expressions. However, for prefix operators, we were
failing to do so in ways that are practically meaningful, e.g.
$a = yield from $b produced redundant parentheses around the
yield from.

For prefix operators, the precedence of the direct parent operator
is not actually relevant: What matters is the precedence of any
infix operator whose LHS it appears on. For example, $a . include $b
does not require parentheses, but (include $a) . $b does.

To handle this, keep separate track of the parent operator
precedence, and a special LHS precedence which is used for unary
operator printing only. Because the LHS precedence may not come
from the direct parent, we have to pass it down the call stack.
And if we do that, we may as well do the same for the parent
precedence.

This also fixes an integration test failure with php-src, because
arrow function precedence was previously not respected (and would
be ugly to respect without this change).
2023-02-26 18:26:20 +01:00
Nikita Popov
e9416a0eae Support fixup for dynamic class const name
This is new in PHP 8.3.
2023-02-26 16:00:35 +01:00
Nikita Popov
7b4a8c1ebd Properly handle static deref LHS
The rules for static and array/object deref are slightly different:
The former does not allow constants.
2023-02-26 15:57:37 +01:00
Nikita Popov
9476cff37d Doc string end label may have leading whitespace
When detecting whether the string contains the end label, allow
leading whitespace in front of it. This is legal since the
introduction of flexible doc strings.
2023-02-26 15:21:33 +01:00
Nikita Popov
6a88bdb05a Support new variables in fixup 2023-02-26 15:17:07 +01:00
Nikita Popov
1eb6b5653e Properly handle new/instanceof operand restrictions
Fixes #912.
2023-02-26 15:11:36 +01:00
Nikita Popov
d24745ddbc Respect precedence during clone pretty printing
Clone is the prefix operator with the highest operator precedence,
but was not treated as an operator at all.
2023-02-26 14:58:17 +01:00
Nikita Popov
cd3c0c11e4 Remove __halt_compiler from semi reserved keyword list
Apparently PHP does not allow use of __halt_compiler as a
semi-reserved keyword.
2023-02-26 12:32:22 +01:00
Nikita Popov
f6ddde6428 Perform end label check on escaped string
Escaping might convert a label character into an escape sequence
if it is not valid UTF-8.
2023-02-26 12:27:05 +01:00
Nikita Popov
47626c74ec Handle interpolated variable after end label
Interpolated variables start with non-label characters, and as
such also count as end label terminators since PHP 7.3.
2023-02-26 12:20:32 +01:00
Nikita Popov
ce3337b0c2 Update allowed characters after doc string label
With the introduction of flexible doc strings, the ending label
is no longer required to be followed by a semicolon or newline.
We need to prevent doc string printing if the label is followed
by any non-label character.
2023-02-26 12:14:04 +01:00
Nikita Popov
d83562e6fe Print INF as 1.0E+1000
This makes pretty printing round trip to another Float literal,
rather than a constant lookup. The 1e1000 form in particular is
chosen because that seems to be the typical form used in various
tests.
2023-02-26 09:47:19 +01:00
Nikita Popov
2df8878f5d [PHP 8.3] Support dynamic class const fetch
RFC: https://wiki.php.net/rfc/dynamic_class_constant_fetch
2023-01-29 20:49:00 +01:00
Markus Staab
8ad4129442
Declare list types (#907)
Closes #905
2022-12-14 22:59:53 +01:00
Markus Staab
4c4af21df8
Rewrote overly magic code to make it readable (#906)
New code inspired by 950bf8f1d1/lib/PhpParser/Builder/Trait_.php (L43)
2022-12-14 22:58:37 +01:00
Nikita Popov
21a3e8cac5 Fix attrGroups/attributes confusion in EnumCase builder
Found by staabm in #907.
2022-12-14 21:50:11 +01:00
Nikita Popov
4ce9781260 Fix parsing of large hex floats containing "e"
These ended up taking the code path for normal floats and being
cast to zero.
2022-11-12 16:15:32 +01:00
Nikita Popov
b0edd4c411 Bail out on PHP tags in removed code
If dropping a node would drop PHP tags, bail out of formatting
preservation. This will lose formatting, but at least produce
legal code.

Closes GH-884.
2022-09-21 20:42:21 +02:00
Nikita Popov
4bcdf74b8b Add support for perserving formatting for static modifier change
Closes GH-891.
2022-09-21 18:56:58 +02:00
Nikita Popov
0dd85ebd34 Support readonly before DNF type
This makes us match the PHP 8.2 handling of readonly. Handling of
"readonly" functions is moved to the parser to allow distinguishing
them from readonly properties with DNF types. We have to uglify the
grammar to avoid some shift/reduce conflicts. Thank you WordPress.
2022-09-18 15:32:34 +02:00
Nikita Popov
132690f2f8 Slightly more precise type 2022-09-17 21:19:37 +02:00
Nikita Popov
f7b448fa15 Bail out on list insertion of non-Node
PhpStan correctly detected that this is not supported. We could
add support for it, but for now just make sure it doesn't crash.
2022-09-17 21:14:31 +02:00
Nikita Popov
b3ad14b938 Fix some types 2022-09-17 20:33:04 +02:00
Nikita Popov
f98341f688 Specify more types 2022-09-17 18:48:56 +02:00
Nikita Popov
fc6b4890ef Specify more types 2022-09-17 16:45:25 +02:00
Nikita Popov
032b102146 Remove deprecated Error constructor
And use this chance to provide accurate position information for
namespace errors.
2022-09-11 22:05:47 +02:00
Nikita Popov
40c89cf924 Specify some more types 2022-09-11 21:54:39 +02:00
Nikita Popov
a099803d01 Use array<string, mixed> type for $attributes
Slightly more accurate, and stops PHPStan from complaining about
the missing array type information.
2022-09-11 20:51:31 +02:00
Nikita Popov
c595989e4d Support adding class constants in trait builder
These are allowed as of PHP 8.2.
2022-09-11 19:34:27 +02:00
Nikita Popov
6af204467c Add some missing property types 2022-09-11 19:30:14 +02:00
Nikita Popov
48f470eac7 Add missing return types 2022-09-11 18:17:05 +02:00
Nikita Popov
43d6332dce Add return types to PrettyPrinter\Standard 2022-09-11 17:49:41 +02:00
Nikita Popov
9b46dffb12 Fix formatting preservation for alternative elseif/else syntax
Test taken from PR #797.
2022-09-11 16:58:35 +02:00
Nikita Popov
205bd75aa8 Add isPublic() etc methods on Param node
Also isPromoted() to check for any flags.
2022-09-11 16:11:32 +02:00
Nikita Popov
031c5e6ed0 Move verifyModifier/verifyClassModifier to Modifiers class
Now that the Modifiers are in a separate class, these *internal*
verification methods should also be moved there.
2022-09-11 16:05:21 +02:00
Christopher Hertel
36b2a996ca Add isReadonly on Param node 2022-09-11 16:05:10 +02:00
Nikita Popov
b9fe3449e8 Add missing parameter types 2022-09-11 15:22:23 +02:00
Nikita Popov
e9800cf7d3 Add tools/ directory
With php-cs-fixer and phpstan. Also reformat one file.
2022-09-11 13:17:17 +02:00
Nikita Popov
9b5a2c8991 Use PHPStan level 5 2022-09-11 12:40:08 +02:00
Nikita Popov
8dfce13d77 Add phpstan baseline 2022-09-11 12:31:50 +02:00
Nikita Popov
f59f226f65 Fix some phpstan warnings 2022-09-11 12:16:12 +02:00
Jaroslav Hanslík
468c0ef6bc Fixed type in UnionType
(cherry picked from commit 2f1fd784fe5560675722a1e5cbbcece5f43bf3a0)
2022-09-10 22:42:32 +02:00
Nikita Popov
636f066b76 Use Node\ClosureUse instead of Expr\ClosureUse in parser
Fixes #883.
2022-09-05 18:35:39 +02:00