From e6865059b45b954df46163bb860dcb6136dcd6b9 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Fri, 22 May 2020 12:06:59 +0200 Subject: [PATCH] Inherit PHPDocs from internal classes --- composer.json | 2 +- conf/config.neon | 2 ++ .../BetterReflectionProvider.php | 8 ++++-- src/Reflection/ClassReflection.php | 6 +++- .../PhpDefectClassReflectionExtension.php | 16 ----------- .../Runtime/RuntimeReflectionProvider.php | 6 +++- src/Testing/TestCase.php | 4 +++ stubs/iterable.stub | 2 +- tests/PHPStan/Broker/BrokerTest.php | 1 + .../PhpDefectClassReflectionExtensionTest.php | 28 ------------------- .../missing-method-parameter-typehint.php | 15 ++++++++++ 11 files changed, 40 insertions(+), 50 deletions(-) diff --git a/composer.json b/composer.json index 3da6659586..dc76b98bfc 100644 --- a/composer.json +++ b/composer.json @@ -20,7 +20,7 @@ "nette/utils": "^3.1.1", "nikic/php-parser": "^4.4.0", "ondram/ci-detector": "^3.1", - "ondrejmirtes/better-reflection": "^4.2.12", + "ondrejmirtes/better-reflection": "^4.2.13", "phpstan/phpdoc-parser": "^0.4.7", "react/child-process": "^0.6.1", "react/event-loop": "^1.1", diff --git a/conf/config.neon b/conf/config.neon index 8ee7d0a9a4..30a1ba4478 100644 --- a/conf/config.neon +++ b/conf/config.neon @@ -78,6 +78,8 @@ parameters: - '#^Hoa\\#' - '#^DateTime(?:Interface|Immutable)?$#' - '#^Soap(?:Client|Var|Server|Fault|Param|Header)$#' + - '#^Serializable$#' + - '#^XMLReader#' dynamicConstantNames: - ICONV_IMPL - LIBXML_VERSION diff --git a/src/Reflection/BetterReflection/BetterReflectionProvider.php b/src/Reflection/BetterReflection/BetterReflectionProvider.php index 3533a52609..7ff83f0b59 100644 --- a/src/Reflection/BetterReflection/BetterReflectionProvider.php +++ b/src/Reflection/BetterReflection/BetterReflectionProvider.php @@ -36,6 +36,8 @@ class BetterReflectionProvider implements ReflectionProvider { + private ReflectionProvider\ReflectionProviderProvider $reflectionProviderProvider; + private \PHPStan\DependencyInjection\Reflection\ClassReflectionExtensionRegistryProvider $classReflectionExtensionRegistryProvider; private \Roave\BetterReflection\Reflector\ClassReflector $classReflector; @@ -72,6 +74,7 @@ class BetterReflectionProvider implements ReflectionProvider private static array $anonymousClasses = []; public function __construct( + ReflectionProvider\ReflectionProviderProvider $reflectionProviderProvider, ClassReflectionExtensionRegistryProvider $classReflectionExtensionRegistryProvider, ClassReflector $classReflector, FileTypeMapper $fileTypeMapper, @@ -87,6 +90,7 @@ public function __construct( ConstantReflector $constantReflector ) { + $this->reflectionProviderProvider = $reflectionProviderProvider; $this->classReflectionExtensionRegistryProvider = $classReflectionExtensionRegistryProvider; $this->classReflector = $classReflector; $this->fileTypeMapper = $fileTypeMapper; @@ -137,7 +141,7 @@ public function getClass(string $className): ClassReflection } $classReflection = new ClassReflection( - $this, + $this->reflectionProviderProvider->getReflectionProvider(), $this->fileTypeMapper, $this->classReflectionExtensionRegistryProvider->getRegistry()->getPropertiesClassReflectionExtensions(), $this->classReflectionExtensionRegistryProvider->getRegistry()->getMethodsClassReflectionExtensions(), @@ -203,7 +207,7 @@ public function getAnonymousClassReflection(\PhpParser\Node\Stmt\Class_ $classNo ); self::$anonymousClasses[$className] = new ClassReflection( - $this, + $this->reflectionProviderProvider->getReflectionProvider(), $this->fileTypeMapper, $this->classReflectionExtensionRegistryProvider->getRegistry()->getPropertiesClassReflectionExtensions(), $this->classReflectionExtensionRegistryProvider->getRegistry()->getMethodsClassReflectionExtensions(), diff --git a/src/Reflection/ClassReflection.php b/src/Reflection/ClassReflection.php index 4d572224bb..4653328ad3 100644 --- a/src/Reflection/ClassReflection.php +++ b/src/Reflection/ClassReflection.php @@ -481,7 +481,11 @@ public function isSubclassOf(string $className): bool return $this->subclasses[$className] = false; } - return $this->subclasses[$className] = $this->reflection->isSubclassOf($className); + try { + return $this->subclasses[$className] = $this->reflection->isSubclassOf($className); + } catch (\ReflectionException $e) { + return $this->subclasses[$className] = false; + } } /** diff --git a/src/Reflection/PhpDefect/PhpDefectClassReflectionExtension.php b/src/Reflection/PhpDefect/PhpDefectClassReflectionExtension.php index 3f3a457781..c6d633cade 100644 --- a/src/Reflection/PhpDefect/PhpDefectClassReflectionExtension.php +++ b/src/Reflection/PhpDefect/PhpDefectClassReflectionExtension.php @@ -148,22 +148,6 @@ class PhpDefectClassReflectionExtension implements PropertiesClassReflectionExte 'exceptions_enabled' => 'int', 'info' => 'array', ], - 'XMLReader' => [ - 'attributeCount' => 'int', - 'baseURI' => 'string', - 'depth' => 'int', - 'hasAttributes' => 'bool', - 'hasValue' => 'bool', - 'isDefault' => 'bool', - 'isEmptyElement' => 'bool', - 'localName' => 'string', - 'name' => 'string', - 'namespaceURI' => 'string', - 'nodeType' => 'int', - 'prefix' => 'string', - 'value' => 'string', - 'xmlLang' => 'string', - ], 'ZipArchive' => [ 'status' => 'int', 'statusSys' => 'int', diff --git a/src/Reflection/Runtime/RuntimeReflectionProvider.php b/src/Reflection/Runtime/RuntimeReflectionProvider.php index 6d6f5ea74b..48aa02e5e4 100644 --- a/src/Reflection/Runtime/RuntimeReflectionProvider.php +++ b/src/Reflection/Runtime/RuntimeReflectionProvider.php @@ -26,6 +26,8 @@ class RuntimeReflectionProvider implements ReflectionProvider { + private ReflectionProvider\ReflectionProviderProvider $reflectionProviderProvider; + private ClassReflectionExtensionRegistryProvider $classReflectionExtensionRegistryProvider; /** @var \PHPStan\Reflection\ClassReflection[] */ @@ -62,6 +64,7 @@ class RuntimeReflectionProvider implements ReflectionProvider private static array $anonymousClasses = []; public function __construct( + ReflectionProvider\ReflectionProviderProvider $reflectionProviderProvider, ClassReflectionExtensionRegistryProvider $classReflectionExtensionRegistryProvider, FunctionReflectionFactory $functionReflectionFactory, FileTypeMapper $fileTypeMapper, @@ -74,6 +77,7 @@ public function __construct( StubPhpDocProvider $stubPhpDocProvider ) { + $this->reflectionProviderProvider = $reflectionProviderProvider; $this->classReflectionExtensionRegistryProvider = $classReflectionExtensionRegistryProvider; $this->functionReflectionFactory = $functionReflectionFactory; $this->fileTypeMapper = $fileTypeMapper; @@ -194,7 +198,7 @@ private function getClassFromReflection(\ReflectionClass $reflectionClass, strin $className = $reflectionClass->getName(); if (!isset($this->classReflections[$className])) { $classReflection = new ClassReflection( - $this, + $this->reflectionProviderProvider->getReflectionProvider(), $this->fileTypeMapper, $this->classReflectionExtensionRegistryProvider->getRegistry()->getPropertiesClassReflectionExtensions(), $this->classReflectionExtensionRegistryProvider->getRegistry()->getMethodsClassReflectionExtensions(), diff --git a/src/Testing/TestCase.php b/src/Testing/TestCase.php index f9c92d8ae9..e561dd6f4b 100644 --- a/src/Testing/TestCase.php +++ b/src/Testing/TestCase.php @@ -206,6 +206,7 @@ private function createRuntimeReflectionProvider(ReflectionProvider $actualRefle ); $reflectionProvider = new ClassBlacklistReflectionProvider( new RuntimeReflectionProvider( + $setterReflectionProviderProvider, $classReflectionExtensionRegistryProvider, $functionReflectionFactory, $fileTypeMapper, @@ -223,6 +224,8 @@ private function createRuntimeReflectionProvider(ReflectionProvider $actualRefle '#^Hoa\\\\#', '#^DateTime(?:Interface|Immutable)?$#', '#^Soap(?:Client|Var|Server|Fault|Param|Header)$#', + '#^Serializable$#', + '#^XMLReader#', ] ); $this->setUpReflectionProvider( @@ -362,6 +365,7 @@ private function createStaticReflectionProvider(): ReflectionProvider $classReflectionExtensionRegistryProvider = $this->getClassReflectionExtensionRegistryProvider(); $reflectionProvider = new BetterReflectionProvider( + $setterReflectionProviderProvider, $classReflectionExtensionRegistryProvider, $classReflector, $fileTypeMapper, diff --git a/stubs/iterable.stub b/stubs/iterable.stub index a65e43e263..0bd23a19f5 100644 --- a/stubs/iterable.stub +++ b/stubs/iterable.stub @@ -94,7 +94,7 @@ interface SeekableIterator extends Iterator * @implements SeekableIterator * @implements ArrayAccess */ -class ArrayIterator implements SeekableIterator, ArrayAccess, Countable, Serializable +class ArrayIterator implements SeekableIterator, ArrayAccess, Countable { /** diff --git a/tests/PHPStan/Broker/BrokerTest.php b/tests/PHPStan/Broker/BrokerTest.php index c889ea5960..3f79b54cc9 100644 --- a/tests/PHPStan/Broker/BrokerTest.php +++ b/tests/PHPStan/Broker/BrokerTest.php @@ -42,6 +42,7 @@ protected function setUp(): void $setterReflectionProviderProvider = new SetterReflectionProviderProvider(); $reflectionProvider = new RuntimeReflectionProvider( + $setterReflectionProviderProvider, $classReflectionExtensionRegistryProvider, $this->createMock(FunctionReflectionFactory::class), new FileTypeMapper($setterReflectionProviderProvider, $this->getParser(), $phpDocStringResolver, $phpDocNodeResolver, $this->createMock(Cache::class), $anonymousClassNameHelper), diff --git a/tests/PHPStan/Reflection/PhpDefect/PhpDefectClassReflectionExtensionTest.php b/tests/PHPStan/Reflection/PhpDefect/PhpDefectClassReflectionExtensionTest.php index 56e3c547a2..5b964d42a4 100644 --- a/tests/PHPStan/Reflection/PhpDefect/PhpDefectClassReflectionExtensionTest.php +++ b/tests/PHPStan/Reflection/PhpDefect/PhpDefectClassReflectionExtensionTest.php @@ -5,7 +5,6 @@ use PHPStan\Analyser\Scope; use PHPStan\Broker\Broker; use PHPStan\Type\VerbosityLevel; -use XMLReader; use ZipArchive; class PhpDefectClassReflectionExtensionTest extends \PHPStan\Testing\TestCase @@ -27,7 +26,6 @@ class PhpDefectClassReflectionExtensionTest extends \PHPStan\Testing\TestCase * @dataProvider dataDomTextProperties * @dataProvider dataDomProcessingInstructionProperties * @dataProvider dataDomXPathProperties - * @dataProvider dataXmlReaderProperties * @dataProvider dataZipArchiveProperties * @dataProvider dataLibXMLErrorProperties * @param string $className @@ -550,32 +548,6 @@ public function dataDomXPathProperties(): array ]; } - public function dataXmlReaderProperties(): array - { - return [ - [ - XMLReader::class, - XMLReader::class, - [ - 'attributeCount' => 'int', - 'baseURI' => 'string', - 'depth' => 'int', - 'hasAttributes' => 'bool', - 'hasValue' => 'bool', - 'isDefault' => 'bool', - 'isEmptyElement' => 'bool', - 'localName' => 'string', - 'name' => 'string', - 'namespaceURI' => 'string', - 'nodeType' => 'int', - 'prefix' => 'string', - 'value' => 'string', - 'xmlLang' => 'string', - ], - ], - ]; - } - public function dataZipArchiveProperties(): array { if (!class_exists('ZipArchive')) { diff --git a/tests/PHPStan/Rules/Methods/data/missing-method-parameter-typehint.php b/tests/PHPStan/Rules/Methods/data/missing-method-parameter-typehint.php index decbf3f65f..9b41afd605 100644 --- a/tests/PHPStan/Rules/Methods/data/missing-method-parameter-typehint.php +++ b/tests/PHPStan/Rules/Methods/data/missing-method-parameter-typehint.php @@ -158,3 +158,18 @@ public function doFoo($obj) } } + +class SerializableImpl implements \Serializable +{ + + public function serialize(): string + { + return serialize([]); + } + + public function unserialize($serialized): void + { + + } + +}