Skip to content

Commit c4b89a0

Browse files
committed
Merge remote-tracking branch 'origin/1.12.x' into 2.1.x
2 parents 60f9b8b + 0c1f22a commit c4b89a0

21 files changed

+915
-13
lines changed

phpstan-baseline.neon

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,6 +1101,18 @@ parameters:
11011101
count: 2
11021102
path: src/Type/Generic/GenericObjectType.php
11031103

1104+
-
1105+
message: '#^Doing instanceof PHPStan\\Type\\ObjectType is error\-prone and deprecated\. Use Type\:\:isObject\(\) or Type\:\:getObjectClassNames\(\) instead\.$#'
1106+
identifier: phpstanApi.instanceofType
1107+
count: 1
1108+
path: src/Type/Generic/GenericStaticType.php
1109+
1110+
-
1111+
message: '#^Doing instanceof PHPStan\\Type\\TypeWithClassName is error\-prone and deprecated\. Use Type\:\:getObjectClassNames\(\) or Type\:\:getObjectClassReflections\(\) instead\.$#'
1112+
identifier: phpstanApi.instanceofType
1113+
count: 1
1114+
path: src/Type/Generic/GenericStaticType.php
1115+
11041116
-
11051117
message: '#^Doing instanceof PHPStan\\Type\\IntersectionType is error\-prone and deprecated\.$#'
11061118
identifier: phpstanApi.instanceofType

src/Analyser/MutatingScope.php

Lines changed: 76 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103
use PHPStan\Type\GeneralizePrecision;
104104
use PHPStan\Type\Generic\GenericClassStringType;
105105
use PHPStan\Type\Generic\GenericObjectType;
106+
use PHPStan\Type\Generic\GenericStaticType;
106107
use PHPStan\Type\Generic\TemplateType;
107108
use PHPStan\Type\Generic\TemplateTypeHelper;
108109
use PHPStan\Type\Generic\TemplateTypeMap;
@@ -5547,8 +5548,17 @@ public function debug(): array
55475548
private function exactInstantiation(New_ $node, string $className): ?Type
55485549
{
55495550
$resolvedClassName = $this->resolveExactName(new Name($className));
5551+
$isStatic = false;
55505552
if ($resolvedClassName === null) {
5551-
return null;
5553+
if (strtolower($className) !== 'static') {
5554+
return null;
5555+
}
5556+
5557+
if (!$this->isInClass()) {
5558+
return null;
5559+
}
5560+
$resolvedClassName = $this->getClassReflection()->getName();
5561+
$isStatic = true;
55525562
}
55535563

55545564
if (!$this->reflectionProvider->hasClass($resolvedClassName)) {
@@ -5605,7 +5615,7 @@ private function exactInstantiation(New_ $node, string $className): ?Type
56055615
return $methodResult;
56065616
}
56075617

5608-
$objectType = new ObjectType($resolvedClassName);
5618+
$objectType = $isStatic ? new StaticType($classReflection) : new ObjectType($resolvedClassName);
56095619
if (!$classReflection->isGeneric()) {
56105620
return $objectType;
56115621
}
@@ -5638,6 +5648,14 @@ private function exactInstantiation(New_ $node, string $className): ?Type
56385648
}
56395649

