|
10 | 10 | use PHPStan\Rules\Rule; |
11 | 11 | use PHPStan\Rules\RuleErrorBuilder; |
12 | 12 | use PHPStan\Type\VerbosityLevel; |
| 13 | +use function array_column; |
| 14 | +use function array_map; |
13 | 15 | use function array_merge; |
14 | 16 | use function count; |
15 | 17 | use function sprintf; |
@@ -49,35 +51,38 @@ public function processNode(Node $node, Scope $scope): array |
49 | 51 | $errors = []; |
50 | 52 | foreach ($implementsTags as $implementsTag) { |
51 | 53 | $type = $implementsTag->getType(); |
52 | | - $classNames = $type->getObjectClassNames(); |
53 | | - if (count($classNames) === 0) { |
| 54 | + if (count($type->getObjectClassNames()) === 0) { |
54 | 55 | $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @phpstan-require-implements contains non-object type %s.', $type->describe(VerbosityLevel::typeOnly()))) |
55 | 56 | ->identifier('requireImplements.nonObject') |
56 | 57 | ->build(); |
57 | 58 | continue; |
58 | 59 | } |
59 | 60 |
|
60 | | - $class = $classNames[0]; |
61 | | - $referencedClassReflection = $type->getObjectClassReflections()[0] ?? null; |
62 | | - if ($referencedClassReflection === null) { |
63 | | - $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @phpstan-require-implements contains unknown class %s.', $class)) |
64 | | - ->discoveringSymbolsTip() |
65 | | - ->identifier('class.notFound') |
66 | | - ->build(); |
67 | | - continue; |
68 | | - } |
| 61 | + $referencedClassReflections = array_map(static fn ($reflection) => [$reflection, $reflection->getName()], $type->getObjectClassReflections()); |
| 62 | + $referencedClassReflectionsMap = array_column($referencedClassReflections, 0, 1); |
| 63 | + foreach ($type->getObjectClassNames() as $class) { |
| 64 | + $referencedClassReflection = $referencedClassReflectionsMap[$class] ?? null; |
| 65 | + if ($referencedClassReflection === null) { |
| 66 | + $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @phpstan-require-implements contains unknown class %s.', $class)) |
| 67 | + ->discoveringSymbolsTip() |
| 68 | + ->identifier('class.notFound') |
| 69 | + ->build(); |
| 70 | + continue; |
| 71 | + } |
| 72 | + |
| 73 | + if (!$referencedClassReflection->isInterface()) { |
| 74 | + $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @phpstan-require-implements cannot contain non-interface type %s.', $class)) |
| 75 | + ->identifier(sprintf('requireImplements.%s', strtolower($referencedClassReflection->getClassTypeDescription()))) |
| 76 | + ->build(); |
| 77 | + } else { |
| 78 | + $errors = array_merge( |
| 79 | + $errors, |
| 80 | + $this->classCheck->checkClassNames([ |
| 81 | + new ClassNameNodePair($class, $node), |
| 82 | + ], $this->checkClassCaseSensitivity), |
| 83 | + ); |
| 84 | + } |
69 | 85 |
|
70 | | - if (!$referencedClassReflection->isInterface()) { |
71 | | - $errors[] = RuleErrorBuilder::message(sprintf('PHPDoc tag @phpstan-require-implements cannot contain non-interface type %s.', $class)) |
72 | | - ->identifier(sprintf('requireImplements.%s', strtolower($referencedClassReflection->getClassTypeDescription()))) |
73 | | - ->build(); |
74 | | - } else { |
75 | | - $errors = array_merge( |
76 | | - $errors, |
77 | | - $this->classCheck->checkClassNames([ |
78 | | - new ClassNameNodePair($class, $node), |
79 | | - ], $this->checkClassCaseSensitivity), |
80 | | - ); |
81 | 86 | } |
82 | 87 | } |
83 | 88 |
|
|
0 commit comments