diff --git a/Rules/NameNodeHolderFindRule.php b/Rules/NameNodeHolderFindRule.php new file mode 100644 index 0000000..cda6156 --- /dev/null +++ b/Rules/NameNodeHolderFindRule.php @@ -0,0 +1,45 @@ +getOriginalNode(); + $properties = $classLike->getProperties(); + $classReflection = $scope->getClassReflection(); + foreach ($properties as $property) { + foreach($property->props as $prop) { + $propertyName = $prop->name->toString(); + $propertyReflection = $classReflection->getNativeProperty($propertyName); + $propertyType = $propertyReflection->getReadableType(); + $trinary = $propertyType->isSuperTypeOf(new ObjectType('PhpParser\Node\Name')); + if (!$trinary->no()) { + return [ + RuleErrorBuilder::message( + $classLike->namespacedName->toString() + )->build(), + ]; + } + } + } + return []; + } +} diff --git a/Tests/NameNodeHolderFindRuleTest/NameNodeHolderFindRuleTest.php b/Tests/NameNodeHolderFindRuleTest/NameNodeHolderFindRuleTest.php new file mode 100644 index 0000000..8d6d473 --- /dev/null +++ b/Tests/NameNodeHolderFindRuleTest/NameNodeHolderFindRuleTest.php @@ -0,0 +1,34 @@ + + */ +class NameNodeHolderFindRuleTest extends RuleTestCase +{ + protected function getRule(): Rule + { + return new NameNodeHolderFindRule(); + } + + /** + * @dataProvider data + */ + public function testRule(string $file, array $expected): void + { + $this->analyse([$file], $expected); + } + + public function data(): array + { + return [ + [__DIR__ . '/data/name-holder.php', [['App\DummyFuncCall', 8]]], + [__DIR__ . '/data/non-name-holder.php', []], + ]; + } +} diff --git a/Tests/NameNodeHolderFindRuleTest/data/name-holder.php b/Tests/NameNodeHolderFindRuleTest/data/name-holder.php new file mode 100644 index 0000000..491def5 --- /dev/null +++ b/Tests/NameNodeHolderFindRuleTest/data/name-holder.php @@ -0,0 +1,40 @@ + Arguments */ + public $args; + + /** + * Constructs a function call node. + * + * @param Node\Name|Expr $name Function name + * @param array $args Arguments + * @param array $attributes Additional attributes + */ + public function __construct($name, array $args = [], array $attributes = []) { + $this->attributes = $attributes; + $this->name = $name; + $this->args = $args; + } + + public function getSubNodeNames() : array { + return ['name', 'args']; + } + + public function getType() : string { + return 'Expr_FuncCall'; + } + + public function getRawArgs(): array { + return $this->args; + } +} + diff --git a/Tests/NameNodeHolderFindRuleTest/data/non-name-holder.php b/Tests/NameNodeHolderFindRuleTest/data/non-name-holder.php new file mode 100644 index 0000000..aa9dba2 --- /dev/null +++ b/Tests/NameNodeHolderFindRuleTest/data/non-name-holder.php @@ -0,0 +1,34 @@ +attributes = $attributes; + $this->var = $var; + $this->dim = $dim; + } + + public function getSubNodeNames() : array { + return ['var', 'dim']; + } + + public function getType() : string { + return 'Expr_ArrayDimFetch'; + } +} diff --git a/phpstan.neon b/phpstan.neon index 174fda9..375c243 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,3 +1,4 @@ rules: - Rules\MyRule - Rules\CallStaticMethodInClassRule + - Rules\NameNodeHolderFindRule