56405650
if ($constructorMethod instanceof DummyConstructorReflection) {
5651+
if ($isStatic) {
5652+
return new GenericStaticType(
5653+
$classReflection,
5654+
$classReflection->typeMapToList($classReflection->getTemplateTypeMap()->resolveToBounds()),
5655+
null,
5656+
[],
5657+
);
5658+
}
56415659
return new GenericObjectType(
56425660
$resolvedClassName,
56435661
$classReflection->typeMapToList($classReflection->getTemplateTypeMap()->resolveToBounds()),
@@ -5646,6 +5664,15 @@ private function exactInstantiation(New_ $node, string $className): ?Type
56465664

56475665
if ($constructorMethod->getDeclaringClass()->getName() !== $classReflection->getName()) {
56485666
if (!$constructorMethod->getDeclaringClass()->isGeneric()) {
5667+
if ($isStatic) {
5668+
return new GenericStaticType(
5669+
$classReflection,
5670+
$classReflection->typeMapToList($classReflection->getTemplateTypeMap()->resolveToBounds()),
5671+
null,
5672+
[],
5673+
);
5674+
}
5675+
56495676
return new GenericObjectType(
56505677
$resolvedClassName,
56515678
$classReflection->typeMapToList($classReflection->getTemplateTypeMap()->resolveToBounds()),
@@ -5654,13 +5681,31 @@ private function exactInstantiation(New_ $node, string $className): ?Type
56545681
$newType = new GenericObjectType($resolvedClassName, $classReflection->typeMapToList($classReflection->getTemplateTypeMap()));
56555682
$ancestorType = $newType->getAncestorWithClassName($constructorMethod->getDeclaringClass()->getName());
56565683
if ($ancestorType === null) {
5684+
if ($isStatic) {
5685+
return new GenericStaticType(
5686+
$classReflection,
5687+
$classReflection->typeMapToList($classReflection->getTemplateTypeMap()->resolveToBounds()),
5688+
null,
5689+
[],
5690+
);
5691+
}
5692+
56575693
return new GenericObjectType(
56585694
$resolvedClassName,
56595695
$classReflection->typeMapToList($classReflection->getTemplateTypeMap()->resolveToBounds()),
56605696
);
56615697
}
56625698
$ancestorClassReflections = $ancestorType->getObjectClassReflections();
56635699
if (count($ancestorClassReflections) !== 1) {
5700+
if ($isStatic) {
5701+
return new GenericStaticType(
5702+
$classReflection,
5703+
$classReflection->typeMapToList($classReflection->getTemplateTypeMap()->resolveToBounds()),
5704+
null,
5705+
[],
5706+
);
5707+
}
5708+
56645709
return new GenericObjectType(
56655710
$resolvedClassName,
56665711
$classReflection->typeMapToList($classReflection->getTemplateTypeMap()->resolveToBounds()),
@@ -5671,6 +5716,15 @@ private function exactInstantiation(New_ $node, string $className): ?Type
56715716
$newParentType = $this->getType($newParentNode);
56725717
$newParentTypeClassReflections = $newParentType->getObjectClassReflections();
56735718
if (count($newParentTypeClassReflections) !== 1) {
5719+
if ($isStatic) {
5720+
return new GenericStaticType(
5721+
$classReflection,
5722+
$classReflection->typeMapToList($classReflection->getTemplateTypeMap()->resolveToBounds()),
5723+
null,
5724+
[],
5725+
);
5726+
}
5727+
56745728
return new GenericObjectType(
56755729
$resolvedClassName,
56765730
$classReflection->typeMapToList($classReflection->getTemplateTypeMap()->resolveToBounds()),
@@ -5707,6 +5761,15 @@ private function exactInstantiation(New_ $node, string $className): ?Type
57075761
$resolvedTypeMap[$ancestorType->getName()] = TypeCombinator::union($resolvedTypeMap[$ancestorType->getName()], $type);
57085762
}
57095763

5764+
if ($isStatic) {
5765+
return new GenericStaticType(
5766+
$classReflection,
5767+
$classReflection->typeMapToList(new TemplateTypeMap($resolvedTypeMap)),
5768+
null,
5769+
[],
5770+
);
5771+
}
5772+
57105773
return new GenericObjectType(
57115774
$resolvedClassName,
57125775
$classReflection->typeMapToList(new TemplateTypeMap($resolvedTypeMap)),
@@ -5721,10 +5784,19 @@ private function exactInstantiation(New_ $node, string $className): ?Type
57215784
);
57225785

57235786
$resolvedTemplateTypeMap = $parametersAcceptor->getResolvedTemplateTypeMap();
5724-
return TypeTraverser::map(new GenericObjectType(
5787+
$newGenericType = new GenericObjectType(
57255788
$resolvedClassName,
57265789
$classReflection->typeMapToList($classReflection->getTemplateTypeMap()),
5727-
), static function (Type $type, callable $traverse) use ($resolvedTemplateTypeMap): Type {
5790+
);
5791+
if ($isStatic) {
5792+
$newGenericType = new GenericStaticType(
5793+
$classReflection,
5794+
$classReflection->typeMapToList($classReflection->getTemplateTypeMap()),
5795+
null,
5796+
[],
5797+
);
5798+
}
5799+
return TypeTraverser::map($newGenericType, static function (Type $type, callable $traverse) use ($resolvedTemplateTypeMap): Type {
57285800
if ($type instanceof TemplateType && !$type->isArgument()) {
57295801
$newType = $resolvedTemplateTypeMap->getType($type->getName());
57305802
if ($newType === null || $newType instanceof ErrorType) {

src/PhpDoc/TypeNodeResolver.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
use PHPStan\Type\FloatType;
7272
use PHPStan\Type\Generic\GenericClassStringType;
7373
use PHPStan\Type\Generic\GenericObjectType;
74+
use PHPStan\Type\Generic\GenericStaticType;
7475
use PHPStan\Type\Generic\TemplateType;
7576
use PHPStan\Type\Generic\TemplateTypeFactory;
7677
use PHPStan\Type\Generic\TemplateTypeMap;
@@ -783,6 +784,14 @@ static function (string $variance): TemplateTypeVariance {
783784
return $type->isResolvable() ? $type->resolve() : $type;
784785
}
785786

787+
return new ErrorType();
788+
} elseif ($mainTypeName === 'static') {
789+
if ($nameScope->getClassName() !== null && $this->getReflectionProvider()->hasClass($nameScope->getClassName())) {
790+
$classReflection = $this->getReflectionProvider()->getClass($nameScope->getClassName());
791+
792+
return new GenericStaticType($classReflection, $genericTypes, null, $variances);
793+
}
794+
786795
return new ErrorType();
787796
}
788797

src/Reflection/ResolvedFunctionVariantWithOriginal.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use PHPStan\Type\ConditionalTypeForParameter;
77
use PHPStan\Type\ErrorType;
88
use PHPStan\Type\Generic\GenericObjectType;
9+
use PHPStan\Type\Generic\GenericStaticType;
910
use PHPStan\Type\Generic\TemplateType;
1011
use PHPStan\Type\Generic\TemplateTypeHelper;
1112
use PHPStan\Type\Generic\TemplateTypeMap;
@@ -244,7 +245,7 @@ private function resolveResolvableTemplateTypes(Type $type, TemplateTypeVariance
244245
};
245246

246247
return TypeTraverser::map($type, function (Type $type, callable $traverse) use ($references, $objectCb): Type {
247-
if ($type instanceof GenericObjectType) {
248+
if ($type instanceof GenericObjectType || $type instanceof GenericStaticType) {
248249
return TypeTraverser::map($type, $objectCb);
249250
}
250251

src/Reflection/Type/CalledOnTypeUnresolvedMethodPrototypeReflection.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
use PHPStan\Reflection\ExtendedParametersAcceptor;
1111
use PHPStan\Reflection\Php\ExtendedDummyParameter;
1212
use PHPStan\Reflection\ResolvedMethodReflection;
13+
use PHPStan\Type\Generic\GenericObjectType;
14+
use PHPStan\Type\Generic\GenericStaticType;
15+
use PHPStan\Type\ObjectType;
1316
use PHPStan\Type\StaticType;
1417
use PHPStan\Type\Type;
1518
use PHPStan\Type\TypeTraverser;
@@ -114,6 +117,13 @@ private function transformMethodWithStaticType(ClassReflection $declaringClass,
114117
private function transformStaticType(Type $type): Type
115118
{
116119
return TypeTraverser::map($type, function (Type $type, callable $traverse): Type {
120+
if ($type instanceof GenericStaticType) {
121+
if ($this->calledOnType instanceof ObjectType) {
122+
return new GenericObjectType($this->calledOnType->getClassName(), $type->getTypes());
123+
}
124+
125+
return $this->calledOnType;
126+
}
117127
if ($type instanceof StaticType) {
118128
return $this->calledOnType;
119129
}

src/Rules/Generics/GenericObjectTypeCheck.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use PHPStan\Rules\RuleErrorBuilder;
77
use PHPStan\ShouldNotHappenException;
88
use PHPStan\Type\Generic\GenericObjectType;
9+
use PHPStan\Type\Generic\GenericStaticType;
910
use PHPStan\Type\Generic\TemplateType;
1011
use PHPStan\Type\Generic\TemplateTypeHelper;
1112
use PHPStan\Type\Generic\TemplateTypeVariance;
@@ -166,15 +167,15 @@ public function check(
166167
}
167168

168169
/**
169-
* @return GenericObjectType[]
170+
* @return list<GenericObjectType|GenericStaticType>
170171
*/
171172
private function getGenericTypes(Type $phpDocType): array
172173
{
173174
$genericObjectTypes = [];
174175
TypeTraverser::map($phpDocType, static function (Type $type, callable $traverse) use (&$genericObjectTypes): Type {
175-
if ($type instanceof GenericObjectType) {
176+
if ($type instanceof GenericObjectType || $type instanceof GenericStaticType) {
176177
$resolvedType = TemplateTypeHelper::resolveToBounds($type);
177-
if (!$resolvedType instanceof GenericObjectType) {
178+
if (!$resolvedType instanceof GenericObjectType && !$resolvedType instanceof GenericStaticType) {
178179
throw new ShouldNotHappenException();
179180
}
180181
$genericObjectTypes[] = $resolvedType;

src/Rules/Methods/MethodSignatureRule.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use PHPStan\TrinaryLogic;
1818
use PHPStan\Type\Accessory\AccessoryArrayListType;
1919
use PHPStan\Type\ArrayType;
20+
use PHPStan\Type\Generic\GenericStaticType;
2021
use PHPStan\Type\Generic\TemplateTypeHelper;
2122
use PHPStan\Type\IntegerRangeType;
2223
use PHPStan\Type\IntersectionType;
@@ -265,6 +266,15 @@ private function checkParameterTypeCompatibility(
265266
private function transformStaticType(ClassReflection $declaringClass, Type $type): Type
266267
{
267268
return TypeTraverser::map($type, static function (Type $type, callable $traverse) use ($declaringClass): Type {
269+
if ($type instanceof GenericStaticType) {
270+
if ($declaringClass->isFinal()) {
271+
$changedType = $type->changeBaseClass($declaringClass)->getStaticObjectType();
272+
} else {
273+
$changedType = $type->changeBaseClass($declaringClass);
274+
}
275+
return $traverse($changedType);
276+
}
277+
268278
if ($type instanceof StaticType) {
269279
if ($declaringClass->isFinal()) {
270280
$changedType = new ObjectType($declaringClass->getName());

src/Rules/MissingTypehintCheck.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use PHPStan\Type\ConditionalType;
1414
use PHPStan\Type\ConditionalTypeForParameter;
1515
use PHPStan\Type\Generic\GenericObjectType;
16+
use PHPStan\Type\Generic\GenericStaticType;
1617
use PHPStan\Type\Generic\TemplateType;
1718
use PHPStan\Type\Generic\TemplateTypeHelper;
1819
use PHPStan\Type\IntersectionType;
@@ -100,7 +101,7 @@ public function getNonGenericObjectTypesWithGenericClass(Type $type): array
100101
{
101102
$objectTypes = [];
102103
TypeTraverser::map($type, function (Type $type, callable $traverse) use (&$objectTypes): Type {
103-
if ($type instanceof GenericObjectType) {
104+
if ($type instanceof GenericObjectType || $type instanceof GenericStaticType) {
104105
$traverse($type);
105106
return $type;
106107
}

0 commit comments

Comments
 (0)