From 47130d7e4fdd22386bee7c444531aad5dc7bbe30 Mon Sep 17 00:00:00 2001 From: Jan Nedbal Date: Fri, 20 May 2022 09:33:50 +0200 Subject: [PATCH 1/4] NodeScopeResolver: call nodeCallback for all attribute-related nodes --- src/Analyser/NodeScopeResolver.php | 72 +++++++++++++----------------- 1 file changed, 30 insertions(+), 42 deletions(-) diff --git a/src/Analyser/NodeScopeResolver.php b/src/Analyser/NodeScopeResolver.php index 9018578135..b941085e3f 100644 --- a/src/Analyser/NodeScopeResolver.php +++ b/src/Analyser/NodeScopeResolver.php @@ -8,6 +8,7 @@ use PhpParser\Comment\Doc; use PhpParser\Node; use PhpParser\Node\Arg; +use PhpParser\Node\AttributeGroup; use PhpParser\Node\Expr; use PhpParser\Node\Expr\Array_; use PhpParser\Node\Expr\ArrayDimFetch; @@ -395,13 +396,7 @@ private function processStmtNode( } elseif ($stmt instanceof Node\Stmt\Function_) { $hasYield = false; $throwPoints = []; - foreach ($stmt->attrGroups as $attrGroup) { - foreach ($attrGroup->attrs as $attr) { - foreach ($attr->args as $arg) { - $this->processExprNode($arg->value, $scope, $nodeCallback, ExpressionContext::createDeep()); - } - } - } + $this->processAttributeGroups($stmt->attrGroups, $scope, $nodeCallback); [$templateTypeMap, $phpDocParameterTypes, $phpDocReturnType, $phpDocThrowType, $deprecatedDescription, $isDeprecated, $isInternal, $isFinal, $isPure] = $this->getPhpDocs($scope, $stmt); foreach ($stmt->params as $param) { @@ -456,13 +451,7 @@ private function processStmtNode( } elseif ($stmt instanceof Node\Stmt\ClassMethod) { $hasYield = false; $throwPoints = []; - foreach ($stmt->attrGroups as $attrGroup) { - foreach ($attrGroup->attrs as $attr) { - foreach ($attr->args as $arg) { - $this->processExprNode($arg->value, $scope, $nodeCallback, ExpressionContext::createDeep()); - } - } - } + $this->processAttributeGroups($stmt->attrGroups, $scope, $nodeCallback); [$templateTypeMap, $phpDocParameterTypes, $phpDocReturnType, $phpDocThrowType, $deprecatedDescription, $isDeprecated, $isInternal, $isFinal, $isPure] = $this->getPhpDocs($scope, $stmt); foreach ($stmt->params as $param) { @@ -633,13 +622,7 @@ private function processStmtNode( } $classStatementsGatherer = new ClassStatementsGatherer($classReflection, $nodeCallback); - foreach ($stmt->attrGroups as $attrGroup) { - foreach ($attrGroup->attrs as $attr) { - foreach ($attr->args as $arg) { - $this->processExprNode($arg->value, $classScope, $classStatementsGatherer, ExpressionContext::createDeep()); - } - } - } + $this->processAttributeGroups($stmt->attrGroups, $classScope, $classStatementsGatherer); $this->processStmtNodes($stmt, $stmt->stmts, $classScope, $classStatementsGatherer); $nodeCallback(new ClassPropertiesNode($stmt, $classStatementsGatherer->getProperties(), $classStatementsGatherer->getTraitProperties(), $classStatementsGatherer->getPropertyUsages(), $classStatementsGatherer->getMethodCalls()), $classScope); @@ -649,13 +632,8 @@ private function processStmtNode( } elseif ($stmt instanceof Node\Stmt\Property) { $hasYield = false; $throwPoints = []; - foreach ($stmt->attrGroups as $attrGroup) { - foreach ($attrGroup->attrs as $attr) { - foreach ($attr->args as $arg) { - $this->processExprNode($arg->value, $scope, $nodeCallback, ExpressionContext::createDeep()); - } - } - } + $this->processAttributeGroups($stmt->attrGroups, $scope, $nodeCallback); + foreach ($stmt->props as $prop) { $this->processStmtNode($prop, $scope, $nodeCallback); [,,,,,,,,,$isReadOnly, $docComment] = $this->getPhpDocs($scope, $stmt); @@ -1406,13 +1384,7 @@ private function processStmtNode( $hasYield = false; $throwPoints = []; if ($stmt instanceof Node\Stmt\ClassConst) { - foreach ($stmt->attrGroups as $attrGroup) { - foreach ($attrGroup->attrs as $attr) { - foreach ($attr->args as $arg) { - $this->processExprNode($arg->value, $scope, $nodeCallback, ExpressionContext::createDeep()); - } - } - } + $this->processAttributeGroups($stmt->attrGroups, $scope, $nodeCallback); } foreach ($stmt->consts as $const) { $nodeCallback($const, $scope); @@ -3108,13 +3080,7 @@ private function processParamNode( callable $nodeCallback, ): void { - foreach ($param->attrGroups as $attrGroup) { - foreach ($attrGroup->attrs as $attr) { - foreach ($attr->args as $arg) { - $this->processExprNode($arg->value, $scope, $nodeCallback, ExpressionContext::createDeep()); - } - } - } + $this->processAttributeGroups($param->attrGroups, $scope, $nodeCallback); $nodeCallback($param, $scope); if ($param->type !== null) { $nodeCallback($param->type, $scope); @@ -3126,6 +3092,28 @@ private function processParamNode( $this->processExprNode($param->default, $scope, $nodeCallback, ExpressionContext::createDeep()); } + /** + * @param AttributeGroup[] $attrGroups + * @param callable(Node $node, Scope $scope): void $nodeCallback + */ + private function processAttributeGroups( + array $attrGroups, + MutatingScope $scope, + callable $nodeCallback, + ): void + { + foreach ($attrGroups as $attrGroup) { + foreach ($attrGroup->attrs as $attr) { + foreach ($attr->args as $arg) { + $this->processExprNode($arg->value, $scope, $nodeCallback, ExpressionContext::createDeep()); + $nodeCallback($arg, $scope); + } + $nodeCallback($attr, $scope); + } + $nodeCallback($attrGroup, $scope); + } + } + /** * @param MethodReflection|FunctionReflection|null $calleeReflection * @param Node\Arg[] $args From dd04ea35290f682c733dd29a0403d0e81919f57c Mon Sep 17 00:00:00 2001 From: Jan Nedbal Date: Fri, 20 May 2022 12:30:37 +0200 Subject: [PATCH 2/4] add tests --- tests/PHPStan/Node/AttributeArgRuleTest.php | 59 +++++++++++++++++++ tests/PHPStan/Node/AttributeGroupRuleTest.php | 59 +++++++++++++++++++ tests/PHPStan/Node/AttributeRuleTest.php | 59 +++++++++++++++++++ tests/PHPStan/Node/data/attributes.php | 41 +++++++++++++ 4 files changed, 218 insertions(+) create mode 100644 tests/PHPStan/Node/AttributeArgRuleTest.php create mode 100644 tests/PHPStan/Node/AttributeGroupRuleTest.php create mode 100644 tests/PHPStan/Node/AttributeRuleTest.php create mode 100644 tests/PHPStan/Node/data/attributes.php diff --git a/tests/PHPStan/Node/AttributeArgRuleTest.php b/tests/PHPStan/Node/AttributeArgRuleTest.php new file mode 100644 index 0000000000..d1946f91c3 --- /dev/null +++ b/tests/PHPStan/Node/AttributeArgRuleTest.php @@ -0,0 +1,59 @@ +analyse([$file], $errors); + } + +} diff --git a/tests/PHPStan/Node/AttributeGroupRuleTest.php b/tests/PHPStan/Node/AttributeGroupRuleTest.php new file mode 100644 index 0000000000..4739c28919 --- /dev/null +++ b/tests/PHPStan/Node/AttributeGroupRuleTest.php @@ -0,0 +1,59 @@ +analyse([$file], $errors); + } + +} diff --git a/tests/PHPStan/Node/AttributeRuleTest.php b/tests/PHPStan/Node/AttributeRuleTest.php new file mode 100644 index 0000000000..f1f6efce7d --- /dev/null +++ b/tests/PHPStan/Node/AttributeRuleTest.php @@ -0,0 +1,59 @@ +analyse([$file], $errors); + } + +} diff --git a/tests/PHPStan/Node/data/attributes.php b/tests/PHPStan/Node/data/attributes.php new file mode 100644 index 0000000000..050f5c7845 --- /dev/null +++ b/tests/PHPStan/Node/data/attributes.php @@ -0,0 +1,41 @@ + Date: Fri, 20 May 2022 16:45:25 +0200 Subject: [PATCH 3/4] fix phpstan errors --- tests/PHPStan/Node/AttributeArgRule.php | 31 +++++++++++++++++ tests/PHPStan/Node/AttributeArgRuleTest.php | 32 +++++------------- tests/PHPStan/Node/AttributeGroupRule.php | 31 +++++++++++++++++ tests/PHPStan/Node/AttributeGroupRuleTest.php | 32 +++++------------- tests/PHPStan/Node/AttributeRule.php | 31 +++++++++++++++++ tests/PHPStan/Node/AttributeRuleTest.php | 33 ++++++------------- tests/PHPStan/Node/data/attributes.php | 2 +- 7 files changed, 122 insertions(+), 70 deletions(-) create mode 100644 tests/PHPStan/Node/AttributeArgRule.php create mode 100644 tests/PHPStan/Node/AttributeGroupRule.php create mode 100644 tests/PHPStan/Node/AttributeRule.php diff --git a/tests/PHPStan/Node/AttributeArgRule.php b/tests/PHPStan/Node/AttributeArgRule.php new file mode 100644 index 0000000000..90865da170 --- /dev/null +++ b/tests/PHPStan/Node/AttributeArgRule.php @@ -0,0 +1,31 @@ + + */ +class AttributeArgRule implements Rule +{ + + public const ERROR_MESSAGE = 'Found Arg'; + + public function getNodeType(): string + { + return Node\Arg::class; + } + + /** + * @param Node\Arg $node + * @return string[] + */ + public function processNode(Node $node, Scope $scope): array + { + return [self::ERROR_MESSAGE]; + } + +} diff --git a/tests/PHPStan/Node/AttributeArgRuleTest.php b/tests/PHPStan/Node/AttributeArgRuleTest.php index d1946f91c3..29773859d8 100644 --- a/tests/PHPStan/Node/AttributeArgRuleTest.php +++ b/tests/PHPStan/Node/AttributeArgRuleTest.php @@ -3,43 +3,29 @@ namespace PHPStan\Node; use PhpParser\Node; -use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; -use PHPStan\Rules\RuleError; use PHPStan\Testing\RuleTestCase; +/** + * @extends RuleTestCase + */ class AttributeArgRuleTest extends RuleTestCase { - public const ERROR_MESSAGE = 'Found Arg'; - + /** + * @return Rule + */ protected function getRule(): Rule { - return new class() implements Rule { - - public function getNodeType(): string - { - return Node\Arg::class; - } - - /** - * @param Node\Arg $node - * @return RuleError[] - */ - public function processNode(Node $node, Scope $scope): array - { - return [AttributeArgRuleTest::ERROR_MESSAGE]; - } - - }; + return new AttributeArgRule(); } public function dataRule(): iterable { yield [ __DIR__ . '/data/attributes.php', - self::ERROR_MESSAGE, - [8, 16, 20, 23, 26, 27, 34, 40], + AttributeArgRule::ERROR_MESSAGE, + [8, 16, 20, 23, 26, 27, 34, 40], ]; } diff --git a/tests/PHPStan/Node/AttributeGroupRule.php b/tests/PHPStan/Node/AttributeGroupRule.php new file mode 100644 index 0000000000..127c4f1f62 --- /dev/null +++ b/tests/PHPStan/Node/AttributeGroupRule.php @@ -0,0 +1,31 @@ + + */ +class AttributeGroupRule implements Rule +{ + + public const ERROR_MESSAGE = 'Found AttributeGroup'; + + public function getNodeType(): string + { + return Node\AttributeGroup::class; + } + + /** + * @param Node\AttributeGroup $node + * @return string[] + */ + public function processNode(Node $node, Scope $scope): array + { + return [self::ERROR_MESSAGE]; + } + +} diff --git a/tests/PHPStan/Node/AttributeGroupRuleTest.php b/tests/PHPStan/Node/AttributeGroupRuleTest.php index 4739c28919..d1e3044f44 100644 --- a/tests/PHPStan/Node/AttributeGroupRuleTest.php +++ b/tests/PHPStan/Node/AttributeGroupRuleTest.php @@ -3,43 +3,29 @@ namespace PHPStan\Node; use PhpParser\Node; -use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; -use PHPStan\Rules\RuleError; use PHPStan\Testing\RuleTestCase; +/** + * @extends RuleTestCase + */ class AttributeGroupRuleTest extends RuleTestCase { - public const ERROR_MESSAGE = 'Found AttributeGroup'; - + /** + * @return Rule + */ protected function getRule(): Rule { - return new class() implements Rule { - - public function getNodeType(): string - { - return Node\AttributeGroup::class; - } - - /** - * @param Node\AttributeGroup $node - * @return RuleError[] - */ - public function processNode(Node $node, Scope $scope): array - { - return [AttributeGroupRuleTest::ERROR_MESSAGE]; - } - - }; + return new AttributeGroupRule(); } public function dataRule(): iterable { yield [ __DIR__ . '/data/attributes.php', - self::ERROR_MESSAGE, - [8, 16, 20, 23, 26, 27, 34, 40], + AttributeGroupRule::ERROR_MESSAGE, + [8, 16, 20, 23, 26, 27, 34, 40], ]; } diff --git a/tests/PHPStan/Node/AttributeRule.php b/tests/PHPStan/Node/AttributeRule.php new file mode 100644 index 0000000000..9b7519bce8 --- /dev/null +++ b/tests/PHPStan/Node/AttributeRule.php @@ -0,0 +1,31 @@ + + */ +class AttributeRule implements Rule +{ + + public const ERROR_MESSAGE = 'Found Attribute'; + + public function getNodeType(): string + { + return Node\Attribute::class; + } + + /** + * @param Node\Attribute $node + * @return string[] + */ + public function processNode(Node $node, Scope $scope): array + { + return [self::ERROR_MESSAGE]; + } + +} diff --git a/tests/PHPStan/Node/AttributeRuleTest.php b/tests/PHPStan/Node/AttributeRuleTest.php index f1f6efce7d..9eadcd0fdb 100644 --- a/tests/PHPStan/Node/AttributeRuleTest.php +++ b/tests/PHPStan/Node/AttributeRuleTest.php @@ -3,43 +3,30 @@ namespace PHPStan\Node; use PhpParser\Node; -use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; -use PHPStan\Rules\RuleError; use PHPStan\Testing\RuleTestCase; +use const PHP_VERSION_ID; +/** + * @extends RuleTestCase + */ class AttributeRuleTest extends RuleTestCase { - public const ERROR_MESSAGE = 'Found Attribute'; - + /** + * @return Rule + */ protected function getRule(): Rule { - return new class() implements Rule { - - public function getNodeType(): string - { - return Node\Attribute::class; - } - - /** - * @param Node\Attribute $node - * @return RuleError[] - */ - public function processNode(Node $node, Scope $scope): array - { - return [AttributeRuleTest::ERROR_MESSAGE]; - } - - }; + return new AttributeRule(); } public function dataRule(): iterable { yield [ __DIR__ . '/data/attributes.php', - self::ERROR_MESSAGE, - [8, 16, 20, 23, 26, 27, 34, 40], + AttributeRule::ERROR_MESSAGE, + [8, 16, 20, 23, 26, 27, 34, 40], ]; } diff --git a/tests/PHPStan/Node/data/attributes.php b/tests/PHPStan/Node/data/attributes.php index 050f5c7845..0103b343c4 100644 --- a/tests/PHPStan/Node/data/attributes.php +++ b/tests/PHPStan/Node/data/attributes.php @@ -1,4 +1,4 @@ -= 8.0 namespace NodeCallbackCalled; From 1aaae32c0b487ad0c6cac5ec2d52e42551f864a3 Mon Sep 17 00:00:00 2001 From: Jan Nedbal Date: Fri, 27 May 2022 14:55:41 +0200 Subject: [PATCH 4/4] cs fix --- tests/PHPStan/Node/AttributeRuleTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/PHPStan/Node/AttributeRuleTest.php b/tests/PHPStan/Node/AttributeRuleTest.php index 9eadcd0fdb..3b189a210d 100644 --- a/tests/PHPStan/Node/AttributeRuleTest.php +++ b/tests/PHPStan/Node/AttributeRuleTest.php @@ -5,7 +5,6 @@ use PhpParser\Node; use PHPStan\Rules\Rule; use PHPStan\Testing\RuleTestCase; -use const PHP_VERSION_ID; /** * @extends RuleTestCase