Skip to content

Commit

Permalink
Added component components (#6)
Browse files Browse the repository at this point in the history
Closes #2
  • Loading branch information
ariddlestone authored Feb 20, 2023
1 parent 774739e commit c3ad834
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 0 deletions.
3 changes: 3 additions & 0 deletions extension.neon
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
64 changes: 64 additions & 0 deletions src/ComponentComponentsExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

declare(strict_types=1);

namespace ARiddlestone\PHPStanCakePHP2;

use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\PropertiesClassReflectionExtension;
use PHPStan\Reflection\PropertyReflection;
use PHPStan\Reflection\ReflectionProvider;

final class ComponentComponentsExtension implements
PropertiesClassReflectionExtension
{
/**
* @var ReflectionProvider
*/
private $reflectionProvider;

public function __construct(ReflectionProvider $reflectionProvider)
{
$this->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';
}
}
33 changes: 33 additions & 0 deletions tests/ComponentExtensionsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace ARiddlestone\PHPStanCakePHP2\Test;

use PHPStan\Testing\TypeInferenceTestCase;

class ComponentExtensionsTest extends TypeInferenceTestCase
{
/**
* @return mixed[]
*/
public function dataFileAsserts(): iterable
{
yield from $this->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',
];
}
}
3 changes: 3 additions & 0 deletions tests/classes/Controller/Component/SecondComponent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<?php

class SecondComponent extends Component {}
10 changes: 10 additions & 0 deletions tests/data/existing_component_component.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types = 1);

use function PHPStan\Testing\assertType;

/** @var BasicComponent $parentComponent */
$childComponent = $parentComponent->Second;

assertType('SecondComponent', $childComponent);
10 changes: 10 additions & 0 deletions tests/data/invalid_component_property.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types = 1);

use function PHPStan\Testing\assertType;

/** @var BasicComponent $component */
$property = $component->stdClass;

assertType('*ERROR*', $property);

0 comments on commit c3ad834

Please sign in to comment.