diff --git a/extension.neon b/extension.neon index 549f137..cc9b02a 100644 --- a/extension.neon +++ b/extension.neon @@ -8,6 +8,9 @@ parameters: stubFiles: - stubs/Utility.php services: + - class: ARiddlestone\PHPStanCakePHP2\ComponentComponentsExtension + tags: + - phpstan.broker.propertiesClassReflectionExtension - class: ARiddlestone\PHPStanCakePHP2\ControllerComponentsExtension tags: - phpstan.broker.propertiesClassReflectionExtension diff --git a/src/ComponentComponentsExtension.php b/src/ComponentComponentsExtension.php new file mode 100644 index 0000000..cf20e25 --- /dev/null +++ b/src/ComponentComponentsExtension.php @@ -0,0 +1,64 @@ +reflectionProvider = $reflectionProvider; + } + + public function hasProperty( + ClassReflection $classReflection, + string $propertyName + ): bool { + if (! $classReflection->is('Component')) { + return false; + } + + $className = $this->getClassName($propertyName); + + if (! $this->reflectionProvider->hasClass($className)) { + return false; + } + + if ( + ! $this->reflectionProvider + ->getClass($className) + ->is('Component') + ) { + return false; + } + + return true; + } + + public function getProperty( + ClassReflection $classReflection, + string $propertyName + ): PropertyReflection { + return new PublicReadOnlyPropertyReflection( + $this->getClassName($propertyName), + $classReflection + ); + } + + private function getClassName(string $propertyName): string + { + return $propertyName . 'Component'; + } +} diff --git a/tests/ComponentExtensionsTest.php b/tests/ComponentExtensionsTest.php new file mode 100644 index 0000000..6218f5e --- /dev/null +++ b/tests/ComponentExtensionsTest.php @@ -0,0 +1,33 @@ +gatherAssertTypes(__DIR__ . '/data/existing_component_component.php'); + yield from $this->gatherAssertTypes(__DIR__ . '/data/invalid_component_property.php'); + } + + /** + * @dataProvider dataFileAsserts + * @param mixed $args + */ + public function testControllerExtensions(string $assertType, string $file, ...$args): void + { + $this->assertFileAsserts($assertType, $file, ...$args); + } + + public static function getAdditionalConfigFiles(): array + { + return [ + __DIR__ . '/data/phpstan.neon', + ]; + } +} diff --git a/tests/classes/Controller/Component/SecondComponent.php b/tests/classes/Controller/Component/SecondComponent.php new file mode 100644 index 0000000..76e6f4c --- /dev/null +++ b/tests/classes/Controller/Component/SecondComponent.php @@ -0,0 +1,3 @@ +Second; + +assertType('SecondComponent', $childComponent); diff --git a/tests/data/invalid_component_property.php b/tests/data/invalid_component_property.php new file mode 100644 index 0000000..d992d0a --- /dev/null +++ b/tests/data/invalid_component_property.php @@ -0,0 +1,10 @@ +stdClass; + +assertType('*ERROR*', $property);