Skip to content

Commit 10388a9

Browse files
committed
Continue refactoring (unDRYing) PhpDocBlock
1 parent 2539ab7 commit 10388a9

File tree

3 files changed

+122
-132
lines changed

3 files changed

+122
-132
lines changed

phpstan-baseline.neon

-10
Original file line numberDiff line numberDiff line change
@@ -171,16 +171,6 @@ parameters:
171171
count: 1
172172
path: src/Internal/ContainerDynamicReturnTypeExtension.php
173173

174-
-
175-
message: "#^Variable method call on PHPStan\\\\Reflection\\\\ClassReflection\\.$#"
176-
count: 2
177-
path: src/PhpDoc/PhpDocBlock.php
178-
179-
-
180-
message: "#^Variable static method call on PHPStan\\\\PhpDoc\\\\PhpDocBlock\\.$#"
181-
count: 1
182-
path: src/PhpDoc/PhpDocBlock.php
183-
184174
-
185175
message: "#^Call to function method_exists\\(\\) with PHPStan\\\\PhpDocParser\\\\Ast\\\\PhpDoc\\\\PhpDocNode and 'getParamOutTypeTagV…' will always evaluate to true\\.$#"
186176
count: 1

src/PhpDoc/PhpDocBlock.php

+122-117
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,8 @@
44

55
use PHPStan\PhpDoc\Tag\AssertTagParameter;
66
use PHPStan\Reflection\ClassReflection;
7-
use PHPStan\Reflection\ConstantReflection;
8-
use PHPStan\Reflection\MethodReflection;
97
use PHPStan\Reflection\Php\PhpMethodReflection;
10-
use PHPStan\Reflection\Php\PhpPropertyReflection;
11-
use PHPStan\Reflection\PropertyReflection;
128
use PHPStan\Reflection\ResolvedMethodReflection;
13-
use PHPStan\Reflection\ResolvedPropertyReflection;
149
use PHPStan\Type\ConditionalTypeForParameter;
1510
use PHPStan\Type\Type;
1611
use PHPStan\Type\TypeTraverser;
@@ -114,74 +109,71 @@ public function transformAssertTagParameterWithParameterNameMapping(AssertTagPar
114109
return $parameter;
115110
}
116111

117-
/**
118-
* @param array<int, string> $originalPositionalParameterNames
119-
* @param array<int, string> $newPositionalParameterNames
120-
*/
121112
public static function resolvePhpDocBlockForProperty(
122113
?string $docComment,
123114
ClassReflection $classReflection,
124115
?string $trait,
125116
string $propertyName,
126117
?string $file,
127118
?bool $explicit,
128-
array $originalPositionalParameterNames, // unused
129-
array $newPositionalParameterNames, // unused
130119
): self
131120
{
132-
$docBlocksFromParents = self::resolveParentPhpDocBlocks(
133-
self::getParentReflections($classReflection),
134-
$propertyName,
135-
'hasNativeProperty',
136-
'getNativeProperty',
137-
__FUNCTION__,
138-
$explicit ?? $docComment !== null,
139-
$newPositionalParameterNames,
140-
);
121+
$docBlocksFromParents = [];
122+
foreach (self::getParentReflections($classReflection) as $parentReflection) {
123+
$oneResult = self::resolvePropertyPhpDocBlockFromClass(
124+
$parentReflection,
125+
$propertyName,
126+
$explicit ?? $docComment !== null,
127+
);
128+
129+
if ($oneResult === null) { // Null if it is private or from a wrong trait.
130+
continue;
131+
}
132+
133+
$docBlocksFromParents[] = $oneResult;
134+
}
141135

142136
return new self(
143137
$docComment ?? ResolvedPhpDocBlock::EMPTY_DOC_STRING,
144138
$file,
145139
$classReflection,
146140
$trait,
147141
$explicit ?? true,
148-
self::remapParameterNames($originalPositionalParameterNames, $newPositionalParameterNames),
142+
[],
149143
$docBlocksFromParents,
150144
);
151145
}
152146

153-
/**
154-
* @param array<int, string> $originalPositionalParameterNames
155-
* @param array<int, string> $newPositionalParameterNames
156-
*/
157147
public static function resolvePhpDocBlockForConstant(
158148
?string $docComment,
159149
ClassReflection $classReflection,
160-
?string $trait, // unused
161150
string $constantName,
162151
?string $file,
163152
?bool $explicit,
164-
array $originalPositionalParameterNames, // unused
165-
array $newPositionalParameterNames, // unused
166153
): self
167154
{
168-
$docBlocksFromParents = self::resolveParentPhpDocBlocks(
169-
self::getParentReflections($classReflection),
170-
$constantName,
171-
'hasConstant',
172-
'getConstant',
173-
__FUNCTION__,
174-
$explicit ?? $docComment !== null,
175-
$newPositionalParameterNames,
176-
);
155+
$docBlocksFromParents = [];
156+
foreach (self::getParentReflections($classReflection) as $parentReflection) {
157+
$oneResult = self::resolveConstantPhpDocBlockFromClass(
158+
$parentReflection,
159+
$constantName,
160+
$explicit ?? $docComment !== null,
161+
);
162+
163+
if ($oneResult === null) { // Null if it is private or from a wrong trait.
164+
continue;
165+
}
166+
167+
$docBlocksFromParents[] = $oneResult;
168+
}
177169

178170
return new self(
179171
$docComment ?? ResolvedPhpDocBlock::EMPTY_DOC_STRING,
180172
$file,
181173
$classReflection,
182-
$trait,
174+
null,
183175
$explicit ?? true,
184-
self::remapParameterNames($originalPositionalParameterNames, $newPositionalParameterNames),
176+
[],
185177
$docBlocksFromParents,
186178
);
187179
}
@@ -219,15 +211,21 @@ public static function resolvePhpDocBlockForMethod(
219211
$parentReflections[] = $traitReflection;
220212
}
221213

