Skip to content

Commit

Permalink
Merge pull request #365 from PHPCSStandards/php-8.1/add-support-for-i…
Browse files Browse the repository at this point in the history
…ntersection-types

PHP 8.1: add support for intersection types
  • Loading branch information
jrfnl authored Oct 15, 2022
2 parents 422e688 + a3c3e0e commit dd41a73
Show file tree
Hide file tree
Showing 12 changed files with 429 additions and 25 deletions.
59 changes: 34 additions & 25 deletions PHPCSUtils/Tokens/Collections.php
Original file line number Diff line number Diff line change
Expand Up @@ -471,20 +471,22 @@ class Collections
*
* @since 1.0.0-alpha1
* @since 1.0.0-alpha4 Added the T_TYPE_UNION, T_FALSE, T_NULL tokens for PHP 8.0 union type support.
* @since 1.0.0-alpha4 Added the T_TYPE_INTERSECTION token for PHP 8.1 intersection type support.
*
* @deprecated 1.0.0-alpha4 Use the {@see Collections::parameterTypeTokens()} method instead.
*
* @var array <int|string> => <int|string>
*/
public static $parameterTypeTokens = [
\T_CALLABLE => \T_CALLABLE,
\T_SELF => \T_SELF,
\T_PARENT => \T_PARENT,
\T_FALSE => \T_FALSE,
\T_NULL => \T_NULL,
\T_STRING => \T_STRING,
\T_NS_SEPARATOR => \T_NS_SEPARATOR,
\T_TYPE_UNION => \T_TYPE_UNION,
\T_CALLABLE => \T_CALLABLE,
\T_SELF => \T_SELF,
\T_PARENT => \T_PARENT,
\T_FALSE => \T_FALSE,
\T_NULL => \T_NULL,
\T_STRING => \T_STRING,
\T_NS_SEPARATOR => \T_NS_SEPARATOR,
\T_TYPE_UNION => \T_TYPE_UNION,
\T_TYPE_INTERSECTION => \T_TYPE_INTERSECTION,
];

/**
Expand Down Expand Up @@ -523,42 +525,46 @@ class Collections
*
* @since 1.0.0-alpha1
* @since 1.0.0-alpha4 Added the T_TYPE_UNION, T_FALSE, T_NULL tokens for PHP 8.0 union type support.
* @since 1.0.0-alpha4 Added the T_TYPE_INTERSECTION token for PHP 8.1 intersection type support.
*
* @deprecated 1.0.0-alpha4 Use the {@see Collections::propertyTypeTokens()} method instead.
*
* @var array <int|string> => <int|string>
*/
public static $propertyTypeTokens = [
\T_CALLABLE => \T_CALLABLE,
\T_SELF => \T_SELF,
\T_PARENT => \T_PARENT,
\T_FALSE => \T_FALSE,
\T_NULL => \T_NULL,
\T_STRING => \T_STRING,
\T_NS_SEPARATOR => \T_NS_SEPARATOR,
\T_TYPE_UNION => \T_TYPE_UNION,
\T_CALLABLE => \T_CALLABLE,
\T_SELF => \T_SELF,
\T_PARENT => \T_PARENT,
\T_FALSE => \T_FALSE,
\T_NULL => \T_NULL,
\T_STRING => \T_STRING,
\T_NS_SEPARATOR => \T_NS_SEPARATOR,
\T_TYPE_UNION => \T_TYPE_UNION,
\T_TYPE_INTERSECTION => \T_TYPE_INTERSECTION,
];

