-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
PHP 8.0 | Tokenizer/PHP: tokenize the "|" for union types as T_TYPE_U…
…NION This adds a new block of logic to the `PHP::processAdditional()` method which changes the token code and type of `T_BITWISE_OR` `|` tokens in type declarations to `T_TYPE_UNION`. As the `PHP::processAdditional()` method walks backwards through the token stack, the arrow function backfill will not have been done yet, so for those some special conditions have been put in place. I've tried to limit the token walking within the new block as much as possible while still maintaining accuracy. This includes changing all union type operators in a single type declaration in one go, instead of on each individual `T_BITWISE_OR` token, which prevents the same logic having to be executed multiple times for multi-union types like `int|float|null`. Includes dedicated unit tests. Ref: https://wiki.php.net/rfc/union_types_v2
- Loading branch information
Showing
4 changed files
with
384 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
<?php | ||
|
||
/* | ||
* Type union or bitwise or. | ||
*/ | ||
|
||
/* testBitwiseOr1 */ | ||
$result = $value | $test /* testBitwiseOr2 */ | $another; | ||
|
||
class TypeUnion | ||
{ | ||
/* testTypeUnionPropertySimple */ | ||
public static Foo|Bar $obj; | ||
|
||
/* testTypeUnionPropertyReverseModifierOrder */ | ||
static protected int|float $number /* testBitwiseOrPropertyDefaultValue */ = E_WARNING | E_NOTICE; | ||
|
||
private | ||
/* testTypeUnionPropertyMulti1 */ | ||
array | | ||
/* testTypeUnionPropertyMulti2 */ | ||
Traversable | // phpcs:ignore Stnd.Cat.Sniff | ||
false | ||
/* testTypeUnionPropertyMulti3 */ | ||
| null $arrayOrFalse; | ||
|
||
public function paramTypes( | ||
/* testTypeUnionParam1 */ | ||
int|float $paramA /* testBitwiseOrParamDefaultValue */ = CONSTANT_A | CONSTANT_B, | ||
|
||
/* testTypeUnionParam2 */ | ||
Foo|\Bar /* testTypeUnionParam3 */ |Baz &...$paramB = null, | ||
) { | ||
/* testBitwiseOr3 */ | ||
return (($a1 ^ $b1) |($a2 ^ $b2)) + $c; | ||
} | ||
|
||
/* testTypeUnionReturnType */ | ||
public function returnType() : int|false {} | ||
|
||
/* testTypeUnionConstructorPropertyPromotion */ | ||
public function __construct( public bool|null $property) {} | ||
|
||
/* testTypeUnionAbstractMethodReturnType1 */ | ||
abstract public function abstractMethod(): object|array /* testTypeUnionAbstractMethodReturnType2 */ |false; | ||
} | ||
|
||
/* testTypeUnionClosureParamIllegalNullable */ | ||
$closureWithParamType = function (?string|null $string) {}; | ||
|
||
/* testBitwiseOrClosureParamDefault */ | ||
$closureWithReturnType = function ($string = NONSENSE | FAKE)/* testTypeUnionClosureReturn */ : \Package\MyA|PackageB {}; | ||
|
||
/* testTypeUnionArrowParam */ | ||
$arrowWithParamType = fn (object|array $param, /* testBitwiseOrArrowParamDefault */ ?int $int = CONSTA | CONSTB ) | ||
/* testBitwiseOrArrowExpression */ | ||
=> $param | $int; | ||
|
||
/* testTypeUnionArrowReturnType */ | ||
$arrowWithReturnType = fn ($param) : int|null => $param * 10; | ||
|
||
/* testBitwiseOrInArrayKey */ | ||
$array = array( | ||
A | B => /* testBitwiseOrInArrayValue */ B | C | ||
); | ||
|
||
/* testBitwiseOrInShortArrayKey */ | ||
$array = [ | ||
A | B => /* testBitwiseOrInShortArrayValue */ B | C | ||
]; | ||
|
||
/* testBitwiseOrTryCatch */ | ||
try { | ||
} catch ( ExceptionA | ExceptionB $e ) { | ||
} | ||
|
||
/* testBitwiseOrNonArrowFnFunctionCall */ | ||
$obj->fn($something | $else); | ||
|
||
/* testTypeUnionNonArrowFunctionDeclaration */ | ||
function &fn(int|false $something) {} | ||
|
||
/* testLiveCoding */ | ||
// Intentional parse error. This has to be the last test in the file. | ||
return function( type| |
Oops, something went wrong.