From 4b9b05982e007ebbbc7976d909ef00431fb78870 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Mon, 7 Nov 2022 16:28:15 +0100 Subject: [PATCH] Implement getConstantStrings() on Type --- src/Analyser/MutatingScope.php | 2 +- src/Reflection/InitializerExprTypeResolver.php | 4 ++-- src/Rules/Classes/InstantiationRule.php | 2 +- src/Rules/DeadCode/UnusedPrivateMethodRule.php | 3 +-- src/Rules/DeadCode/UnusedPrivatePropertyRule.php | 3 +-- src/Rules/Functions/PrintfParametersRule.php | 3 +-- src/Rules/Properties/AccessPropertiesRule.php | 3 +-- .../Properties/AccessStaticPropertiesRule.php | 2 +- src/Rules/Properties/PropertyReflectionFinder.php | 5 ++--- src/Rules/Regexp/RegularExpressionPatternRule.php | 3 +-- src/Type/Accessory/AccessoryArrayListType.php | 5 +++++ src/Type/Accessory/AccessoryLiteralStringType.php | 5 +++++ src/Type/Accessory/AccessoryNonEmptyStringType.php | 5 +++++ src/Type/Accessory/AccessoryNonFalsyStringType.php | 5 +++++ src/Type/Accessory/AccessoryNumericStringType.php | 5 +++++ src/Type/Accessory/HasOffsetType.php | 5 +++++ src/Type/Accessory/HasOffsetValueType.php | 5 +++++ src/Type/Accessory/HasPropertyType.php | 5 +++++ src/Type/Accessory/NonEmptyArrayType.php | 5 +++++ src/Type/Accessory/OversizedArrayType.php | 5 +++++ src/Type/BooleanType.php | 5 +++++ src/Type/CallableType.php | 5 +++++ src/Type/ClosureType.php | 5 +++++ src/Type/Constant/ConstantStringType.php | 5 +++++ src/Type/FloatType.php | 5 +++++ src/Type/IntegerType.php | 5 +++++ src/Type/IntersectionType.php | 5 +++++ src/Type/IterableType.php | 5 +++++ src/Type/MixedType.php | 5 +++++ src/Type/NeverType.php | 5 +++++ src/Type/NonexistentParentClassType.php | 8 +++++++- src/Type/NullType.php | 5 +++++ src/Type/ObjectType.php | 5 +++++ .../Php/ArrayColumnFunctionReturnTypeExtension.php | 3 +-- src/Type/Php/DateFunctionReturnTypeExtension.php | 3 +-- .../DateIntervalConstructorThrowTypeExtension.php | 3 +-- .../Php/DateTimeConstructorThrowTypeExtension.php | 3 +-- src/Type/Php/DateTimeModifyReturnTypeExtension.php | 3 +-- ...rentClassDynamicFunctionReturnTypeExtension.php | 2 +- src/Type/Php/HashFunctionsReturnTypeExtension.php | 2 +- src/Type/Php/MbFunctionsReturnTypeExtension.php | 3 +-- .../Php/MbStrlenFunctionReturnTypeExtension.php | 2 +- ...ectionFunctionConstructorThrowTypeExtension.php | 3 +-- ...flectionMethodConstructorThrowTypeExtension.php | 4 ++-- ...ectionPropertyConstructorThrowTypeExtension.php | 7 +++---- ...mpleXMLElementConstructorThrowTypeExtension.php | 3 +-- ...pleXMLElementXpathMethodReturnTypeExtension.php | 3 +-- .../Php/StrCaseFunctionsReturnTypeExtension.php | 4 ++-- .../Php/StrSplitFunctionReturnTypeExtension.php | 3 +-- .../Php/StrtotimeFunctionReturnTypeExtension.php | 2 +- src/Type/Php/SubstrDynamicReturnTypeExtension.php | 3 +-- ...onCompareFunctionDynamicReturnTypeExtension.php | 7 +++---- src/Type/ResourceType.php | 5 +++++ src/Type/StaticType.php | 5 +++++ src/Type/StrictMixedType.php | 5 +++++ src/Type/StringType.php | 5 +++++ src/Type/Traits/LateResolvableTypeTrait.php | 5 +++++ src/Type/Traits/NonObjectTypeTrait.php | 5 +++++ src/Type/Traits/ObjectTypeTrait.php | 5 +++++ src/Type/Type.php | 4 ++++ src/Type/TypeUtils.php | 2 ++ src/Type/UnionType.php | 5 +++++ src/Type/UnionTypeHelper.php | 14 ++++++++++++++ 63 files changed, 214 insertions(+), 57 deletions(-) diff --git a/src/Analyser/MutatingScope.php b/src/Analyser/MutatingScope.php index 46e7c6dc41a..98e1c8b4b56 100644 --- a/src/Analyser/MutatingScope.php +++ b/src/Analyser/MutatingScope.php @@ -2957,7 +2957,7 @@ private function expressionTypeIsUnchangeable(ExpressionTypeHolder $typeHolder): && $expr->name instanceof FullyQualified && $expr->name->toLowerString() === 'function_exists' && isset($expr->getArgs()[0]) - && count(TypeUtils::getConstantStrings($this->getType($expr->getArgs()[0]->value))) === 1 + && count($this->getType($expr->getArgs()[0]->value)->getConstantStrings()) === 1 && (new ConstantBooleanType(true))->isSuperTypeOf($type)->yes(); } diff --git a/src/Reflection/InitializerExprTypeResolver.php b/src/Reflection/InitializerExprTypeResolver.php index b3d49df16e1..0d56aeeb3fd 100644 --- a/src/Reflection/InitializerExprTypeResolver.php +++ b/src/Reflection/InitializerExprTypeResolver.php @@ -376,7 +376,7 @@ public function getConcatType(Expr $left, Expr $right, callable $getTypeCallback // we limit the number of union-types for performance reasons if ($leftStringType instanceof UnionType && count($leftStringType->getTypes()) <= 16 && $rightStringType instanceof ConstantStringType) { - $constantStrings = TypeUtils::getConstantStrings($leftStringType); + $constantStrings = $leftStringType->getConstantStrings(); if (count($constantStrings) > 0) { $strings = []; foreach ($constantStrings as $constantString) { @@ -391,7 +391,7 @@ public function getConcatType(Expr $left, Expr $right, callable $getTypeCallback } } if ($rightStringType instanceof UnionType && count($rightStringType->getTypes()) <= 16 && $leftStringType instanceof ConstantStringType) { - $constantStrings = TypeUtils::getConstantStrings($rightStringType); + $constantStrings = $rightStringType->getConstantStrings(); if (count($constantStrings) > 0) { $strings = []; foreach ($constantStrings as $constantString) { diff --git a/src/Rules/Classes/InstantiationRule.php b/src/Rules/Classes/InstantiationRule.php index ce2ff2920b8..4adfdacda60 100644 --- a/src/Rules/Classes/InstantiationRule.php +++ b/src/Rules/Classes/InstantiationRule.php @@ -234,7 +234,7 @@ private function getClassNames(Node $node, Scope $scope): array return array_merge( array_map( static fn (ConstantStringType $type): array => [$type->getValue(), true], - TypeUtils::getConstantStrings($type), + $type->getConstantStrings(), ), array_map( static fn (string $name): array => [$name, false], diff --git a/src/Rules/DeadCode/UnusedPrivateMethodRule.php b/src/Rules/DeadCode/UnusedPrivateMethodRule.php index 84709f06a83..e7b8660b8b7 100644 --- a/src/Rules/DeadCode/UnusedPrivateMethodRule.php +++ b/src/Rules/DeadCode/UnusedPrivateMethodRule.php @@ -14,7 +14,6 @@ use PHPStan\Type\Constant\ConstantStringType; use PHPStan\Type\MixedType; use PHPStan\Type\ObjectType; -use PHPStan\Type\TypeUtils; use function array_map; use function count; use function sprintf; @@ -76,7 +75,7 @@ public function processNode(Node $node, Scope $scope): array $methodNames = [$methodCallNode->name->toString()]; } else { $methodNameType = $callScope->getType($methodCallNode->name); - $strings = TypeUtils::getConstantStrings($methodNameType); + $strings = $methodNameType->getConstantStrings(); if (count($strings) === 0) { return []; } diff --git a/src/Rules/DeadCode/UnusedPrivatePropertyRule.php b/src/Rules/DeadCode/UnusedPrivatePropertyRule.php index a829883b142..c5e12e547d9 100644 --- a/src/Rules/DeadCode/UnusedPrivatePropertyRule.php +++ b/src/Rules/DeadCode/UnusedPrivatePropertyRule.php @@ -13,7 +13,6 @@ use PHPStan\Type\Constant\ConstantStringType; use PHPStan\Type\MixedType; use PHPStan\Type\ObjectType; -use PHPStan\Type\TypeUtils; use function array_key_exists; use function array_map; use function count; @@ -125,7 +124,7 @@ public function processNode(Node $node, Scope $scope): array $propertyNames = [$fetch->name->toString()]; } else { $propertyNameType = $usage->getScope()->getType($fetch->name); - $strings = TypeUtils::getConstantStrings($propertyNameType); + $strings = $propertyNameType->getConstantStrings(); if (count($strings) === 0) { return []; } diff --git a/src/Rules/Functions/PrintfParametersRule.php b/src/Rules/Functions/PrintfParametersRule.php index b6f0552b653..10d2e8eb459 100644 --- a/src/Rules/Functions/PrintfParametersRule.php +++ b/src/Rules/Functions/PrintfParametersRule.php @@ -9,7 +9,6 @@ use PHPStan\Php\PhpVersion; use PHPStan\Rules\Rule; use PHPStan\Rules\RuleErrorBuilder; -use PHPStan\Type\TypeUtils; use function array_filter; use function count; use function in_array; @@ -73,7 +72,7 @@ public function processNode(Node $node, Scope $scope): array $formatArgType = $scope->getType($args[$formatArgumentPosition]->value); $placeHoldersCount = null; - foreach (TypeUtils::getConstantStrings($formatArgType) as $formatString) { + foreach ($formatArgType->getConstantStrings() as $formatString) { $format = $formatString->getValue(); $tempPlaceHoldersCount = $this->getPlaceholdersCount($name, $format); if ($placeHoldersCount === null) { diff --git a/src/Rules/Properties/AccessPropertiesRule.php b/src/Rules/Properties/AccessPropertiesRule.php index 98bde4599b0..94180928496 100644 --- a/src/Rules/Properties/AccessPropertiesRule.php +++ b/src/Rules/Properties/AccessPropertiesRule.php @@ -16,7 +16,6 @@ use PHPStan\Type\Constant\ConstantStringType; use PHPStan\Type\ErrorType; use PHPStan\Type\Type; -use PHPStan\Type\TypeUtils; use PHPStan\Type\VerbosityLevel; use function array_map; use function array_merge; @@ -48,7 +47,7 @@ public function processNode(Node $node, Scope $scope): array if ($node->name instanceof Identifier) { $names = [$node->name->name]; } else { - $names = array_map(static fn (ConstantStringType $type): string => $type->getValue(), TypeUtils::getConstantStrings($scope->getType($node->name))); + $names = array_map(static fn (ConstantStringType $type): string => $type->getValue(), $scope->getType($node->name)->getConstantStrings()); } $errors = []; diff --git a/src/Rules/Properties/AccessStaticPropertiesRule.php b/src/Rules/Properties/AccessStaticPropertiesRule.php index eae90649d0d..851984016fb 100644 --- a/src/Rules/Properties/AccessStaticPropertiesRule.php +++ b/src/Rules/Properties/AccessStaticPropertiesRule.php @@ -54,7 +54,7 @@ public function processNode(Node $node, Scope $scope): array if ($node->name instanceof Node\VarLikeIdentifier) { $names = [$node->name->name]; } else { - $names = array_map(static fn (ConstantStringType $type): string => $type->getValue(), TypeUtils::getConstantStrings($scope->getType($node->name))); + $names = array_map(static fn (ConstantStringType $type): string => $type->getValue(), $scope->getType($node->name)->getConstantStrings()); } $errors = []; diff --git a/src/Rules/Properties/PropertyReflectionFinder.php b/src/Rules/Properties/PropertyReflectionFinder.php index 1dd0cc47482..3f6cc8b000a 100644 --- a/src/Rules/Properties/PropertyReflectionFinder.php +++ b/src/Rules/Properties/PropertyReflectionFinder.php @@ -9,7 +9,6 @@ use PHPStan\Analyser\Scope; use PHPStan\Type\Constant\ConstantStringType; use PHPStan\Type\Type; -use PHPStan\Type\TypeUtils; use function array_map; class PropertyReflectionFinder @@ -25,7 +24,7 @@ public function findPropertyReflectionsFromNode($propertyFetch, Scope $scope): a if ($propertyFetch->name instanceof Node\Identifier) { $names = [$propertyFetch->name->name]; } else { - $names = array_map(static fn (ConstantStringType $name): string => $name->getValue(), TypeUtils::getConstantStrings($scope->getType($propertyFetch->name))); + $names = array_map(static fn (ConstantStringType $name): string => $name->getValue(), $scope->getType($propertyFetch->name)->getConstantStrings()); } $reflections = []; @@ -58,7 +57,7 @@ public function findPropertyReflectionsFromNode($propertyFetch, Scope $scope): a if ($propertyFetch->name instanceof VarLikeIdentifier) { $names = [$propertyFetch->name->name]; } else { - $names = array_map(static fn (ConstantStringType $name): string => $name->getValue(), TypeUtils::getConstantStrings($scope->getType($propertyFetch->name))); + $names = array_map(static fn (ConstantStringType $name): string => $name->getValue(), $scope->getType($propertyFetch->name)->getConstantStrings()); } $reflections = []; diff --git a/src/Rules/Regexp/RegularExpressionPatternRule.php b/src/Rules/Regexp/RegularExpressionPatternRule.php index 56da7deda1f..9d6c9a18513 100644 --- a/src/Rules/Regexp/RegularExpressionPatternRule.php +++ b/src/Rules/Regexp/RegularExpressionPatternRule.php @@ -10,7 +10,6 @@ use PHPStan\Rules\Rule; use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Type\Constant\ConstantStringType; -use PHPStan\Type\TypeUtils; use function in_array; use function sprintf; use function str_starts_with; @@ -65,7 +64,7 @@ private function extractPatterns(FuncCall $functionCall, Scope $scope): array $patternStrings = []; - foreach (TypeUtils::getConstantStrings($patternType) as $constantStringType) { + foreach ($patternType->getConstantStrings() as $constantStringType) { if ( !in_array($functionName, [ 'preg_match', diff --git a/src/Type/Accessory/AccessoryArrayListType.php b/src/Type/Accessory/AccessoryArrayListType.php index c132d9329a1..bc166485c61 100644 --- a/src/Type/Accessory/AccessoryArrayListType.php +++ b/src/Type/Accessory/AccessoryArrayListType.php @@ -55,6 +55,11 @@ public function getConstantArrays(): array return []; } + public function getConstantStrings(): array + { + return []; + } + public function accepts(Type $type, bool $strictTypes): TrinaryLogic { if ($type instanceof CompoundType) { diff --git a/src/Type/Accessory/AccessoryLiteralStringType.php b/src/Type/Accessory/AccessoryLiteralStringType.php index 07369b9893c..1414e742a29 100644 --- a/src/Type/Accessory/AccessoryLiteralStringType.php +++ b/src/Type/Accessory/AccessoryLiteralStringType.php @@ -46,6 +46,11 @@ public function getReferencedClasses(): array return []; } + public function getConstantStrings(): array + { + return []; + } + public function accepts(Type $type, bool $strictTypes): TrinaryLogic { if ($type instanceof MixedType) { diff --git a/src/Type/Accessory/AccessoryNonEmptyStringType.php b/src/Type/Accessory/AccessoryNonEmptyStringType.php index 1a1ce0f17e3..f2cabcff5ff 100644 --- a/src/Type/Accessory/AccessoryNonEmptyStringType.php +++ b/src/Type/Accessory/AccessoryNonEmptyStringType.php @@ -46,6 +46,11 @@ public function getReferencedClasses(): array return []; } + public function getConstantStrings(): array + { + return []; + } + public function accepts(Type $type, bool $strictTypes): TrinaryLogic { if ($type instanceof CompoundType) { diff --git a/src/Type/Accessory/AccessoryNonFalsyStringType.php b/src/Type/Accessory/AccessoryNonFalsyStringType.php index 97276352e11..f5550393b24 100644 --- a/src/Type/Accessory/AccessoryNonFalsyStringType.php +++ b/src/Type/Accessory/AccessoryNonFalsyStringType.php @@ -47,6 +47,11 @@ public function getReferencedClasses(): array return []; } + public function getConstantStrings(): array + { + return []; + } + public function accepts(Type $type, bool $strictTypes): TrinaryLogic { if ($type instanceof CompoundType) { diff --git a/src/Type/Accessory/AccessoryNumericStringType.php b/src/Type/Accessory/AccessoryNumericStringType.php index 8a4ad974a9c..6ed189cd8df 100644 --- a/src/Type/Accessory/AccessoryNumericStringType.php +++ b/src/Type/Accessory/AccessoryNumericStringType.php @@ -46,6 +46,11 @@ public function getReferencedClasses(): array return []; } + public function getConstantStrings(): array + { + return []; + } + public function accepts(Type $type, bool $strictTypes): TrinaryLogic { if ($type instanceof CompoundType) { diff --git a/src/Type/Accessory/HasOffsetType.php b/src/Type/Accessory/HasOffsetType.php index 2bf723e0e42..be1b778f6d2 100644 --- a/src/Type/Accessory/HasOffsetType.php +++ b/src/Type/Accessory/HasOffsetType.php @@ -58,6 +58,11 @@ public function getReferencedClasses(): array return []; } + public function getConstantStrings(): array + { + return []; + } + public function accepts(Type $type, bool $strictTypes): TrinaryLogic { if ($type instanceof CompoundType) { diff --git a/src/Type/Accessory/HasOffsetValueType.php b/src/Type/Accessory/HasOffsetValueType.php index 05b3e293247..d649a04e3a1 100644 --- a/src/Type/Accessory/HasOffsetValueType.php +++ b/src/Type/Accessory/HasOffsetValueType.php @@ -57,6 +57,11 @@ public function getReferencedClasses(): array return []; } + public function getConstantStrings(): array + { + return []; + } + public function accepts(Type $type, bool $strictTypes): TrinaryLogic { if ($type instanceof CompoundType) { diff --git a/src/Type/Accessory/HasPropertyType.php b/src/Type/Accessory/HasPropertyType.php index 1d650578788..8793c2f4cee 100644 --- a/src/Type/Accessory/HasPropertyType.php +++ b/src/Type/Accessory/HasPropertyType.php @@ -39,6 +39,11 @@ public function getReferencedClasses(): array return []; } + public function getConstantStrings(): array + { + return []; + } + public function getPropertyName(): string { return $this->propertyName; diff --git a/src/Type/Accessory/NonEmptyArrayType.php b/src/Type/Accessory/NonEmptyArrayType.php index c4df2cbbbd8..94746d3b4af 100644 --- a/src/Type/Accessory/NonEmptyArrayType.php +++ b/src/Type/Accessory/NonEmptyArrayType.php @@ -52,6 +52,11 @@ public function getConstantArrays(): array return []; } + public function getConstantStrings(): array + { + return []; + } + public function accepts(Type $type, bool $strictTypes): TrinaryLogic { if ($type instanceof CompoundType) { diff --git a/src/Type/Accessory/OversizedArrayType.php b/src/Type/Accessory/OversizedArrayType.php index 88bfcdd276a..e216e7a4447 100644 --- a/src/Type/Accessory/OversizedArrayType.php +++ b/src/Type/Accessory/OversizedArrayType.php @@ -51,6 +51,11 @@ public function getConstantArrays(): array return []; } + public function getConstantStrings(): array + { + return []; + } + public function accepts(Type $type, bool $strictTypes): TrinaryLogic { if ($type instanceof CompoundType) { diff --git a/src/Type/BooleanType.php b/src/Type/BooleanType.php index 3dee7d71c87..4859bb202f5 100644 --- a/src/Type/BooleanType.php +++ b/src/Type/BooleanType.php @@ -38,6 +38,11 @@ public function __construct() { } + public function getConstantStrings(): array + { + return []; + } + public function describe(VerbosityLevel $level): string { return 'bool'; diff --git a/src/Type/CallableType.php b/src/Type/CallableType.php index a1f54edf263..8421f0247a0 100644 --- a/src/Type/CallableType.php +++ b/src/Type/CallableType.php @@ -74,6 +74,11 @@ public function getReferencedClasses(): array return array_merge($classes, $this->returnType->getReferencedClasses()); } + public function getConstantStrings(): array + { + return []; + } + public function accepts(Type $type, bool $strictTypes): TrinaryLogic { if ($type instanceof CompoundType && !$type instanceof self) { diff --git a/src/Type/ClosureType.php b/src/Type/ClosureType.php index 9ae57b480f0..8dff3317135 100644 --- a/src/Type/ClosureType.php +++ b/src/Type/ClosureType.php @@ -230,6 +230,11 @@ public function getConstant(string $constantName): ConstantReflection return $this->objectType->getConstant($constantName); } + public function getConstantStrings(): array + { + return []; + } + public function isIterable(): TrinaryLogic { return TrinaryLogic::createNo(); diff --git a/src/Type/Constant/ConstantStringType.php b/src/Type/Constant/ConstantStringType.php index 67bf2fbddd4..a35ec89c2a2 100644 --- a/src/Type/Constant/ConstantStringType.php +++ b/src/Type/Constant/ConstantStringType.php @@ -64,6 +64,11 @@ public function getValue(): string return $this->value; } + public function getConstantStrings(): array + { + return [$this]; + } + public function isClassStringType(): TrinaryLogic { if ($this->isClassString) { diff --git a/src/Type/FloatType.php b/src/Type/FloatType.php index fd53b13a6ff..0201b98f56b 100644 --- a/src/Type/FloatType.php +++ b/src/Type/FloatType.php @@ -46,6 +46,11 @@ public function getReferencedClasses(): array return []; } + public function getConstantStrings(): array + { + return []; + } + public function accepts(Type $type, bool $strictTypes): TrinaryLogic { if ($type instanceof self || $type->isInteger()->yes()) { diff --git a/src/Type/IntegerType.php b/src/Type/IntegerType.php index f97c7456f89..d0cdf9fee61 100644 --- a/src/Type/IntegerType.php +++ b/src/Type/IntegerType.php @@ -41,6 +41,11 @@ public function describe(VerbosityLevel $level): string return 'int'; } + public function getConstantStrings(): array + { + return []; + } + /** * @param mixed[] $properties */ diff --git a/src/Type/IntersectionType.php b/src/Type/IntersectionType.php index 9a0c7299a86..4f953e8cd44 100644 --- a/src/Type/IntersectionType.php +++ b/src/Type/IntersectionType.php @@ -111,6 +111,11 @@ public function getConstantArrays(): array return UnionTypeHelper::getConstantArrays($this->getTypes()); } + public function getConstantStrings(): array + { + return UnionTypeHelper::getConstantStrings($this->getTypes()); + } + public function accepts(Type $otherType, bool $strictTypes): TrinaryLogic { foreach ($this->types as $type) { diff --git a/src/Type/IterableType.php b/src/Type/IterableType.php index 57701731f86..e4bb2e39e4d 100644 --- a/src/Type/IterableType.php +++ b/src/Type/IterableType.php @@ -60,6 +60,11 @@ public function getReferencedClasses(): array ); } + public function getConstantStrings(): array + { + return []; + } + public function accepts(Type $type, bool $strictTypes): TrinaryLogic { if ($type->isConstantArray()->yes() && $type->isIterableAtLeastOnce()->no()) { diff --git a/src/Type/MixedType.php b/src/Type/MixedType.php index 0274f36cc3b..56027a8bc88 100644 --- a/src/Type/MixedType.php +++ b/src/Type/MixedType.php @@ -73,6 +73,11 @@ public function getConstantArrays(): array return []; } + public function getConstantStrings(): array + { + return []; + } + public function accepts(Type $type, bool $strictTypes): TrinaryLogic { return TrinaryLogic::createYes(); diff --git a/src/Type/NeverType.php b/src/Type/NeverType.php index 38b824168c1..e6ce12d7d5d 100644 --- a/src/Type/NeverType.php +++ b/src/Type/NeverType.php @@ -56,6 +56,11 @@ public function getConstantArrays(): array return []; } + public function getConstantStrings(): array + { + return []; + } + public function accepts(Type $type, bool $strictTypes): TrinaryLogic { return TrinaryLogic::createYes(); diff --git a/src/Type/NonexistentParentClassType.php b/src/Type/NonexistentParentClassType.php index b36f76663b7..b9ea4ab7198 100644 --- a/src/Type/NonexistentParentClassType.php +++ b/src/Type/NonexistentParentClassType.php @@ -20,7 +20,8 @@ use PHPStan\Type\Traits\TruthyBooleanTypeTrait; use PHPStan\Type\Traits\UndecidedComparisonTypeTrait; -class NonexistentParentClassType implements Type +class +NonexistentParentClassType implements Type { use JustNullableTypeTrait; @@ -94,6 +95,11 @@ public function getConstant(string $constantName): ConstantReflection throw new ShouldNotHappenException(); } + public function getConstantStrings(): array + { + return []; + } + public function isCloneable(): TrinaryLogic { return TrinaryLogic::createNo(); diff --git a/src/Type/NullType.php b/src/Type/NullType.php index c803e9bc4c9..01185347615 100644 --- a/src/Type/NullType.php +++ b/src/Type/NullType.php @@ -41,6 +41,11 @@ public function getReferencedClasses(): array return []; } + public function getConstantStrings(): array + { + return []; + } + /** * @return null */ diff --git a/src/Type/ObjectType.php b/src/Type/ObjectType.php index 1319d2448b0..fee760ca5a5 100644 --- a/src/Type/ObjectType.php +++ b/src/Type/ObjectType.php @@ -711,6 +711,11 @@ public function getConstant(string $constantName): ConstantReflection return $class->getConstant($constantName); } + public function getConstantStrings(): array + { + return []; + } + public function isIterable(): TrinaryLogic { return $this->isInstanceOf(Traversable::class); diff --git a/src/Type/Php/ArrayColumnFunctionReturnTypeExtension.php b/src/Type/Php/ArrayColumnFunctionReturnTypeExtension.php index 78c26cacf31..bf89efb9495 100644 --- a/src/Type/Php/ArrayColumnFunctionReturnTypeExtension.php +++ b/src/Type/Php/ArrayColumnFunctionReturnTypeExtension.php @@ -21,7 +21,6 @@ use PHPStan\Type\NullType; use PHPStan\Type\Type; use PHPStan\Type\TypeCombinator; -use PHPStan\Type\TypeUtils; use function count; class ArrayColumnFunctionReturnTypeExtension implements DynamicFunctionReturnTypeExtension @@ -157,7 +156,7 @@ private function getOffsetOrProperty(Type $type, Type $offsetOrProperty, Scope $ } if (!$type->canAccessProperties()->no()) { - $propertyTypes = TypeUtils::getConstantStrings($offsetOrProperty); + $propertyTypes = $offsetOrProperty->getConstantStrings(); if ($propertyTypes === []) { return new MixedType(); } diff --git a/src/Type/Php/DateFunctionReturnTypeExtension.php b/src/Type/Php/DateFunctionReturnTypeExtension.php index a10f66b6e53..2147fd1b80b 100644 --- a/src/Type/Php/DateFunctionReturnTypeExtension.php +++ b/src/Type/Php/DateFunctionReturnTypeExtension.php @@ -14,7 +14,6 @@ use PHPStan\Type\StringType; use PHPStan\Type\Type; use PHPStan\Type\TypeCombinator; -use PHPStan\Type\TypeUtils; use PHPStan\Type\UnionType; use function count; use function date; @@ -38,7 +37,7 @@ public function getTypeFromFunctionCall( return new StringType(); } $argType = $scope->getType($functionCall->getArgs()[0]->value); - $constantStrings = TypeUtils::getConstantStrings($argType); + $constantStrings = $argType->getConstantStrings(); if (count($constantStrings) === 0) { return new StringType(); diff --git a/src/Type/Php/DateIntervalConstructorThrowTypeExtension.php b/src/Type/Php/DateIntervalConstructorThrowTypeExtension.php index e7fda0fa2c4..746fa0f2f5b 100644 --- a/src/Type/Php/DateIntervalConstructorThrowTypeExtension.php +++ b/src/Type/Php/DateIntervalConstructorThrowTypeExtension.php @@ -10,7 +10,6 @@ use PHPStan\Type\NeverType; use PHPStan\Type\Type; use PHPStan\Type\TypeCombinator; -use PHPStan\Type\TypeUtils; use function count; class DateIntervalConstructorThrowTypeExtension implements DynamicStaticMethodThrowTypeExtension @@ -28,7 +27,7 @@ public function getThrowTypeFromStaticMethodCall(MethodReflection $methodReflect } $valueType = $scope->getType($methodCall->getArgs()[0]->value); - $constantStrings = TypeUtils::getConstantStrings($valueType); + $constantStrings = $valueType->getConstantStrings(); foreach ($constantStrings as $constantString) { try { diff --git a/src/Type/Php/DateTimeConstructorThrowTypeExtension.php b/src/Type/Php/DateTimeConstructorThrowTypeExtension.php index c84512c05a7..d69fad1ef34 100644 --- a/src/Type/Php/DateTimeConstructorThrowTypeExtension.php +++ b/src/Type/Php/DateTimeConstructorThrowTypeExtension.php @@ -11,7 +11,6 @@ use PHPStan\Type\NeverType; use PHPStan\Type\Type; use PHPStan\Type\TypeCombinator; -use PHPStan\Type\TypeUtils; use function count; use function in_array; @@ -30,7 +29,7 @@ public function getThrowTypeFromStaticMethodCall(MethodReflection $methodReflect } $valueType = $scope->getType($methodCall->getArgs()[0]->value); - $constantStrings = TypeUtils::getConstantStrings($valueType); + $constantStrings = $valueType->getConstantStrings(); foreach ($constantStrings as $constantString) { try { diff --git a/src/Type/Php/DateTimeModifyReturnTypeExtension.php b/src/Type/Php/DateTimeModifyReturnTypeExtension.php index 937ce2fd274..7fbd70ed71a 100644 --- a/src/Type/Php/DateTimeModifyReturnTypeExtension.php +++ b/src/Type/Php/DateTimeModifyReturnTypeExtension.php @@ -12,7 +12,6 @@ use PHPStan\Type\NeverType; use PHPStan\Type\Type; use PHPStan\Type\TypeCombinator; -use PHPStan\Type\TypeUtils; use function count; class DateTimeModifyReturnTypeExtension implements DynamicMethodReturnTypeExtension @@ -44,7 +43,7 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method } $valueType = $scope->getType($methodCall->getArgs()[0]->value); - $constantStrings = TypeUtils::getConstantStrings($valueType); + $constantStrings = $valueType->getConstantStrings(); $hasFalse = false; $hasDateTime = false; diff --git a/src/Type/Php/GetParentClassDynamicFunctionReturnTypeExtension.php b/src/Type/Php/GetParentClassDynamicFunctionReturnTypeExtension.php index 2ba8086d477..cb0e9e79d5f 100644 --- a/src/Type/Php/GetParentClassDynamicFunctionReturnTypeExtension.php +++ b/src/Type/Php/GetParentClassDynamicFunctionReturnTypeExtension.php @@ -60,7 +60,7 @@ public function getTypeFromFunctionCall( return $defaultReturnType; } - $constantStrings = TypeUtils::getConstantStrings($argType); + $constantStrings = $argType->getConstantStrings(); if (count($constantStrings) > 0) { return TypeCombinator::union(...array_map(fn (ConstantStringType $stringType): Type => $this->findParentClassNameType($stringType->getValue()), $constantStrings)); } diff --git a/src/Type/Php/HashFunctionsReturnTypeExtension.php b/src/Type/Php/HashFunctionsReturnTypeExtension.php index a1c6d2e06ec..72b26d3dd50 100644 --- a/src/Type/Php/HashFunctionsReturnTypeExtension.php +++ b/src/Type/Php/HashFunctionsReturnTypeExtension.php @@ -99,7 +99,7 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection, return TypeUtils::toBenevolentUnion($defaultReturnType); } - $constantAlgorithmTypes = TypeUtils::getConstantStrings($algorithmType); + $constantAlgorithmTypes = $algorithmType->getConstantStrings(); if ($constantAlgorithmTypes === []) { return TypeUtils::toBenevolentUnion($defaultReturnType); diff --git a/src/Type/Php/MbFunctionsReturnTypeExtension.php b/src/Type/Php/MbFunctionsReturnTypeExtension.php index f0bf08dff05..13f8d238b08 100644 --- a/src/Type/Php/MbFunctionsReturnTypeExtension.php +++ b/src/Type/Php/MbFunctionsReturnTypeExtension.php @@ -15,7 +15,6 @@ use PHPStan\Type\StringType; use PHPStan\Type\Type; use PHPStan\Type\TypeCombinator; -use PHPStan\Type\TypeUtils; use PHPStan\Type\UnionType; use function array_key_exists; use function array_map; @@ -55,7 +54,7 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection, return TypeCombinator::remove($returnType, new BooleanType()); } - $strings = TypeUtils::getConstantStrings($scope->getType($functionCall->getArgs()[$positionEncodingParam - 1]->value)); + $strings = $scope->getType($functionCall->getArgs()[$positionEncodingParam - 1]->value)->getConstantStrings(); $results = array_unique(array_map(fn (ConstantStringType $encoding): bool => $this->isSupportedEncoding($encoding->getValue()), $strings)); if ($returnType->equals(new UnionType([new StringType(), new BooleanType()]))) { diff --git a/src/Type/Php/MbStrlenFunctionReturnTypeExtension.php b/src/Type/Php/MbStrlenFunctionReturnTypeExtension.php index 5373ae15447..c6e78122786 100644 --- a/src/Type/Php/MbStrlenFunctionReturnTypeExtension.php +++ b/src/Type/Php/MbStrlenFunctionReturnTypeExtension.php @@ -70,7 +70,7 @@ public function getTypeFromFunctionCall( } elseif (count($functionCall->getArgs()) === 2) { // custom encoding is specified $encodings = array_map( static fn (ConstantStringType $t) => $t->getValue(), - TypeUtils::getConstantStrings($scope->getType($functionCall->getArgs()[1]->value)), + $scope->getType($functionCall->getArgs()[1]->value)->getConstantStrings(), ); } diff --git a/src/Type/Php/ReflectionFunctionConstructorThrowTypeExtension.php b/src/Type/Php/ReflectionFunctionConstructorThrowTypeExtension.php index 7dd3ba3e224..078301bb121 100644 --- a/src/Type/Php/ReflectionFunctionConstructorThrowTypeExtension.php +++ b/src/Type/Php/ReflectionFunctionConstructorThrowTypeExtension.php @@ -11,7 +11,6 @@ use PHPStan\Type\NeverType; use PHPStan\Type\Type; use PHPStan\Type\TypeCombinator; -use PHPStan\Type\TypeUtils; use ReflectionFunction; use function count; @@ -34,7 +33,7 @@ public function getThrowTypeFromStaticMethodCall(MethodReflection $methodReflect } $valueType = $scope->getType($methodCall->getArgs()[0]->value); - foreach (TypeUtils::getConstantStrings($valueType) as $constantString) { + foreach ($valueType->getConstantStrings() as $constantString) { if (!$this->reflectionProvider->hasFunction(new Name($constantString->getValue()), $scope)) { return $methodReflection->getThrowType(); } diff --git a/src/Type/Php/ReflectionMethodConstructorThrowTypeExtension.php b/src/Type/Php/ReflectionMethodConstructorThrowTypeExtension.php index 18890c42368..5ce43b87876 100644 --- a/src/Type/Php/ReflectionMethodConstructorThrowTypeExtension.php +++ b/src/Type/Php/ReflectionMethodConstructorThrowTypeExtension.php @@ -50,7 +50,7 @@ public function getThrowTypeFromStaticMethodCall(MethodReflection $methodReflect foreach ($classes as $class) { $classReflection = $this->reflectionProvider->getClass($class); - foreach (TypeUtils::getConstantStrings($propertyType) as $constantPropertyString) { + foreach ($propertyType->getConstantStrings() as $constantPropertyString) { if (!$classReflection->hasMethod($constantPropertyString->getValue())) { return $methodReflection->getThrowType(); } @@ -65,7 +65,7 @@ public function getThrowTypeFromStaticMethodCall(MethodReflection $methodReflect } // Look for non constantStrings value. - foreach (TypeUtils::getConstantStrings($propertyType) as $constantPropertyString) { + foreach ($propertyType->getConstantStrings() as $constantPropertyString) { $propertyType = TypeCombinator::remove($propertyType, $constantPropertyString); } diff --git a/src/Type/Php/ReflectionPropertyConstructorThrowTypeExtension.php b/src/Type/Php/ReflectionPropertyConstructorThrowTypeExtension.php index eed7c7d1151..098b3f1567e 100644 --- a/src/Type/Php/ReflectionPropertyConstructorThrowTypeExtension.php +++ b/src/Type/Php/ReflectionPropertyConstructorThrowTypeExtension.php @@ -10,7 +10,6 @@ use PHPStan\Type\NeverType; use PHPStan\Type\Type; use PHPStan\Type\TypeCombinator; -use PHPStan\Type\TypeUtils; use ReflectionProperty; use function count; @@ -34,13 +33,13 @@ public function getThrowTypeFromStaticMethodCall(MethodReflection $methodReflect $valueType = $scope->getType($methodCall->getArgs()[0]->value); $propertyType = $scope->getType($methodCall->getArgs()[1]->value); - foreach (TypeUtils::getConstantStrings($valueType) as $constantString) { + foreach ($valueType->getConstantStrings() as $constantString) { if (!$this->reflectionProvider->hasClass($constantString->getValue())) { return $methodReflection->getThrowType(); } $classReflection = $this->reflectionProvider->getClass($constantString->getValue()); - foreach (TypeUtils::getConstantStrings($propertyType) as $constantPropertyString) { + foreach ($propertyType->getConstantStrings() as $constantPropertyString) { if (!$classReflection->hasProperty($constantPropertyString->getValue())) { return $methodReflection->getThrowType(); } @@ -54,7 +53,7 @@ public function getThrowTypeFromStaticMethodCall(MethodReflection $methodReflect } // Look for non constantStrings value. - foreach (TypeUtils::getConstantStrings($propertyType) as $constantPropertyString) { + foreach ($propertyType->getConstantStrings() as $constantPropertyString) { $propertyType = TypeCombinator::remove($propertyType, $constantPropertyString); } diff --git a/src/Type/Php/SimpleXMLElementConstructorThrowTypeExtension.php b/src/Type/Php/SimpleXMLElementConstructorThrowTypeExtension.php index e7b8247870d..4d2d2906e6e 100644 --- a/src/Type/Php/SimpleXMLElementConstructorThrowTypeExtension.php +++ b/src/Type/Php/SimpleXMLElementConstructorThrowTypeExtension.php @@ -9,7 +9,6 @@ use PHPStan\Type\NeverType; use PHPStan\Type\Type; use PHPStan\Type\TypeCombinator; -use PHPStan\Type\TypeUtils; use SimpleXMLElement; use function count; @@ -28,7 +27,7 @@ public function getThrowTypeFromStaticMethodCall(MethodReflection $methodReflect } $valueType = $scope->getType($methodCall->getArgs()[0]->value); - $constantStrings = TypeUtils::getConstantStrings($valueType); + $constantStrings = $valueType->getConstantStrings(); foreach ($constantStrings as $constantString) { try { diff --git a/src/Type/Php/SimpleXMLElementXpathMethodReturnTypeExtension.php b/src/Type/Php/SimpleXMLElementXpathMethodReturnTypeExtension.php index 175cd703ed3..d9a7fefa341 100644 --- a/src/Type/Php/SimpleXMLElementXpathMethodReturnTypeExtension.php +++ b/src/Type/Php/SimpleXMLElementXpathMethodReturnTypeExtension.php @@ -12,7 +12,6 @@ use PHPStan\Type\NeverType; use PHPStan\Type\Type; use PHPStan\Type\TypeCombinator; -use PHPStan\Type\TypeUtils; use SimpleXMLElement; class SimpleXMLElementXpathMethodReturnTypeExtension implements DynamicMethodReturnTypeExtension @@ -38,7 +37,7 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method $xmlElement = new SimpleXMLElement(''); - foreach (TypeUtils::getConstantStrings($argType) as $constantString) { + foreach ($argType->getConstantStrings() as $constantString) { $result = @$xmlElement->xpath($constantString->getValue()); if ($result === false) { // We can't be sure since it's maybe a namespaced xpath diff --git a/src/Type/Php/StrCaseFunctionsReturnTypeExtension.php b/src/Type/Php/StrCaseFunctionsReturnTypeExtension.php index 6c1f6853302..411bb63e7df 100644 --- a/src/Type/Php/StrCaseFunctionsReturnTypeExtension.php +++ b/src/Type/Php/StrCaseFunctionsReturnTypeExtension.php @@ -71,13 +71,13 @@ public function getTypeFromFunctionCall( } elseif (in_array($fnName, ['ucwords', 'mb_convert_kana'], true)) { if (count($args) >= 2) { $modeType = $scope->getType($args[1]->value); - $modes = array_map(static fn ($mode) => $mode->getValue(), TypeUtils::getConstantStrings($modeType)); + $modes = array_map(static fn ($mode) => $mode->getValue(), $modeType->getConstantStrings()); } else { $modes = $fnName === 'mb_convert_kana' ? ['KV'] : [" \t\r\n\f\v"]; } } - $constantStrings = array_map(static fn ($type) => $type->getValue(), TypeUtils::getConstantStrings($argType)); + $constantStrings = array_map(static fn ($type) => $type->getValue(), $argType->getConstantStrings()); if (count($constantStrings) > 0 && mb_check_encoding($constantStrings, 'UTF-8')) { $strings = []; diff --git a/src/Type/Php/StrSplitFunctionReturnTypeExtension.php b/src/Type/Php/StrSplitFunctionReturnTypeExtension.php index a01d2485e3b..d64b1afa39d 100644 --- a/src/Type/Php/StrSplitFunctionReturnTypeExtension.php +++ b/src/Type/Php/StrSplitFunctionReturnTypeExtension.php @@ -22,7 +22,6 @@ use PHPStan\Type\Type; use PHPStan\Type\TypeCombinator; use PHPStan\Type\TypeTraverser; -use PHPStan\Type\TypeUtils; use PHPStan\Type\UnionType; use function array_map; use function array_unique; @@ -69,7 +68,7 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection, $encoding = null; if ($functionReflection->getName() === 'mb_str_split') { if (count($functionCall->getArgs()) >= 3) { - $strings = TypeUtils::getConstantStrings($scope->getType($functionCall->getArgs()[2]->value)); + $strings = $scope->getType($functionCall->getArgs()[2]->value)->getConstantStrings(); $values = array_unique(array_map(static fn (ConstantStringType $encoding): string => $encoding->getValue(), $strings)); if (count($values) !== 1) { diff --git a/src/Type/Php/StrtotimeFunctionReturnTypeExtension.php b/src/Type/Php/StrtotimeFunctionReturnTypeExtension.php index 304b5401d33..ef5e1af7871 100644 --- a/src/Type/Php/StrtotimeFunctionReturnTypeExtension.php +++ b/src/Type/Php/StrtotimeFunctionReturnTypeExtension.php @@ -39,7 +39,7 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection, if ($argType instanceof MixedType) { return TypeUtils::toBenevolentUnion($defaultReturnType); } - $results = array_unique(array_map(static fn (ConstantStringType $string): int|bool => strtotime($string->getValue()), TypeUtils::getConstantStrings($argType))); + $results = array_unique(array_map(static fn (ConstantStringType $string): int|bool => strtotime($string->getValue()), $argType->getConstantStrings())); $resultTypes = array_unique(array_map(static fn (int|bool $value): string => gettype($value), $results)); if (count($resultTypes) !== 1 || count($results) === 0) { diff --git a/src/Type/Php/SubstrDynamicReturnTypeExtension.php b/src/Type/Php/SubstrDynamicReturnTypeExtension.php index 1927ea8b630..7322564e573 100644 --- a/src/Type/Php/SubstrDynamicReturnTypeExtension.php +++ b/src/Type/Php/SubstrDynamicReturnTypeExtension.php @@ -17,7 +17,6 @@ use PHPStan\Type\StringType; use PHPStan\Type\Type; use PHPStan\Type\TypeCombinator; -use PHPStan\Type\TypeUtils; use function count; use function is_bool; use function substr; @@ -55,7 +54,7 @@ public function getTypeFromFunctionCall( $positiveLength = IntegerRangeType::fromInterval(1, null)->isSuperTypeOf($length)->yes(); } - $constantStrings = TypeUtils::getConstantStrings($string); + $constantStrings = $string->getConstantStrings(); if ( count($constantStrings) > 0 && $offset instanceof ConstantIntegerType diff --git a/src/Type/Php/VersionCompareFunctionDynamicReturnTypeExtension.php b/src/Type/Php/VersionCompareFunctionDynamicReturnTypeExtension.php index f695b20899c..bb03ba22faa 100644 --- a/src/Type/Php/VersionCompareFunctionDynamicReturnTypeExtension.php +++ b/src/Type/Php/VersionCompareFunctionDynamicReturnTypeExtension.php @@ -12,7 +12,6 @@ use PHPStan\Type\DynamicFunctionReturnTypeExtension; use PHPStan\Type\Type; use PHPStan\Type\TypeCombinator; -use PHPStan\Type\TypeUtils; use function array_filter; use function count; use function version_compare; @@ -35,15 +34,15 @@ public function getTypeFromFunctionCall( return ParametersAcceptorSelector::selectFromArgs($scope, $functionCall->getArgs(), $functionReflection->getVariants())->getReturnType(); } - $version1Strings = TypeUtils::getConstantStrings($scope->getType($functionCall->getArgs()[0]->value)); - $version2Strings = TypeUtils::getConstantStrings($scope->getType($functionCall->getArgs()[1]->value)); + $version1Strings = $scope->getType($functionCall->getArgs()[0]->value)->getConstantStrings(); + $version2Strings = $scope->getType($functionCall->getArgs()[1]->value)->getConstantStrings(); $counts = [ count($version1Strings), count($version2Strings), ]; if (isset($functionCall->getArgs()[2])) { - $operatorStrings = TypeUtils::getConstantStrings($scope->getType($functionCall->getArgs()[2]->value)); + $operatorStrings = $scope->getType($functionCall->getArgs()[2]->value)->getConstantStrings(); $counts[] = count($operatorStrings); $returnType = new BooleanType(); } else { diff --git a/src/Type/ResourceType.php b/src/Type/ResourceType.php index 115787ad47c..8a5022cb023 100644 --- a/src/Type/ResourceType.php +++ b/src/Type/ResourceType.php @@ -41,6 +41,11 @@ public function describe(VerbosityLevel $level): string return 'resource'; } + public function getConstantStrings(): array + { + return []; + } + public function toNumber(): Type { return new ErrorType(); diff --git a/src/Type/StaticType.php b/src/Type/StaticType.php index db9803bc48d..0ae747a4475 100644 --- a/src/Type/StaticType.php +++ b/src/Type/StaticType.php @@ -113,6 +113,11 @@ public function getConstantArrays(): array return $this->getStaticObjectType()->getConstantArrays(); } + public function getConstantStrings(): array + { + return $this->getStaticObjectType()->getConstantStrings(); + } + public function accepts(Type $type, bool $strictTypes): TrinaryLogic { if ($type instanceof CompoundType) { diff --git a/src/Type/StrictMixedType.php b/src/Type/StrictMixedType.php index 01db3d74dad..f50efe57b9a 100644 --- a/src/Type/StrictMixedType.php +++ b/src/Type/StrictMixedType.php @@ -33,6 +33,11 @@ public function getReferencedClasses(): array return []; } + public function getConstantStrings(): array + { + return []; + } + public function accepts(Type $type, bool $strictTypes): TrinaryLogic { return TrinaryLogic::createYes(); diff --git a/src/Type/StringType.php b/src/Type/StringType.php index 88b661c937b..169ac7a5ff8 100644 --- a/src/Type/StringType.php +++ b/src/Type/StringType.php @@ -41,6 +41,11 @@ public function describe(VerbosityLevel $level): string return 'string'; } + public function getConstantStrings(): array + { + return []; + } + public function isOffsetAccessible(): TrinaryLogic { return TrinaryLogic::createYes(); diff --git a/src/Type/Traits/LateResolvableTypeTrait.php b/src/Type/Traits/LateResolvableTypeTrait.php index fb1a74d93ea..000223f9699 100644 --- a/src/Type/Traits/LateResolvableTypeTrait.php +++ b/src/Type/Traits/LateResolvableTypeTrait.php @@ -31,6 +31,11 @@ public function getConstantArrays(): array return $this->resolve()->getConstantArrays(); } + public function getConstantStrings(): array + { + return $this->resolve()->getConstantStrings(); + } + public function accepts(Type $type, bool $strictTypes): TrinaryLogic { return $this->resolve()->accepts($type, $strictTypes); diff --git a/src/Type/Traits/NonObjectTypeTrait.php b/src/Type/Traits/NonObjectTypeTrait.php index ca2ca69d276..10d929ab447 100644 --- a/src/Type/Traits/NonObjectTypeTrait.php +++ b/src/Type/Traits/NonObjectTypeTrait.php @@ -69,6 +69,11 @@ public function getConstant(string $constantName): ConstantReflection throw new ShouldNotHappenException(); } + public function getConstantStrings(): array + { + return []; + } + public function isCloneable(): TrinaryLogic { return TrinaryLogic::createNo(); diff --git a/src/Type/Traits/ObjectTypeTrait.php b/src/Type/Traits/ObjectTypeTrait.php index a764609a5fa..a7289b3a73f 100644 --- a/src/Type/Traits/ObjectTypeTrait.php +++ b/src/Type/Traits/ObjectTypeTrait.php @@ -96,6 +96,11 @@ public function getConstant(string $constantName): ConstantReflection return new DummyConstantReflection($constantName); } + public function getConstantStrings(): array + { + return []; + } + public function isCloneable(): TrinaryLogic { return TrinaryLogic::createYes(); diff --git a/src/Type/Type.php b/src/Type/Type.php index 169eacdf9ed..6e56279dfb3 100644 --- a/src/Type/Type.php +++ b/src/Type/Type.php @@ -11,6 +11,7 @@ use PHPStan\Reflection\Type\UnresolvedPropertyPrototypeReflection; use PHPStan\TrinaryLogic; use PHPStan\Type\Constant\ConstantArrayType; +use PHPStan\Type\Constant\ConstantStringType; use PHPStan\Type\Generic\TemplateTypeMap; use PHPStan\Type\Generic\TemplateTypeReference; use PHPStan\Type\Generic\TemplateTypeVariance; @@ -30,6 +31,9 @@ public function getArrays(): array; /** @return list */ public function getConstantArrays(): array; + /** @return list */ + public function getConstantStrings(): array; + public function accepts(Type $type, bool $strictTypes): TrinaryLogic; public function isSuperTypeOf(Type $type): TrinaryLogic; diff --git a/src/Type/TypeUtils.php b/src/Type/TypeUtils.php index a6fada9cd73..394ac6ee8f1 100644 --- a/src/Type/TypeUtils.php +++ b/src/Type/TypeUtils.php @@ -93,6 +93,8 @@ public static function getConstantArrays(Type $type): array /** * @return ConstantStringType[] + * + * @deprecated Use PHPStan\Type\Type->getConstantStrings() instead */ public static function getConstantStrings(Type $type): array { diff --git a/src/Type/UnionType.php b/src/Type/UnionType.php index e55912aff4a..67a0c3f493e 100644 --- a/src/Type/UnionType.php +++ b/src/Type/UnionType.php @@ -107,6 +107,11 @@ public function getConstantArrays(): array return UnionTypeHelper::getConstantArrays($this->getTypes()); } + public function getConstantStrings(): array + { + return UnionTypeHelper::getConstantStrings($this->getTypes()); + } + public function accepts(Type $type, bool $strictTypes): TrinaryLogic { if ( diff --git a/src/Type/UnionTypeHelper.php b/src/Type/UnionTypeHelper.php index 02b1988111c..6bd5256ec73 100644 --- a/src/Type/UnionTypeHelper.php +++ b/src/Type/UnionTypeHelper.php @@ -60,6 +60,20 @@ public static function getConstantArrays(array $types): array ); } + /** + * @param Type[] $types + * @return list + */ + public static function getConstantStrings(array $types): array + { + return array_merge( + ...array_map( + static fn (Type $type) => $type->getConstantStrings(), + $types, + ), + ); + } + /** * @param Type[] $types * @return Type[]