/**
* DEPRECATED: Token types which can be encountered in a return type declaration.
*
* @since 1.0.0-alpha1
* @since 1.0.0-alpha4 Added the T_TYPE_UNION, T_FALSE, T_NULL tokens for PHP 8.0 union type support.
* @since 1.0.0-alpha4 Added the T_TYPE_INTERSECTION token for PHP 8.1 intersection type support.
*
* @deprecated 1.0.0-alpha4 Use the {@see Collections::returnTypeTokens()} method instead.
*
* @var array <int|string> => <int|string>
*/
public static $returnTypeTokens = [
\T_CALLABLE => \T_CALLABLE,
\T_SELF => \T_SELF,
\T_PARENT => \T_PARENT,
\T_STATIC => \T_STATIC,
\T_FALSE => \T_FALSE,
\T_NULL => \T_NULL,
\T_STRING => \T_STRING,
\T_NS_SEPARATOR => \T_NS_SEPARATOR,
\T_TYPE_UNION => \T_TYPE_UNION,
\T_CALLABLE => \T_CALLABLE,
\T_SELF => \T_SELF,
\T_PARENT => \T_PARENT,
\T_STATIC => \T_STATIC,
\T_FALSE => \T_FALSE,
\T_NULL => \T_NULL,
\T_STRING => \T_STRING,
\T_NS_SEPARATOR => \T_NS_SEPARATOR,
\T_TYPE_UNION => \T_TYPE_UNION,
\T_TYPE_INTERSECTION => \T_TYPE_INTERSECTION,
];

/**
Expand Down Expand Up @@ -910,6 +916,7 @@ public static function parameterPassingTokens()
* @since 1.0.0-alpha4 This method replaces the {@see Collections::$parameterTypeTokens} property.
* @since 1.0.0-alpha4 Added the T_TYPE_UNION, T_FALSE, T_NULL tokens for PHP 8.0 union type support.
* @since 1.0.0-alpha4 Added support for PHP 8.0 identifier name tokens.
* @since 1.0.0-alpha4 Added the T_TYPE_INTERSECTION token for PHP 8.1 intersection type support.
*
* @return array <int|string> => <int|string>
*/
Expand Down Expand Up @@ -949,6 +956,7 @@ public static function parameterTypeTokensBC()
* @since 1.0.0-alpha4 This method replaces the {@see Collections::$propertyTypeTokens} property.
* @since 1.0.0-alpha4 Added the T_TYPE_UNION, T_FALSE, T_NULL tokens for PHP 8.0 union type support.
* @since 1.0.0-alpha4 Added support for PHP 8.0 identifier name tokens.
* @since 1.0.0-alpha4 Added the T_TYPE_INTERSECTION token for PHP 8.1 intersection type support.
*
* @return array <int|string> => <int|string>
*/
Expand Down Expand Up @@ -988,6 +996,7 @@ public static function propertyTypeTokensBC()
* @since 1.0.0-alpha4 This method replaces the {@see Collections::$returnTypeTokens} property.
* @since 1.0.0-alpha4 Added the T_TYPE_UNION, T_FALSE, T_NULL tokens for PHP 8.0 union type support.
* @since 1.0.0-alpha4 Added support for PHP 8.0 identifier name tokens.
* @since 1.0.0-alpha4 Added the T_TYPE_INTERSECTION token for PHP 8.1 intersection type support.
*
* @return array <int|string> => <int|string>
*/
Expand Down
2 changes: 2 additions & 0 deletions PHPCSUtils/Utils/FunctionDeclarations.php
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ public static function getName(File $phpcsFile, $stackPtr)
* @since 1.0.0-alpha2 Added support for PHP 7.4 arrow functions.
* @since 1.0.0-alpha3 Added support for PHP 8.0 static return type.
* @since 1.0.0-alpha4 Added support for PHP 8.0 union types.
* @since 1.0.0-alpha4 Added support for PHP 8.1 intersection types.
*
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
* @param int $stackPtr The position in the stack of the function token to
Expand Down Expand Up @@ -364,6 +365,7 @@ public static function getProperties(File $phpcsFile, $stackPtr)
* @since 1.0.0-alpha4 Added support for PHP 8.0 identifier name tokenization.
* @since 1.0.0-alpha4 Added support for PHP 8.0 parameter attributes.
* @since 1.0.0-alpha4 Added support for PHP 8.1 readonly keyword for constructor property promotion.
* @since 1.0.0-alpha4 Added support for PHP 8.1 intersection types.
*
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
* @param int $stackPtr The position in the stack of the function token
Expand Down
1 change: 1 addition & 0 deletions PHPCSUtils/Utils/Variables.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ class Variables
* @since 1.0.0-alpha4 Added support for PHP 8.0 union types.
* @since 1.0.0-alpha4 No longer gets confused by PHP 8.0 property attributes.
* @since 1.0.0-alpha4 Added support for PHP 8.1 readonly properties.
* @since 1.0.0-alpha4 Added support for PHP 8.1 intersection types.
*
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
* @param int $stackPtr The position in the stack of the `T_VARIABLE` token
Expand Down
16 changes: 16 additions & 0 deletions Tests/BackCompat/BCFile/GetMemberPropertiesTest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -299,3 +299,19 @@ enum Direction implements ArrayAccess
/* testEnumMethodParamNotProperty */
public function offsetGet($val) { ... }
}

