From fe0551e374df78c4bbcd4c4e0523a4b50a3bb9c8 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Wed, 27 Jul 2022 14:58:13 +0700 Subject: [PATCH] [TypeDeclaration] Handle crash on intersection in Union type on AddMethodCallBasedStrictParamTypeRector (#2704) * [TypeDeclaration] Skip intersection in Union type on AddMethodCallBasedStrictParamTypeRector * Fixed :tada: * [ci-review] Rector Rectify * cs fix * fix * [ci-review] Rector Rectify * reduce complexity * final touch: eol * final touch: comment rollback Co-authored-by: GitHub Action --- .../TypeMapper/UnionTypeMapper.php | 9 +++++- .../skip_intersection_in_union.php.inc | 30 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 rules-tests/TypeDeclaration/Rector/ClassMethod/AddMethodCallBasedStrictParamTypeRector/FixtureIntersection/skip_intersection_in_union.php.inc diff --git a/packages/PHPStanStaticTypeMapper/TypeMapper/UnionTypeMapper.php b/packages/PHPStanStaticTypeMapper/TypeMapper/UnionTypeMapper.php index 99452a73112..758f2ebb78a 100644 --- a/packages/PHPStanStaticTypeMapper/TypeMapper/UnionTypeMapper.php +++ b/packages/PHPStanStaticTypeMapper/TypeMapper/UnionTypeMapper.php @@ -7,6 +7,7 @@ use PhpParser\Node; use PhpParser\Node\ComplexType; use PhpParser\Node\Identifier; +use PhpParser\Node\IntersectionType as PHPParserNodeIntersectionType; use PhpParser\Node\Name; use PhpParser\Node\Name\FullyQualified; use PhpParser\Node\NullableType; @@ -16,6 +17,7 @@ use PHPStan\Type\ClassStringType; use PHPStan\Type\Constant\ConstantBooleanType; use PHPStan\Type\Generic\GenericClassStringType; +use PHPStan\Type\IntersectionType; use PHPStan\Type\IterableType; use PHPStan\Type\MixedType; use PHPStan\Type\NullType; @@ -286,7 +288,7 @@ private function matchPhpParserUnionType(UnionType $unionType, string $typeKind) * NullType inside UnionType is allowed * make it on TypeKind property as changing other type, eg: return type may conflict with parent child implementation * - * @var Identifier|Name|null $phpParserNode + * @var Identifier|Name|null|PHPParserNodeIntersectionType $phpParserNode */ $phpParserNode = $unionedType instanceof NullType && $typeKind === TypeKind::PROPERTY ? new Name('null') @@ -296,9 +298,14 @@ private function matchPhpParserUnionType(UnionType $unionType, string $typeKind) return null; } + if ($phpParserNode instanceof PHPParserNodeIntersectionType && $unionedType instanceof IntersectionType) { + return null; + } + $phpParserUnionedTypes[] = $phpParserNode; } + /** @var Identifier[]|Name[] $phpParserUnionedTypes */ $phpParserUnionedTypes = array_unique($phpParserUnionedTypes); if (count($phpParserUnionedTypes) < 2) { diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddMethodCallBasedStrictParamTypeRector/FixtureIntersection/skip_intersection_in_union.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddMethodCallBasedStrictParamTypeRector/FixtureIntersection/skip_intersection_in_union.php.inc new file mode 100644 index 00000000000..c629ba7a6f8 --- /dev/null +++ b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddMethodCallBasedStrictParamTypeRector/FixtureIntersection/skip_intersection_in_union.php.inc @@ -0,0 +1,30 @@ +getRequestParameters(), [ + 'request' => $this->getRequestName(), + ]); + + $this->removeEmptyValues($parameters); + + return []; + } + + private function removeEmptyValues($input): array + { + foreach ($input as &$value) { + if (! is_array($value)) { + continue; + } + + $value = $this->removeEmptyValues($value); + } + + return []; + } +}