Skip to content

Commit ff910ce

Browse files
committed
Fix Adapter ReflectionEnum tests on PHP 7.4
1 parent 8fd91a4 commit ff910ce

File tree

3 files changed

+190
-0
lines changed

3 files changed

+190
-0
lines changed

conf/config.neon

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,25 @@ services:
794794
-
795795
class: PHPStan\Reflection\BetterReflection\SourceLocator\OptimizedSingleFileSourceLocatorRepository
796796

797+
-
798+
class: PHPStan\Reflection\BetterReflection\Type\AdapterReflectionEnumCaseDynamicReturnTypeExtension
799+
arguments:
800+
class: PHPStan\BetterReflection\Reflection\Adapter\ReflectionEnumBackedCase
801+
tags:
802+
- phpstan.broker.dynamicMethodReturnTypeExtension
803+
804+
-
805+
class: PHPStan\Reflection\BetterReflection\Type\AdapterReflectionEnumCaseDynamicReturnTypeExtension
806+
arguments:
807+
class: PHPStan\BetterReflection\Reflection\Adapter\ReflectionEnumUnitCase
808+
tags:
809+
- phpstan.broker.dynamicMethodReturnTypeExtension
810+
811+
-
812+
class: PHPStan\Reflection\BetterReflection\Type\AdapterReflectionEnumDynamicReturnTypeExtension
813+
tags:
814+
- phpstan.broker.dynamicMethodReturnTypeExtension
815+
797816
-
798817
class: PHPStan\Reflection\RequireExtension\RequireExtendsMethodsClassReflectionExtension
799818

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Reflection\BetterReflection\Type;
4+
5+
use PhpParser\Node\Expr\MethodCall;
6+
use PHPStan\Analyser\Scope;
7+
use PHPStan\BetterReflection\Reflection\Adapter\ReflectionIntersectionType;
8+
use PHPStan\BetterReflection\Reflection\Adapter\ReflectionNamedType;
9+
use PHPStan\BetterReflection\Reflection\Adapter\ReflectionUnionType;
10+
use PHPStan\Php\PhpVersion;
11+
use PHPStan\Reflection\MethodReflection;
12+
use PHPStan\Type\Constant\ConstantBooleanType;
13+
use PHPStan\Type\DynamicMethodReturnTypeExtension;
14+
use PHPStan\Type\NullType;
15+
use PHPStan\Type\ObjectType;
16+
use PHPStan\Type\StringType;
17+
use PHPStan\Type\Type;
18+
use PHPStan\Type\UnionType;
19+
use function in_array;
20+
21+
class AdapterReflectionEnumCaseDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension
22+
{
23+
24+
public function __construct(private PhpVersion $phpVersion, private string $class)
25+
{
26+
}
27+
28+
public function getClass(): string
29+
{
30+
return $this->class;
31+
}
32+
33+
public function isMethodSupported(MethodReflection $methodReflection): bool
34+
{
35+
return in_array($methodReflection->getName(), [
36+
'getDocComment',
37+
'getType',
38+
], true);
39+
}
40+
41+
public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): ?Type
42+
{
43+
if ($this->phpVersion->getVersionId() >= 80000) {
44+
return null;
45+
}
46+
47+
if ($methodReflection->getName() === 'getDocComment') {
48+
return new UnionType([
49+
new StringType(),
50+
new ConstantBooleanType(false),
51+
]);
52+
}
53+
54+
if ($methodReflection->getName() === 'getType') {
55+
return new UnionType([
56+
new ObjectType(ReflectionIntersectionType::class),
57+
new ObjectType(ReflectionNamedType::class),
58+
new ObjectType(ReflectionUnionType::class),
59+
new NullType(),
60+
]);
61+
}
62+
63+
return null;
64+
}
65+
66+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Reflection\BetterReflection\Type;
4+
5+
use PhpParser\Node\Expr\MethodCall;
6+
use PHPStan\Analyser\Scope;
7+
use PHPStan\BetterReflection\Reflection\Adapter\ReflectionClass;
8+
use PHPStan\BetterReflection\Reflection\Adapter\ReflectionClassConstant;
9+
use PHPStan\BetterReflection\Reflection\Adapter\ReflectionEnum;
10+
use PHPStan\BetterReflection\Reflection\Adapter\ReflectionNamedType;
11+
use PHPStan\Php\PhpVersion;
12+
use PHPStan\Reflection\MethodReflection;
13+
use PHPStan\Type\Accessory\AccessoryNonEmptyStringType;
14+
use PHPStan\Type\Constant\ConstantBooleanType;
15+
use PHPStan\Type\DynamicMethodReturnTypeExtension;
16+
use PHPStan\Type\IntegerType;
17+
use PHPStan\Type\IntersectionType;
18+
use PHPStan\Type\NullType;
19+
use PHPStan\Type\ObjectType;
20+
use PHPStan\Type\StringType;
21+
use PHPStan\Type\Type;
22+
use PHPStan\Type\UnionType;
23+
use function in_array;
24+
25+
class AdapterReflectionEnumDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension
26+
{
27+
28+
public function __construct(private PhpVersion $phpVersion)
29+
{
30+
}
31+
32+
public function getClass(): string
33+
{
34+
return ReflectionEnum::class;
35+
}
36+
37+
public function isMethodSupported(MethodReflection $methodReflection): bool
38+
{
39+
return in_array($methodReflection->getName(), [
40+
'getFileName',
41+
'getStartLine',
42+
'getEndLine',
43+
'getDocComment',
44+
'getReflectionConstant',
45+
'getParentClass',
46+
'getExtensionName',
47+
'getBackingType',
48+
], true);
49+
}
50+
51+
public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): ?Type
52+
{
53+
if ($this->phpVersion->getVersionId() >= 80000) {
54+
return null;
55+
}
56+
57+
if (in_array($methodReflection->getName(), ['getFileName', 'getExtensionName'], true)) {
58+
return new UnionType([
59+
new IntersectionType([
60+
new StringType(),
61+
new AccessoryNonEmptyStringType(),
62+
]),
63+
new ConstantBooleanType(false),
64+
]);
65+
}
66+
67+
if ($methodReflection->getName() === 'getDocComment') {
68+
return new UnionType([
69+
new StringType(),
70+
new ConstantBooleanType(false),
71+
]);
72+
}
73+
74+
if (in_array($methodReflection->getName(), ['getStartLine', 'getEndLine'], true)) {
75+
return new UnionType([
76+
new IntegerType(),
77+
new ConstantBooleanType(false),
78+
]);
79+
}
80+
81+
if ($methodReflection->getName() === 'getReflectionConstant') {
82+
return new UnionType([
83+
new ObjectType(ReflectionClassConstant::class),
84+
new ConstantBooleanType(false),
85+
]);
86+
}
87+
88+
if ($methodReflection->getName() === 'getParentClass') {
89+
return new UnionType([
90+
new ObjectType(ReflectionClass::class),
91+
new ConstantBooleanType(false),
92+
]);
93+
}
94+
95+
if ($methodReflection->getName() === 'getBackingType') {
96+
return new UnionType([
97+
new ObjectType(ReflectionNamedType::class),
98+
new NullType(),
99+
]);
100+
}
101+
102+
return null;
103+
}
104+
105+
}

0 commit comments

Comments
 (0)