$anon = class() {
/* testPHP81IntersectionTypes */
public Foo&Bar $intersectionType;

/* testPHP81MoreIntersectionTypes */
public Foo&Bar&Baz $moreIntersectionTypes;

/* testPHP81IllegalIntersectionTypes */
// Intentional fatal error - types which are not allowed for intersection type, but that's not the concern of the method.
public int&string $illegalIntersectionType;

/* testPHP81NullableIntersectionType */
// Intentional fatal error - nullability is not allowed with intersection type, but that's not the concern of the method.
public ?Foo&Bar $nullableIntersectionType;
};
52 changes: 52 additions & 0 deletions Tests/BackCompat/BCFile/GetMemberPropertiesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -965,6 +965,58 @@ public function dataGetMemberProperties()
'/* testEnumProperty */',
[],
],
'php8.1-single-intersection-type' => [
'/* testPHP81IntersectionTypes */',
[
'scope' => 'public',
'scope_specified' => true,
'is_static' => false,
'is_readonly' => false,
'type' => 'Foo&Bar',
'type_token' => -4, // Offset from the T_VARIABLE token.
'type_end_token' => -2, // Offset from the T_VARIABLE token.
'nullable_type' => false,
],
],
'php8.1-multi-intersection-type' => [
'/* testPHP81MoreIntersectionTypes */',
[
'scope' => 'public',
'scope_specified' => true,
'is_static' => false,
'is_readonly' => false,
'type' => 'Foo&Bar&Baz',
'type_token' => -6, // Offset from the T_VARIABLE token.
'type_end_token' => -2, // Offset from the T_VARIABLE token.
'nullable_type' => false,
],
],
'php8.1-illegal-intersection-type' => [
'/* testPHP81IllegalIntersectionTypes */',
[
'scope' => 'public',
'scope_specified' => true,
'is_static' => false,
'is_readonly' => false,
'type' => 'int&string',
'type_token' => -4, // Offset from the T_VARIABLE token.
'type_end_token' => -2, // Offset from the T_VARIABLE token.
'nullable_type' => false,
],
],
'php8.1-nullable-intersection-type' => [
'/* testPHP81NullableIntersectionType */',
[
'scope' => 'public',
'scope_specified' => true,
'is_static' => false,
'is_readonly' => false,
'type' => '?Foo&Bar',
'type_token' => -4, // Offset from the T_VARIABLE token.
'type_end_token' => -2, // Offset from the T_VARIABLE token.
'nullable_type' => true,
],
],
];
}

Expand Down
17 changes: 17 additions & 0 deletions Tests/BackCompat/BCFile/GetMethodParametersTest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,23 @@ class ParametersWithAttributes(
) {}
}

/* testPHP8IntersectionTypes */
function intersectionTypes(Foo&Bar $obj1, Boo&Bar $obj2) {}

/* testPHP81IntersectionTypesWithSpreadOperatorAndReference */
function globalFunctionWithSpreadAndReference(Boo&Bar &$paramA, Foo&Bar ...$paramB) {}

/* testPHP81MoreIntersectionTypes */
function moreIntersectionTypes(MyClassA&\Package\MyClassB&\Package\MyClassC $var) {}

/* testPHP81IllegalIntersectionTypes */
// Intentional fatal error - simple types are not allowed with intersection types, but that's not the concern of the method.
$closure = function (string&int $numeric_string) {};

/* testPHP81NullableIntersectionTypes */
// Intentional fatal error - nullability is not allowed with intersection types, but that's not the concern of the method.
$closure = function (?Foo&Bar $object) {};

/* testPHP81NewInInitializers */
function newInInitializers(
TypeA $new = new TypeA(self::CONST_VALUE),
Expand Down
Loading

0 comments on commit dd41a73

Please # to comment.