Skip to content

Commit 7848b38

Browse files
committed
Fix various issues with final-overriden class assumptions
1 parent 2d7dd08 commit 7848b38

File tree

3 files changed

+31
-60
lines changed

3 files changed

+31
-60
lines changed

phpstan-baseline.neon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1419,7 +1419,7 @@ parameters:
14191419
-
14201420
message: '#^Doing instanceof PHPStan\\Type\\ObjectType is error\-prone and deprecated\. Use Type\:\:isObject\(\) or Type\:\:getObjectClassNames\(\) instead\.$#'
14211421
identifier: phpstanApi.instanceofType
1422-
count: 3
1422+
count: 2
14231423
path: src/Type/ObjectType.php
14241424

14251425
-

src/Reflection/ClassReflection.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -856,7 +856,7 @@ public function isSubclassOfClass(self $class): bool
856856
return $this->subclasses[$cacheKey];
857857
}
858858

859-
if ($class->isFinal() || $class->isAnonymous()) {
859+
if ($class->isFinalByKeyword() || $class->isAnonymous()) {
860860
return $this->subclasses[$cacheKey] = false;
861861
}
862862

src/Type/ObjectType.php

Lines changed: 29 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ public function getUnresolvedPropertyPrototype(string $propertyName, ClassMember
182182
} else {
183183
$canAccessProperty = $scope->getClassReflection()->getName();
184184
}
185-
$description = $this->describeCache();
185+
$description = $this->describe(VerbosityLevel::cache());
186186

187187
if (isset(self::$properties[$description][$propertyName][$canAccessProperty])) {
188188
return self::$properties[$description][$propertyName][$canAccessProperty];
@@ -321,14 +321,8 @@ public function isSuperTypeOf(Type $type): IsSuperTypeOfResult
321321
return IsSuperTypeOfResult::createNo();
322322
}
323323

324-
$thisDescription = $this->describeCache();
325-
326-
if ($type instanceof self) {
327-
$description = $type->describeCache();
328-
} else {
329-
$description = $type->describe(VerbosityLevel::cache());
330-
}
331-
324+
$thisDescription = $this->describe(VerbosityLevel::cache());
325+
$description = $type->describe(VerbosityLevel::cache());
332326
if (isset(self::$superTypes[$thisDescription][$description])) {
333327
return self::$superTypes[$thisDescription][$description];
334328
}
@@ -516,15 +510,33 @@ public function describe(VerbosityLevel $level): string
516510
$preciseNameCallback,
517511
$preciseWithSubtracted,
518512
function () use ($preciseWithSubtracted): string {
513+
if ($this->cachedDescription !== null) {
514+
return $this->cachedDescription;
515+
}
516+
517+
$description = $preciseWithSubtracted();
518+
519+
if ($this instanceof GenericObjectType) {
520+
$description .= '<';
521+
$typeDescriptions = [];
522+
foreach ($this->getTypes() as $type) {
523+
$typeDescriptions[] = $type->describe(VerbosityLevel::cache());
524+
}
525+
$description .= '<' . implode(', ', $typeDescriptions) . '>';
526+
}
527+
519528
$reflection = $this->classReflection;
520-
$line = '';
521529
if ($reflection !== null) {
522-
$line .= '-';
523-
$line .= (string) $reflection->getNativeReflection()->getStartLine();
524-
$line .= '-';
530+
$description .= '-';
531+
$description .= (string) $reflection->getNativeReflection()->getStartLine();
532+
$description .= '-';
533+
534+
if ($reflection->hasFinalByKeywordOverride()) {
535+
$description .= 'f=' . ($reflection->isFinalByKeyword() ? 't' : 'f');
536+
}
525537
}
526538

527-
return $preciseWithSubtracted() . '-' . static::class . '-' . $line . $this->describeAdditionalCacheKey();
539+
return $this->cachedDescription = $description . $this->describeAdditionalCacheKey();
528540
},
529541
);
530542
}
@@ -534,47 +546,6 @@ protected function describeAdditionalCacheKey(): string
534546
return '';
535547
}
536548

537-
private function describeCache(): string
538-
{
539-
if ($this->cachedDescription !== null) {
540-
return $this->cachedDescription;
541-
}
542-
543-
if (static::class !== self::class) {
544-
return $this->cachedDescription = $this->describe(VerbosityLevel::cache());
545-
}
546-
547-
$description = $this->className;
548-
549-
if ($this instanceof GenericObjectType) {
550-
$description .= '<';
551-
$typeDescriptions = [];
552-
foreach ($this->getTypes() as $type) {
553-
$typeDescriptions[] = $type->describe(VerbosityLevel::cache());
554-
}
555-
$description .= '<' . implode(', ', $typeDescriptions) . '>';
556-
}
557-
558-
if ($this->subtractedType !== null) {
559-
$description .= $this->subtractedType instanceof UnionType
560-
? sprintf('~(%s)', $this->subtractedType->describe(VerbosityLevel::cache()))
561-
: sprintf('~%s', $this->subtractedType->describe(VerbosityLevel::cache()));
562-
}
563-
564-
$reflection = $this->classReflection;
565-
if ($reflection !== null) {
566-
$description .= '-';
567-
$description .= (string) $reflection->getNativeReflection()->getStartLine();
568-
$description .= '-';
569-
570-
if ($reflection->hasFinalByKeywordOverride()) {
571-
$description .= 'f=' . ($reflection->isFinalByKeyword() ? 't' : 'f');
572-
}
573-
}
574-
575-
return $this->cachedDescription = $description;
576-
}
577-
578549
public function toNumber(): Type
579550
{
580551
if ($this->isInstanceOf('SimpleXMLElement')->yes()) {
@@ -777,7 +748,7 @@ public function getUnresolvedMethodPrototype(string $methodName, ClassMemberAcce
777748
} else {
778749
$canCallMethod = $scope->getClassReflection()->getName();
779750
}
780-
$description = $this->describeCache();
751+
$description = $this->describe(VerbosityLevel::cache());
781752
if (isset(self::$methods[$description][$methodName][$canCallMethod])) {
782753
return self::$methods[$description][$methodName][$canCallMethod];
783754
}
@@ -1266,7 +1237,7 @@ public function getEnumCases(): array
12661237
return [];
12671238
}
12681239

1269-
$cacheKey = $this->describeCache();
1240+
$cacheKey = $this->describe(VerbosityLevel::cache());
12701241
if (array_key_exists($cacheKey, self::$enumCases)) {
12711242
return self::$enumCases[$cacheKey];
12721243
}
@@ -1529,7 +1500,7 @@ public function getAncestorWithClassName(string $className): ?self
15291500
return $this->currentAncestors[$className];
15301501
}
15311502

1532-
$description = $this->describeCache();
1503+
$description = $this->describe(VerbosityLevel::cache());
15331504
if (
15341505
array_key_exists($description, self::$ancestors)
15351506
&& array_key_exists($className, self::$ancestors[$description])

0 commit comments

Comments
 (0)