Skip to content

Commit 7055df4

Browse files
committed
fixed error on Enum type declaration and MyEnum|NoEnum and also support MyEnum1|MyEnum2
1 parent 452a803 commit 7055df4

File tree

2 files changed

+65
-11
lines changed

2 files changed

+65
-11
lines changed

src/EnumDynamicReturnTypeExtension.php

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,24 +40,34 @@ public function isMethodSupported(MethodReflection $methodReflection): bool
4040
return in_array(strtolower($methodReflection->getName()), $supportedMethods, true);
4141
}
4242

43-
public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): Type
44-
{
45-
$enumType = $scope->getType($methodCall->var);
46-
$methodName = $methodReflection->getName();
47-
$methodClasses = $enumType->getReferencedClasses();
48-
if (count($methodClasses) !== 1) {
49-
return ParametersAcceptorSelector::selectSingle($methodReflection->getVariants())->getReturnType();
50-
}
43+
public function getTypeFromMethodCall(
44+
MethodReflection $methodReflection,
45+
MethodCall $methodCall,
46+
Scope $scope
47+
): Type {
48+
$type = $scope->getType($methodCall->var);
49+
$typeClasses = $type->getReferencedClasses();
5150

52-
$enumeration = $methodClasses[0];
51+
$valuesTypeAll = null;
52+
foreach ($typeClasses as $typeClass) {
53+
if (!is_subclass_of($typeClass, Enum::class, true)) {
54+
return ParametersAcceptorSelector::selectSingle($methodReflection->getVariants())->getReturnType();
55+
}
56+
57+
$valuesType = $this->getEnumValuesType($typeClass, $scope);
58+
$valuesTypeAll = $valuesTypeAll
59+
? TypeCombinator::union($valuesTypeAll, $valuesType)
60+
: $valuesType;
61+
}
5362

63+
$methodName = $methodReflection->getName();
5464
switch (strtolower($methodName)) {
5565
case 'getvalue':
56-
return $this->getEnumValuesType($enumeration, $scope);
66+
return $valuesTypeAll;
5767
case 'getvalues':
5868
return new ArrayType(
5969
new IntegerType(),
60-
$this->getEnumValuesType($enumeration, $scope)
70+
$valuesTypeAll
6171
);
6272
default:
6373
throw new ShouldNotHappenException("Method {$methodName} is not supported");

tests/EnumDynamicReturnTypeExtensionTest.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,4 +168,48 @@ function f(MabeEnumPHPStanTest\Assets\IntTypeEnum $enum) {
168168

169169
$this->processCode($code, '$enum->getName()', 'string', $this->extension);
170170
}
171+
172+
public function testBaseEnumTypeMethod(): void
173+
{
174+
$code = <<<'CODE'
175+
<?php
176+
function f(MabeEnum\Enum $enum) {
177+
die;
178+
}
179+
CODE;
180+
181+
$this->processCode($code, '$enum->getValue()', 'mixed', $this->extension);
182+
}
183+
184+
public function testMultiEnumClassMethod(): void
185+
{
186+
$code = <<<'CODE'
187+
<?php
188+
use MabeEnumPHPStanTest\Assets\IntTypeEnum;
189+
use MabeEnumPHPStanTest\Assets\StrTypeEnum;
190+
191+
/** @param IntTypeEnum|StrTypeEnum $enum */
192+
function f($enum) {
193+
die;
194+
}
195+
CODE;
196+
197+
$this->processCode($code, '$enum->getValue()', "0|1|'str1'|'str2'", $this->extension);
198+
}
199+
200+
public function testMultiNonEnumClassMethod(): void
201+
{
202+
$code = <<<'CODE'
203+
<?php
204+
use MabeEnumPHPStanTest\Assets\IntTypeEnum;
205+
use MabeEnumPHPStanTest\Assets\NotAnEnum;
206+
207+
/** @param IntTypeEnum|NotAnEnum $enum */
208+
function f($enum) {
209+
die;
210+
}
211+
CODE;
212+
213+
$this->processCode($code, '$enum->getValue()', 'mixed', $this->extension);
214+
}
171215
}

0 commit comments

Comments
 (0)