Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow value-of to work with backed enums (fixes #7874). #8283

Merged
merged 3 commits into from Jul 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 8 additions & 8 deletions UPGRADING.md
Expand Up @@ -42,7 +42,7 @@
- `Psalm\Type\Atomic\TIntRange`
- `Psalm\Type\Atomic\TIterable`
- `Psalm\Type\Atomic\TKeyedArray`
- `Psalm\Type\Atomic\TKeyOfArray`
- `Psalm\Type\Atomic\TKeyOf`
- `Psalm\Type\Atomic\TList`
- `Psalm\Type\Atomic\TLiteralClassString`
- `Psalm\Type\Atomic\TLowercaseString`
Expand All @@ -64,7 +64,7 @@
- `Psalm\Type\Atomic\TTraitString`
- `Psalm\Type\Atomic\TTrue`
- `Psalm\Type\Atomic\TTypeAlias`
- `Psalm\Type\Atomic\TValueOfArray`
- `Psalm\Type\Atomic\TValueOf`
- `Psalm\Type\Atomic\TVoid`
- `Psalm\Type\Union`

Expand Down Expand Up @@ -92,7 +92,7 @@
- `Psalm\Type\Atomic\TInt`
- `Psalm\Type\Atomic\TIterable`
- `Psalm\Type\Atomic\TKeyedArray`
- `Psalm\Type\Atomic\TKeyOfArray`
- `Psalm\Type\Atomic\TKeyOf`
- `Psalm\Type\Atomic\TList`
- `Psalm\Type\Atomic\TLiteralClassString`
- `Psalm\Type\Atomic\TMixed`
Expand All @@ -109,7 +109,7 @@
- `Psalm\Type\Atomic\TTemplateParam`
- `Psalm\Type\Atomic\TTraitString`
- `Psalm\Type\Atomic\TTypeAlias`
- `Psalm\Type\Atomic\TValueOfArray`
- `Psalm\Type\Atomic\TValueOf`
- `Psalm\Type\Atomic\TVoid`
- `Psalm\Type\Union`
- While not a BC break per se, all classes / interfaces / traits / enums under
Expand Down Expand Up @@ -155,8 +155,8 @@
- [BC] Atomic::getId() has now a first param $exact. Calling the method with false will return a less detailed version of the type in some cases (similarly to what `__toString` used to return)
- [BC] To remove a variable from the context, use `Context::remove()`. Calling
`unset($context->vars_in_scope[$var_id])` can cause problems when using references.
- [BC] `TKeyOfClassConstant` has been renamed to `TKeyOfArray`.
- [BC] `TValueOfClassConstant` has been renamed to `TValueOfArray`.
- [BC] `TKeyOfClassConstant` has been renamed to `TKeyOf`.
- [BC] `TValueOfClassConstant` has been renamed to `TValueOf`.
- [BC] `TKeyOfTemplate` base class has been changed from `Scalar` to `Atomic`.
- [BC] Class `Psalm\FileManipulation` became final
- [BC] Class `Psalm\Context` became final
Expand Down Expand Up @@ -742,13 +742,13 @@
- [BC] Class `Psalm\Type\Atomic\TLiteralInt` became final
- [BC] Class `Psalm\Type\Atomic\TTrue` became final
- [BC] Class `Psalm\Type\Atomic\TDependentGetClass` became final
- [BC] Class `Psalm\Type\Atomic\TValueOfArray` became final
- [BC] Class `Psalm\Type\Atomic\TValueOf` became final
- [BC] Class `Psalm\Type\Atomic\TGenericObject` became final
- [BC] Class `Psalm\Type\Atomic\TNonEmptyLowercaseString` became final
- [BC] Class `Psalm\Type\Atomic\TEnumCase` became final
- [BC] Class `Psalm\Type\Atomic\TCallableKeyedArray` became final
- [BC] Class `Psalm\Type\Atomic\TDependentGetDebugType` became final
- [BC] Class `Psalm\Type\Atomic\TKeyOfArray` became final
- [BC] Class `Psalm\Type\Atomic\TKeyOf` became final
- [BC] Class `Psalm\Type\Atomic\TNonspecificLiteralInt` became final
- [BC] Class `Psalm\Type\Atomic\TObjectWithProperties` became final
- [BC] Class `Psalm\Type\Atomic\TTemplateValueOf` became final
Expand Down
8 changes: 4 additions & 4 deletions docs/running_psalm/plugins/plugins_type_system.md
Expand Up @@ -49,15 +49,15 @@ The classes are as follows:

`TIntMaskOf` - as above, but used with a reference to constants in code `int-mask-of<MyClass::CLASS_CONSTANT_*>` will corresponds to `1|2|3|4|5|6|7` if there are three constant 1, 2 and 4

`TKeyOfArray` - Represents an offset of an array (e.g. `key-of<MyClass::CLASS_CONSTANT>`).
`TKeyOf` - Represents an offset of an array (e.g. `key-of<MyClass::CLASS_CONSTANT>`).

`TValueOfArray` - Represents a value of an array (e.g. `value-of<MyClass::CLASS_CONSTANT>`).
`TValueOf` - Represents a value of an array or enum (e.g. `value-of<MyClass::CLASS_CONSTANT>`).

`TTemplateIndexedAccess` - To be documented

`TTemplateKeyOf` - Represents the type used when using TKeyOfArray when the type of the array is a template
`TTemplateKeyOf` - Represents the type used when using TKeyOf when the type of the array is a template

`TTemplateValueOf` - Represents the type used when using TValueOfArray when the type of the array is a template
`TTemplateValueOf` - Represents the type used when using TValueOf when the type of the array or enum is a template

`TPropertiesOf` - Represents properties and their types of a class as a keyed array (e.g. `properties-of<MyClass>`)

Expand Down
8 changes: 4 additions & 4 deletions src/Psalm/Internal/Type/Comparator/AtomicTypeComparator.php
Expand Up @@ -19,7 +19,7 @@
use Psalm\Type\Atomic\TEnumCase;
use Psalm\Type\Atomic\TGenericObject;
use Psalm\Type\Atomic\TIterable;
use Psalm\Type\Atomic\TKeyOfArray;
use Psalm\Type\Atomic\TKeyOf;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TLiteralString;
Expand All @@ -36,7 +36,7 @@
use Psalm\Type\Atomic\TTemplateKeyOf;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TTemplateValueOf;
use Psalm\Type\Atomic\TValueOfArray;
use Psalm\Type\Atomic\TValueOf;

use function array_merge;
use function array_values;
Expand Down Expand Up @@ -341,7 +341,7 @@ public static function isContainedBy(
}

if ($input_type_part instanceof TTemplateKeyOf) {
$array_key_type = TKeyOfArray::getArrayKeyType($input_type_part->as);
$array_key_type = TKeyOf::getArrayKeyType($input_type_part->as);
if ($array_key_type === null) {
return false;
}
Expand Down Expand Up @@ -375,7 +375,7 @@ public static function isContainedBy(
}

if ($input_type_part instanceof TTemplateValueOf) {
$array_value_type = TValueOfArray::getArrayValueType($input_type_part->as);
$array_value_type = TValueOf::getValueType($input_type_part->as, $codebase);
if ($array_value_type === null) {
return false;
}
Expand Down
12 changes: 6 additions & 6 deletions src/Psalm/Internal/Type/TemplateInferredTypeReplacer.php
Expand Up @@ -11,7 +11,7 @@
use Psalm\Type\Atomic\TConditional;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TIterable;
use Psalm\Type\Atomic\TKeyOfArray;
use Psalm\Type\Atomic\TKeyOf;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
Expand All @@ -26,7 +26,7 @@
use Psalm\Type\Atomic\TTemplateParamClass;
use Psalm\Type\Atomic\TTemplatePropertiesOf;
use Psalm\Type\Atomic\TTemplateValueOf;
use Psalm\Type\Atomic\TValueOfArray;
use Psalm\Type\Atomic\TValueOf;
use Psalm\Type\Union;
use UnexpectedValueException;

Expand Down Expand Up @@ -345,15 +345,15 @@ private static function replaceTemplateKeyOfValueOf(
);

if ($atomic_type instanceof TTemplateKeyOf
&& TKeyOfArray::isViableTemplateType($template_type)
&& TKeyOf::isViableTemplateType($template_type)
) {
return new TKeyOfArray(clone $template_type);
return new TKeyOf(clone $template_type);
}

if ($atomic_type instanceof TTemplateValueOf
&& TValueOfArray::isViableTemplateType($template_type)
&& TValueOf::isViableTemplateType($template_type)
) {
return new TValueOfArray(clone $template_type);
return new TValueOf(clone $template_type);
}

return null;
Expand Down
28 changes: 14 additions & 14 deletions src/Psalm/Internal/Type/TypeExpander.php
Expand Up @@ -22,7 +22,7 @@
use Psalm\Type\Atomic\TIntMask;
use Psalm\Type\Atomic\TIntMaskOf;
use Psalm\Type\Atomic\TIterable;
use Psalm\Type\Atomic\TKeyOfArray;
use Psalm\Type\Atomic\TKeyOf;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TLiteralClassString;
Expand All @@ -34,7 +34,7 @@
use Psalm\Type\Atomic\TPropertiesOf;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TTypeAlias;
use Psalm\Type\Atomic\TValueOfArray;
use Psalm\Type\Atomic\TValueOf;
use Psalm\Type\Atomic\TVoid;
use Psalm\Type\Union;
use ReflectionProperty;
Expand Down Expand Up @@ -363,10 +363,10 @@ public static function expandAtomic(
return [$return_type];
}

if ($return_type instanceof TKeyOfArray
|| $return_type instanceof TValueOfArray
if ($return_type instanceof TKeyOf
|| $return_type instanceof TValueOf
) {
return self::expandKeyOfValueOfArray(
return self::expandKeyOfValueOf(
$codebase,
$return_type,
$self_class,
Expand Down Expand Up @@ -965,11 +965,11 @@ function (?Union $property_type): bool {
}

/**
* @param TKeyOfArray|TValueOfArray $return_type
* @param TKeyOf|TValueOf $return_type
* @param string|TNamedObject|TTemplateParam|null $static_class_type
* @return non-empty-list<Atomic>
*/
private static function expandKeyOfValueOfArray(
private static function expandKeyOfValueOf(
Codebase $codebase,
Atomic &$return_type,
?string $self_class,
Expand Down Expand Up @@ -1025,12 +1025,12 @@ private static function expandKeyOfValueOfArray(

if (!$constant_type
|| (
$return_type instanceof TKeyOfArray
&& !TKeyOfArray::isViableTemplateType($constant_type)
$return_type instanceof TKeyOf
&& !TKeyOf::isViableTemplateType($constant_type)
)
|| (
$return_type instanceof TValueOfArray
&& !TValueOfArray::isViableTemplateType($constant_type)
$return_type instanceof TValueOf
&& !TValueOf::isViableTemplateType($constant_type)
)
) {
if ($throw_on_unresolvable_constant) {
Expand All @@ -1049,10 +1049,10 @@ private static function expandKeyOfValueOfArray(
return [$return_type];
}

if ($return_type instanceof TKeyOfArray) {
$new_return_types = TKeyOfArray::getArrayKeyType(new Union($type_atomics));
if ($return_type instanceof TKeyOf) {
$new_return_types = TKeyOf::getArrayKeyType(new Union($type_atomics));
} else {
$new_return_types = TValueOfArray::getArrayValueType(new Union($type_atomics));
$new_return_types = TValueOf::getValueType(new Union($type_atomics), $codebase);
}
if ($new_return_types === null) {
return [$return_type];
Expand Down
16 changes: 8 additions & 8 deletions src/Psalm/Internal/Type/TypeParser.php
Expand Up @@ -41,7 +41,7 @@
use Psalm\Type\Atomic\TIntMaskOf;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Atomic\TIterable;
use Psalm\Type\Atomic\TKeyOfArray;
use Psalm\Type\Atomic\TKeyOf;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TLiteralClassString;
Expand All @@ -63,7 +63,7 @@
use Psalm\Type\Atomic\TTemplatePropertiesOf;
use Psalm\Type\Atomic\TTemplateValueOf;
use Psalm\Type\Atomic\TTypeAlias;
use Psalm\Type\Atomic\TValueOfArray;
use Psalm\Type\Atomic\TValueOf;
use Psalm\Type\TypeNode;
use Psalm\Type\Union;

Expand Down Expand Up @@ -743,13 +743,13 @@ private static function getTypeFromGenericTree(
);
}

if (!TKeyOfArray::isViableTemplateType($generic_params[0])) {
if (!TKeyOf::isViableTemplateType($generic_params[0])) {
throw new TypeParseTreeException(
'Untemplated key-of param ' . $param_name . ' should be an array'
);
}

return new TKeyOfArray($generic_params[0]);
return new TKeyOf($generic_params[0]);
}

if ($generic_type_value === 'value-of') {
Expand All @@ -765,13 +765,13 @@ private static function getTypeFromGenericTree(
);
}

if (!TValueOfArray::isViableTemplateType($generic_params[0])) {
if (!TValueOf::isViableTemplateType($generic_params[0])) {
throw new TypeParseTreeException(
'Untemplated value-of param ' . $param_name . ' should be an array'
);
}

return new TValueOfArray($generic_params[0]);
return new TValueOf($generic_params[0]);
}

if ($generic_type_value === 'int-mask') {
Expand Down Expand Up @@ -842,8 +842,8 @@ private static function getTypeFromGenericTree(
$param_type = $param_union_types[0];

if (!$param_type instanceof TClassConstant
&& !$param_type instanceof TValueOfArray
&& !$param_type instanceof TKeyOfArray
&& !$param_type instanceof TValueOf
&& !$param_type instanceof TKeyOf
) {
throw new TypeParseTreeException(
'Invalid reference passed to int-mask-of'
Expand Down
4 changes: 2 additions & 2 deletions src/Psalm/Type/Atomic/TIntMaskOf.php
Expand Up @@ -11,11 +11,11 @@
*/
final class TIntMaskOf extends TInt
{
/** @var TClassConstant|TKeyOfArray|TValueOfArray */
/** @var TClassConstant|TKeyOf|TValueOf */
public $value;

/**
* @param TClassConstant|TKeyOfArray|TValueOfArray $value
* @param TClassConstant|TKeyOf|TValueOf $value
*/
public function __construct(Atomic $value)
{
Expand Down
Expand Up @@ -11,7 +11,7 @@
/**
* Represents an offset of an array.
*/
final class TKeyOfArray extends TArrayKey
final class TKeyOf extends TArrayKey
{
/** @var Union */
public $type;
Expand Down
2 changes: 1 addition & 1 deletion src/Psalm/Type/Atomic/TTemplateKeyOf.php
Expand Up @@ -9,7 +9,7 @@
use Psalm\Type\Union;

/**
* Represents the type used when using TKeyOfArray when the type of the array is a template
* Represents the type used when using TKeyOf when the type of the array is a template
*/
final class TTemplateKeyOf extends Atomic
{
Expand Down
2 changes: 1 addition & 1 deletion src/Psalm/Type/Atomic/TTemplateValueOf.php
Expand Up @@ -9,7 +9,7 @@
use Psalm\Type\Union;

/**
* Represents the type used when using TValueOfArray when the type of the array is a template
* Represents the type used when using TValueOf when the type of the array or enum is a template
*/
final class TTemplateValueOf extends Atomic
{
Expand Down