diff --git a/packages/FamilyTree/Reflection/FamilyRelationsAnalyzer.php b/packages/FamilyTree/Reflection/FamilyRelationsAnalyzer.php index be21ad06769..0aeff963b65 100644 --- a/packages/FamilyTree/Reflection/FamilyRelationsAnalyzer.php +++ b/packages/FamilyTree/Reflection/FamilyRelationsAnalyzer.php @@ -89,14 +89,29 @@ public function getPossibleUnionPropertyType( $kindPropertyFetch = $this->getKindPropertyFetch($property); $className = $property->getAttribute(AttributeKey::CLASS_NAME); +<<<<<<< HEAD foreach ($ancestorClassReflections as $ancestorClassReflection) { $ancestorClassName = $ancestorClassReflection->getName(); if ($ancestorClassName === $className) { +======= + foreach ($ancestors as $ancestorClassReflection) { + $ancestorName = $ancestorClassReflection->getName(); + if ($ancestorName === $className) { +>>>>>>> getFileName() now returns null continue; } +<<<<<<< HEAD if ($ancestorClassReflection->isSubclassOf('PHPUnit\Framework\TestCase')) { +======= + $fileName = $ancestorClassReflection->getFileName(); +<<<<<<< HEAD + if ($fileName === false) { +======= + if ($fileName === null) { +>>>>>>> getFileName() now returns null +>>>>>>> PHPStan\Reflection\ClassReflection::getFileName() now returns null|string continue; } diff --git a/packages/NodeTypeResolver/PHPStan/Type/TypeFactory.php b/packages/NodeTypeResolver/PHPStan/Type/TypeFactory.php index 701591704dd..4b697ae330c 100644 --- a/packages/NodeTypeResolver/PHPStan/Type/TypeFactory.php +++ b/packages/NodeTypeResolver/PHPStan/Type/TypeFactory.php @@ -178,9 +178,32 @@ private function unwrapConstantArrayTypes(ConstantArrayType $constantArrayType): private function normalizeObjectTypes(Type $type): Type { +<<<<<<< HEAD return TypeTraverser::map($type, function (Type $currentType, callable $traverseCallback): Type { if ($currentType instanceof ShortenedObjectType) { return new FullyQualifiedObjectType($currentType->getFullyQualifiedName()); +======= + return TypeTraverser::map($type, function (Type $traversedType, callable $traverseCallback): Type { + if ($this->isStatic($traversedType) && $this->phpVersionProvider->isAtLeastPhpVersion( + PhpVersionFeature::STATIC_RETURN_TYPE + )) { + /** @var ObjectType $traversedType */ +<<<<<<< HEAD + $className = $traversedType->getClassName(); + if (! $this->reflectionProvider->hasClass($className)) { + throw new ShouldNotHappenException(); + } + + $classReflection = $this->reflectionProvider->getClass($className); + return new ThisType($classReflection); +======= +<<<<<<< HEAD + return new ThisType($traversedType->getClassName()); +======= + return $this->normalizeStaticType($traversedType); +>>>>>>> bd713da77... getFileName() now returns null +>>>>>>> PHPStan\Reflection\ClassReflection::getFileName() now returns null|string +>>>>>>> PHPStan\Reflection\ClassReflection::getFileName() now returns null|string } if ($currentType instanceof ObjectType && ! $currentType instanceof GenericObjectType && ! $currentType instanceof AliasedObjectType && $currentType->getClassName() !== 'Iterator') { @@ -190,4 +213,36 @@ private function normalizeObjectTypes(Type $type): Type return $traverseCallback($currentType); }); } +<<<<<<< HEAD +======= + + private function isStatic(Type $type): bool + { + if (! $type instanceof ObjectType) { + return false; + } + + return $type->getClassName() === ObjectReference::STATIC()->getValue(); + } + + private function isSelf(Type $type): bool + { + if (! $type instanceof ObjectType) { + return false; + } + + return $type->getClassName() === ObjectReference::SELF()->getValue(); + } + + private function normalizeStaticType(ObjectType $traversedType): ThisType + { + /** @var ObjectType $traversedType */ + $classReflection = $traversedType->getClassReflection(); + if (! $classReflection instanceof ClassReflection) { + throw new ShouldNotHappenException(); + } + + return new ThisType($classReflection); + } +>>>>>>> PHPStan\Reflection\ClassReflection::getFileName() now returns null|string } diff --git a/packages/VendorLocker/NodeVendorLocker/ClassMethodParamVendorLockResolver.php b/packages/VendorLocker/NodeVendorLocker/ClassMethodParamVendorLockResolver.php index e43f98e8932..79dfef80c87 100644 --- a/packages/VendorLocker/NodeVendorLocker/ClassMethodParamVendorLockResolver.php +++ b/packages/VendorLocker/NodeVendorLocker/ClassMethodParamVendorLockResolver.php @@ -129,7 +129,7 @@ private function hasClassMethodLockMatchingFileName( // is file in vendor? $fileName = $ancestorClassReflection->getFileName(); // probably internal class - if ($fileName === false) { + if ($fileName === null) { continue; } diff --git a/packages/VendorLocker/ParentClassMethodTypeOverrideGuard.php b/packages/VendorLocker/ParentClassMethodTypeOverrideGuard.php index 4f85ef9788b..7e365c17b6e 100644 --- a/packages/VendorLocker/ParentClassMethodTypeOverrideGuard.php +++ b/packages/VendorLocker/ParentClassMethodTypeOverrideGuard.php @@ -39,7 +39,7 @@ public function isReturnTypeChangeAllowed(ClassMethod $classMethod): bool $fileName = $classReflection->getFileName(); // probably internal - if ($fileName === false) { + if ($fileName === null) { return false; } diff --git a/phpstan.neon b/phpstan.neon index c18241c1916..8e9d63f09ea 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -508,6 +508,15 @@ parameters: message: '#Instead of "instanceof/is_a\(\)" use ReflectionProvider service or "\(new ObjectType\(\)\)\-\>isSuperTypeOf\(\)" for static reflection to work#' path: packages/StaticTypeMapper/ValueObject/Type/AliasedObjectType.php +<<<<<<< HEAD # resolve later - '#Cognitive complexity for "Rector\\Core\\NodeManipulator\\ClassMethodAssignManipulator\:\:collectReferenceVariableNames\(\)" is 13, keep it under 9#' +<<<<<<< HEAD - '#Cognitive complexity for "Rector\\NodeTypeResolver\\PHPStan\\Type\\TypeFactory\:\:normalizeObjectTypes\(\)" is 12, keep it under 9#' +======= +======= + # many internal cases + - '#Calling (.*?) is not covered by backward compatibility promise\. The method might change in a minor PHPStan version#' + - '#Creating (.*?) is not covered by backward compatibility promise\. The class might change in a minor PHPStan version#' +>>>>>>> complete binary object class +>>>>>>> complete binary object class diff --git a/rules/CodingStyle/Reflection/VendorLocationDetector.php b/rules/CodingStyle/Reflection/VendorLocationDetector.php index 74d28ff2f49..0ec14efc374 100644 --- a/rules/CodingStyle/Reflection/VendorLocationDetector.php +++ b/rules/CodingStyle/Reflection/VendorLocationDetector.php @@ -23,7 +23,7 @@ public function detectFunctionLikeReflection( $fileName = $this->resolveReflectionFileName($reflection); // probably internal - if ($fileName === false) { + if ($fileName === null) { return false; } @@ -33,7 +33,7 @@ public function detectFunctionLikeReflection( private function resolveReflectionFileName( MethodReflection | ReflectionWithFilename | FunctionReflection $reflection - ): string | false { + ): string | null { if ($reflection instanceof ReflectionWithFilename) { return $reflection->getFileName(); } @@ -47,6 +47,6 @@ private function resolveReflectionFileName( return $declaringClassReflection->getFileName(); } - return false; + return null; } } diff --git a/rules/DowngradePhp74/Rector/Array_/DowngradeArraySpreadRector.php b/rules/DowngradePhp74/Rector/Array_/DowngradeArraySpreadRector.php index 2356e18725c..c318149ce90 100644 --- a/rules/DowngradePhp74/Rector/Array_/DowngradeArraySpreadRector.php +++ b/rules/DowngradePhp74/Rector/Array_/DowngradeArraySpreadRector.php @@ -189,23 +189,42 @@ private function createArrayItems(Array_ $array): array */ private function createArrayMerge(Array_ $array, array $items): FuncCall { +<<<<<<< HEAD /** @var Scope $scope */ $scope = $array->getAttribute(AttributeKey::SCOPE); $args = array_map(function (ArrayItem|null $arrayItem) use ($scope): Arg { if ($arrayItem === null) { +======= + /** @var Scope $nodeScope */ + $nodeScope = $array->getAttribute(AttributeKey::SCOPE); + + $args = array_map(function (ArrayItem|null $arrayItem) use ($nodeScope): Arg { + if (! $arrayItem instanceof ArrayItem) { +>>>>>>> fix array traverse throw new ShouldNotHappenException(); } if ($arrayItem->unpack) { // Do not unpack anymore $arrayItem->unpack = false; +<<<<<<< HEAD return $this->createArgFromSpreadArrayItem($scope, $arrayItem); +======= + return $this->createArgFromSpreadArrayItem($nodeScope, $arrayItem); +>>>>>>> fix array traverse } return new Arg($arrayItem); }, $items); +<<<<<<< HEAD + +======= +<<<<<<< HEAD +======= +>>>>>>> fix array traverse +>>>>>>> getFileName() now returns null return new FuncCall(new Name('array_merge'), $args); } diff --git a/src/NodeManipulator/BinaryOpManipulator.php b/src/NodeManipulator/BinaryOpManipulator.php index 0c29d137022..e3fcfd731ce 100644 --- a/src/NodeManipulator/BinaryOpManipulator.php +++ b/src/NodeManipulator/BinaryOpManipulator.php @@ -140,7 +140,11 @@ private function normalizeCondition($condition): callable } /** +<<<<<<< HEAD * @return class-string|null +======= + * @return class-string +>>>>>>> complete binary object class */ private function resolveInversedNodeClass(BinaryOp $binaryOp): ?string { diff --git a/src/PhpParser/AstResolver.php b/src/PhpParser/AstResolver.php index 6bb153461e4..c8fdbce3c2e 100644 --- a/src/PhpParser/AstResolver.php +++ b/src/PhpParser/AstResolver.php @@ -99,7 +99,7 @@ public function resolveClassMethodFromMethodReflection(MethodReflection $methodR $fileName = $classReflection->getFileName(); // probably native PHP method → un-parseable - if ($fileName === false) { + if ($fileName === null) { return null; } @@ -146,7 +146,7 @@ public function resolveFunctionFromFunctionReflection(PhpFunctionReflection $php } $fileName = $phpFunctionReflection->getFileName(); - if ($fileName === false) { + if ($fileName === null) { return null; } @@ -229,7 +229,49 @@ public function resolveClassFromClassReflection( ClassReflection $classReflection, string $className ): Trait_ | Class_ | Interface_ | null { +<<<<<<< HEAD return $this->classLikeAstResolver->resolveClassFromClassReflection($classReflection, $className); +======= + if ($classReflection->isBuiltin()) { + return null; + } + + if (isset($this->classLikesByName[$classReflection->getName()])) { + return $this->classLikesByName[$classReflection->getName()]; + } + + $fileName = $classReflection->getFileName(); + + // probably internal class + if ($fileName === null) { + // avoid parsing falsy-file again + $this->classLikesByName[$classReflection->getName()] = null; + return null; + } + + $stmts = $this->smartPhpParser->parseFile($fileName); + if ($stmts === []) { + // avoid parsing falsy-file again + $this->classLikesByName[$classReflection->getName()] = null; + return null; + } + + /** @var array $classLikes */ + $classLikes = $this->betterNodeFinder->findInstanceOf($stmts, ClassLike::class); + + $reflectionClassName = $classReflection->getName(); + foreach ($classLikes as $classLike) { + if ($reflectionClassName !== $className) { + continue; + } + + $this->classLikesByName[$classReflection->getName()] = $classLike; + return $classLike; + } + + $this->classLikesByName[$classReflection->getName()] = null; + return null; +>>>>>>> PHPStan\Reflection\ClassReflection::getFileName() now returns null|string } /** diff --git a/src/PhpParser/Node/AssignAndBinaryMap.php b/src/PhpParser/Node/AssignAndBinaryMap.php index 76631cd762c..d4ae7dde2c1 100644 --- a/src/PhpParser/Node/AssignAndBinaryMap.php +++ b/src/PhpParser/Node/AssignAndBinaryMap.php @@ -109,7 +109,11 @@ public function getAlternative(Node $node): ?string } /** +<<<<<<< HEAD * @return class-string|null +======= + * @return class-string +>>>>>>> complete binary object class */ public function getInversed(BinaryOp $binaryOp): ?string {