222-
$docBlocksFromParents = self::resolveParentPhpDocBlocks(
223-
$parentReflections,
224-
$methodName,
225-
'hasNativeMethod',
226-
'getNativeMethod',
227-
__FUNCTION__,
228-
$explicit ?? $docComment !== null,
229-
$newPositionalParameterNames,
230-
);
214+
$docBlocksFromParents = [];
215+
foreach ($parentReflections as $parentReflection) {
216+
$oneResult = self::resolveMethodPhpDocBlockFromClass(
217+
$parentReflection,
218+
$methodName,
219+
$explicit ?? $docComment !== null,
220+
$newPositionalParameterNames,
221+
);
222+
223+
if ($oneResult === null) { // Null if it is private or from a wrong trait.
224+
continue;
225+
}
226+
227+
$docBlocksFromParents[] = $oneResult;
228+
}
231229

232230
return new self(
233231
$docComment ?? ResolvedPhpDocBlock::EMPTY_DOC_STRING,
@@ -262,117 +260,124 @@ private static function remapParameterNames(
262260
}
263261

264262
/**
265-
* @param array<int, ClassReflection> $parentReflections
266-
* @param array<int, string> $positionalParameterNames
267-
* @return array<int, self>
263+
* @return array<int, ClassReflection>
268264
*/
269-
private static function resolveParentPhpDocBlocks(
270-
array $parentReflections,
265+
private static function getParentReflections(ClassReflection $classReflection): array
266+
{
267+
$result = [];
268+
269+
$parent = $classReflection->getParentClass();
270+
if ($parent !== null) {
271+
$result[] = $parent;
272+
}
273+
274+
foreach ($classReflection->getInterfaces() as $interface) {
275+
$result[] = $interface;
276+
}
277+
278+
return $result;
279+
}
280+
281+
private static function resolveConstantPhpDocBlockFromClass(
282+
ClassReflection $classReflection,
271283
string $name,
272-
string $hasMethodName,
273-
string $getMethodName,
274-
string $resolveMethodName,
275284
bool $explicit,
276-
array $positionalParameterNames,
277-
): array
285+
): ?self
278286
{
279-
$result = [];
287+
if ($classReflection->hasConstant($name)) {
288+
$parentReflection = $classReflection->getConstant($name);
289+
if ($parentReflection->isPrivate()) {
290+
return null;
291+
}
280292

281-
foreach ($parentReflections as $parentReflection) {
282-
$oneResult = self::resolvePhpDocBlockFromClass(
283-
$parentReflection,
293+
$classReflection = $parentReflection->getDeclaringClass();
294+
295+
return self::resolvePhpDocBlockForConstant(
296+
$parentReflection->getDocComment() ?? ResolvedPhpDocBlock::EMPTY_DOC_STRING,
297+
$classReflection,
284298
$name,
285-
$hasMethodName,
286-
$getMethodName,
287-
$resolveMethodName,
299+
$classReflection->getFileName(),
288300
$explicit,
289-
$positionalParameterNames,
290301
);
291-
292-
if ($oneResult === null) { // Null if it is private or from a wrong trait.
293-
continue;
294-
}
295-
296-
$result[] = $oneResult;
297302
}
298303

299-
return $result;
304+
return null;
300305
}
301306

302-
/**
303-
* @return array<int, ClassReflection>
304-
*/
305-
private static function getParentReflections(ClassReflection $classReflection): array
307+
private static function resolvePropertyPhpDocBlockFromClass(
308+
ClassReflection $classReflection,
309+
string $name,
310+
bool $explicit,
311+
): ?self
306312
{
307-
$result = [];
313+
if ($classReflection->hasNativeProperty($name)) {
314+
$parentReflection = $classReflection->getNativeProperty($name);
315+
if ($parentReflection->isPrivate()) {
316+
return null;
317+
}
308318

309-
$parent = $classReflection->getParentClass();
310-
if ($parent !== null) {
311-
$result[] = $parent;
312-
}
319+
$classReflection = $parentReflection->getDeclaringClass();
320+
$traitReflection = $parentReflection->getDeclaringTrait();
313321

314-
foreach ($classReflection->getInterfaces() as $interface) {
315-
$result[] = $interface;
322+
$trait = $traitReflection !== null
323+
? $traitReflection->getName()
324+
: null;
325+
326+
return self::resolvePhpDocBlockForProperty(
327+
$parentReflection->getDocComment() ?? ResolvedPhpDocBlock::EMPTY_DOC_STRING,
328+
$classReflection,
329+
$trait,
330+
$name,
331+
$classReflection->getFileName(),
332+
$explicit,
333+
);
316334
}
317335

318-
return $result;
336+
return null;
319337
}
320338

321339
/**
322340
* @param array<int, string> $positionalParameterNames
323341
*/
324-
private static function resolvePhpDocBlockFromClass(
342+
private static function resolveMethodPhpDocBlockFromClass(
325343
ClassReflection $classReflection,
326344
string $name,
327-
string $hasMethodName,
328-
string $getMethodName,
329-
string $resolveMethodName,
330345
bool $explicit,
331346
array $positionalParameterNames,
332347
): ?self
333348
{
334-
if ($classReflection->$hasMethodName($name)) {
335-
/** @var PropertyReflection|MethodReflection|ConstantReflection $parentReflection */
336-
$parentReflection = $classReflection->$getMethodName($name);
349+
if ($classReflection->hasNativeMethod($name)) {
350+
$parentReflection = $classReflection->getNativeMethod($name);
337351
if ($parentReflection->isPrivate()) {
338352
return null;
339353
}
340354

341355
$classReflection = $parentReflection->getDeclaringClass();
342-
343-
if ($parentReflection instanceof PhpPropertyReflection || $parentReflection instanceof ResolvedPropertyReflection) {
356+
$traitReflection = null;
357+
if ($parentReflection instanceof PhpMethodReflection || $parentReflection instanceof ResolvedMethodReflection) {
344358
$traitReflection = $parentReflection->getDeclaringTrait();
345-
$positionalMethodParameterNames = [];
346-
} elseif ($parentReflection instanceof MethodReflection) {
347-
$traitReflection = null;
348-
if ($parentReflection instanceof PhpMethodReflection || $parentReflection instanceof ResolvedMethodReflection) {
349-
$traitReflection = $parentReflection->getDeclaringTrait();
350-
}
351-
$methodVariants = $parentReflection->getVariants();
352-
$positionalMethodParameterNames = [];
353-
$lowercaseMethodName = strtolower($parentReflection->getName());
354-
if (
355-
count($methodVariants) === 1
356-
&& $lowercaseMethodName !== '__construct'
357-
&& $lowercaseMethodName !== strtolower($parentReflection->getDeclaringClass()->getName())
358-
) {
359-
$methodParameters = $methodVariants[0]->getParameters();
360-
foreach ($methodParameters as $methodParameter) {
361-
$positionalMethodParameterNames[] = $methodParameter->getName();
362-
}
363-
} else {
364-
$positionalMethodParameterNames = $positionalParameterNames;
359+
}
360+
$methodVariants = $parentReflection->getVariants();
361+
$positionalMethodParameterNames = [];
362+
$lowercaseMethodName = strtolower($parentReflection->getName());
363+
if (
364+
count($methodVariants) === 1
365+
&& $lowercaseMethodName !== '__construct'
366+
&& $lowercaseMethodName !== strtolower($parentReflection->getDeclaringClass()->getName())
367+
) {
368+
$methodParameters = $methodVariants[0]->getParameters();
369+
foreach ($methodParameters as $methodParameter) {
370+
$positionalMethodParameterNames[] = $methodParameter->getName();
365371
}
366372
} else {
367-
$traitReflection = null;
368-
$positionalMethodParameterNames = [];
373+
$positionalMethodParameterNames = $positionalParameterNames;
369374
}
370375

371376
$trait = $traitReflection !== null
372377
? $traitReflection->getName()
373378
: null;
374379

375-
return self::$resolveMethodName(
380+
return self::resolvePhpDocBlockForMethod(
376381
$parentReflection->getDocComment() ?? ResolvedPhpDocBlock::EMPTY_DOC_STRING,
377382
$classReflection,
378383
$trait,

src/PhpDoc/PhpDocInheritanceResolver.php

-5
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ public function resolvePhpDocForProperty(
3333
$propertyName,
3434
$classReflectionFileName,
3535
null,
36-
[],
37-
[],
3836
);
3937

4038
return $this->docBlockTreeToResolvedDocBlock($phpDocBlock, $declaringTraitName, null, $propertyName, null);
@@ -50,12 +48,9 @@ public function resolvePhpDocForConstant(
5048
$phpDocBlock = PhpDocBlock::resolvePhpDocBlockForConstant(
5149
$docComment,
5250
$classReflection,
53-
null,
5451
$constantName,
5552
$classReflectionFileName,
5653
null,
57-
[],
58-
[],
5954
);
6055

6156
return $this->docBlockTreeToResolvedDocBlock($phpDocBlock, null, null, null, $constantName);

0 commit comments

Comments
 (0)