Skip to content

Commit a0242e0

Browse files
committed
Type::getEnumCases()
1 parent 8144f4a commit a0242e0

24 files changed

+205
-47
lines changed

src/Analyser/TypeSpecifier.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
use PHPStan\Type\Constant\ConstantStringType;
4141
use PHPStan\Type\ConstantScalarType;
4242
use PHPStan\Type\ConstantType;
43-
use PHPStan\Type\Enum\EnumCaseObjectType;
4443
use PHPStan\Type\FloatType;
4544
use PHPStan\Type\FunctionTypeSpecifyingExtension;
4645
use PHPStan\Type\Generic\GenericClassStringType;
@@ -232,7 +231,7 @@ public function specifyTypesInCondition(
232231
$exprRightType = $scope->getType($expr->right);
233232
if (
234233
$exprLeftType instanceof ConstantScalarType
235-
|| $exprLeftType instanceof EnumCaseObjectType
234+
|| count($exprLeftType->getEnumCases()) === 1
236235
|| ($exprLeftType instanceof ConstantType && !$exprRightType->equals($exprLeftType) && $exprRightType->isSuperTypeOf($exprLeftType)->yes())
237236
) {
238237
$types = $this->create(
@@ -246,7 +245,7 @@ public function specifyTypesInCondition(
246245
}
247246
if (
248247
$exprRightType instanceof ConstantScalarType
249-
|| $exprRightType instanceof EnumCaseObjectType
248+
|| count($exprRightType->getEnumCases()) === 1
250249
|| ($exprRightType instanceof ConstantType && !$exprLeftType->equals($exprRightType) && $exprLeftType->isSuperTypeOf($exprRightType)->yes())
251250
) {
252251
$leftType = $this->create(

src/Rules/Comparison/MatchExpressionRule.php

Lines changed: 7 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,13 @@
99
use PHPStan\Rules\Rule;
1010
use PHPStan\Rules\RuleErrorBuilder;
1111
use PHPStan\Type\Constant\ConstantBooleanType;
12-
use PHPStan\Type\Enum\EnumCaseObjectType;
1312
use PHPStan\Type\NeverType;
1413
use PHPStan\Type\ObjectType;
15-
use PHPStan\Type\SubtractableType;
1614
use PHPStan\Type\TypeCombinator;
17-
use PHPStan\Type\TypeUtils;
18-
use PHPStan\Type\TypeWithClassName;
1915
use PHPStan\Type\UnionType;
2016
use PHPStan\Type\VerbosityLevel;
2117
use UnhandledMatchError;
22-
use function array_keys;
2318
use function array_map;
24-
use function array_values;
2519
use function count;
2620
use function sprintf;
2721

@@ -92,44 +86,13 @@ public function processNode(Node $node, Scope $scope): array
9286

9387
if (!$hasDefault && !$nextArmIsDead) {
9488
$remainingType = $node->getEndScope()->getType($matchCondition);
95-
if ($remainingType instanceof TypeWithClassName && $remainingType instanceof SubtractableType) {
96-
$subtractedType = $remainingType->getSubtractedType();
97-
if ($subtractedType !== null && $remainingType->getClassReflection() !== null) {
98-
$classReflection = $remainingType->getClassReflection();
99-
if ($classReflection->isEnum()) {
100-
$cases = [];
101-
foreach (array_keys($classReflection->getEnumCases()) as $name) {
102-
$cases[$name] = new EnumCaseObjectType($classReflection->getName(), $name);
103-
}
104-
105-
$subtractedTypes = TypeUtils::flattenTypes($subtractedType);
106-
$set = true;
107-
foreach ($subtractedTypes as $subType) {
108-
if (!$subType instanceof EnumCaseObjectType) {
109-
$set = false;
110-
break;
111-
}
112-
113-
if ($subType->getClassName() !== $classReflection->getName()) {
114-
$set = false;
115-
break;
116-
}
117-
118-
unset($cases[$subType->getEnumCaseName()]);
119-
}
120-
121-
$cases = array_values($cases);
122-
$casesCount = count($cases);
123-
if ($set) {
124-
if ($casesCount > 1) {
125-
$remainingType = new UnionType($cases);
126-
}
127-
if ($casesCount === 1) {
128-
$remainingType = $cases[0];
129-
}
130-
}
131-
}
132-
}
89+
$cases = $remainingType->getEnumCases();
90+
$casesCount = count($cases);
91+
if ($casesCount > 1) {
92+
$remainingType = new UnionType($cases);
93+
}
94+
if ($casesCount === 1) {
95+
$remainingType = $cases[0];
13396
}
13497
if (
13598
!$remainingType instanceof NeverType

src/Type/Accessory/HasMethodType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,11 @@ public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope)
143143
];
144144
}
145145

146+
public function getEnumCases(): array
147+
{
148+
return [];
149+
}
150+
146151
public function traverse(callable $cb): Type
147152
{
148153
return $this;

src/Type/Accessory/HasOffsetType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,11 @@ public function toArrayKey(): Type
284284
return new ErrorType();
285285
}
286286

287+
public function getEnumCases(): array
288+
{
289+
return [];
290+
}
291+
287292
public function traverse(callable $cb): Type
288293
{
289294
return $this;

src/Type/Accessory/HasOffsetValueType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,11 @@ public function toArrayKey(): Type
325325
return new ErrorType();
326326
}
327327

328+
public function getEnumCases(): array
329+
{
330+
return [];
331+
}
332+
328333
public function traverse(callable $cb): Type
329334
{
330335
$newValueType = $cb($this->valueType);

src/Type/Accessory/HasPropertyType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope)
104104
return [new TrivialParametersAcceptor()];
105105
}
106106

107+
public function getEnumCases(): array
108+
{
109+
return [];
110+
}
111+
107112
public function traverse(callable $cb): Type
108113
{
109114
return $this;

src/Type/CallableType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,11 @@ public function isScalar(): TrinaryLogic
397397
return TrinaryLogic::createMaybe();
398398
}
399399

400+
public function getEnumCases(): array
401+
{
402+
return [];
403+
}
404+
400405
public function isCommonCallable(): bool
401406
{
402407
return $this->isCommonCallable;

src/Type/ClosureType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,11 @@ public function isCallable(): TrinaryLogic
250250
return TrinaryLogic::createYes();
251251
}
252252

253+
public function getEnumCases(): array
254+
{
255+
return [];
256+
}
257+
253258
/**
254259
* @return ParametersAcceptor[]
255260
*/

src/Type/Enum/EnumCaseObjectType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,11 @@ public function isSmallerThanOrEqual(Type $otherType): TrinaryLogic
145145
return TrinaryLogic::createNo();
146146
}
147147

148+
public function getEnumCases(): array
149+
{
150+
return [$this];
151+
}
152+
148153
/**
149154
* @param mixed[] $properties
150155
*/

src/Type/IntersectionType.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,18 @@ public function shuffleArray(): Type
639639
return $this->intersectTypes(static fn (Type $type): Type => $type->shuffleArray());
640640
}
641641

642+
public function getEnumCases(): array
643+
{
644+
$enumCases = [];
645+
foreach ($this->types as $type) {
646+
foreach ($type->getEnumCases() as $enumCase) {
647+
$enumCases[] = $enumCase;
648+
}
649+
}
650+
651+
return $enumCases;
652+
}
653+
642654
public function isCallable(): TrinaryLogic
643655
{
644656
return $this->intersectResults(static fn (Type $type): TrinaryLogic => $type->isCallable());

0 commit comments

Comments
 (0)