From fee0b13fc5752ad5f2c0e17cab1251d0b07dc7c9 Mon Sep 17 00:00:00 2001 From: orklah Date: Sun, 16 Jan 2022 16:07:56 +0100 Subject: [PATCH] refactor description of types in Atomic --- src/Psalm/Internal/Analyzer/ClassAnalyzer.php | 2 +- src/Psalm/Internal/Type/TypeParser.php | 6 +-- src/Psalm/Storage/FunctionLikeStorage.php | 2 +- src/Psalm/Type/Atomic.php | 30 +++++++++---- src/Psalm/Type/Atomic/CallableTrait.php | 34 +++++++++++---- src/Psalm/Type/Atomic/GenericTrait.php | 22 ++-------- src/Psalm/Type/Atomic/TArrayKey.php | 5 --- src/Psalm/Type/Atomic/TAssertionEmpty.php | 0 src/Psalm/Type/Atomic/TAssertionFalsy.php | 0 src/Psalm/Type/Atomic/TBool.php | 5 --- src/Psalm/Type/Atomic/TCallableObject.php | 5 --- src/Psalm/Type/Atomic/TCallableString.php | 5 --- src/Psalm/Type/Atomic/TClassConstant.php | 7 +--- src/Psalm/Type/Atomic/TClassString.php | 7 +--- src/Psalm/Type/Atomic/TClassStringMap.php | 25 +++-------- src/Psalm/Type/Atomic/TClosedResource.php | 10 ----- src/Psalm/Type/Atomic/TConditional.php | 22 +++------- src/Psalm/Type/Atomic/TDependentGetClass.php | 4 +- src/Psalm/Type/Atomic/TDependentListKey.php | 2 +- src/Psalm/Type/Atomic/TEmptyMixed.php | 2 +- src/Psalm/Type/Atomic/TEmptyNumeric.php | 2 +- src/Psalm/Type/Atomic/TEmptyScalar.php | 2 +- src/Psalm/Type/Atomic/TEnumCase.php | 2 +- src/Psalm/Type/Atomic/TFalse.php | 5 --- src/Psalm/Type/Atomic/TFloat.php | 5 --- src/Psalm/Type/Atomic/TInt.php | 5 --- src/Psalm/Type/Atomic/TIntMask.php | 4 +- src/Psalm/Type/Atomic/TIntMaskOf.php | 5 --- src/Psalm/Type/Atomic/TIntRange.php | 5 --- src/Psalm/Type/Atomic/TIterable.php | 9 +--- src/Psalm/Type/Atomic/TKeyOfClassConstant.php | 10 ----- src/Psalm/Type/Atomic/TKeyedArray.php | 42 ++++--------------- src/Psalm/Type/Atomic/TList.php | 10 +---- src/Psalm/Type/Atomic/TLiteralClassString.php | 11 +++-- src/Psalm/Type/Atomic/TLiteralFloat.php | 6 ++- src/Psalm/Type/Atomic/TLiteralInt.php | 6 ++- src/Psalm/Type/Atomic/TLiteralString.php | 9 ++-- src/Psalm/Type/Atomic/TLowercaseString.php | 2 +- src/Psalm/Type/Atomic/TMixed.php | 5 --- src/Psalm/Type/Atomic/TNamedObject.php | 11 ++--- src/Psalm/Type/Atomic/TNever.php | 5 --- .../Type/Atomic/TNonEmptyLowercaseString.php | 6 ++- src/Psalm/Type/Atomic/TNonEmptyMixed.php | 2 +- .../TNonEmptyNonspecificLiteralString.php | 6 ++- src/Psalm/Type/Atomic/TNonEmptyScalar.php | 2 +- src/Psalm/Type/Atomic/TNonEmptyString.php | 6 ++- src/Psalm/Type/Atomic/TNonFalsyString.php | 6 ++- .../Type/Atomic/TNonspecificLiteralInt.php | 2 +- .../Type/Atomic/TNonspecificLiteralString.php | 6 ++- src/Psalm/Type/Atomic/TNull.php | 5 --- src/Psalm/Type/Atomic/TNumeric.php | 5 --- src/Psalm/Type/Atomic/TNumericString.php | 13 +++--- src/Psalm/Type/Atomic/TObject.php | 5 --- .../Type/Atomic/TObjectWithProperties.php | 39 ++--------------- src/Psalm/Type/Atomic/TPositiveInt.php | 7 +--- src/Psalm/Type/Atomic/TResource.php | 5 --- src/Psalm/Type/Atomic/TScalar.php | 5 --- src/Psalm/Type/Atomic/TString.php | 5 --- .../Type/Atomic/TTemplateIndexedAccess.php | 10 ----- src/Psalm/Type/Atomic/TTemplateKeyOf.php | 11 +++-- src/Psalm/Type/Atomic/TTemplateParam.php | 17 ++++---- src/Psalm/Type/Atomic/TTemplateParamClass.php | 9 +--- src/Psalm/Type/Atomic/TTraitString.php | 10 ----- src/Psalm/Type/Atomic/TTrue.php | 5 --- src/Psalm/Type/Atomic/TTypeAlias.php | 19 +-------- .../Type/Atomic/TValueOfClassConstant.php | 10 ----- src/Psalm/Type/Atomic/TVoid.php | 5 --- src/Psalm/Type/Union.php | 40 ++++++++++++++---- tests/ArrayAccessTest.php | 2 +- tests/ArrayFunctionCallTest.php | 2 +- tests/CallableTest.php | 12 +++--- tests/ClosureTest.php | 18 ++++---- .../Hook/StringProvider/TSqlSelectString.php | 2 +- tests/ConstantTest.php | 8 ++-- tests/EnumTest.php | 2 +- tests/FunctionCallTest.php | 12 +++--- tests/GeneratorTest.php | 4 +- tests/IntRangeTest.php | 4 +- tests/JsonOutputTest.php | 4 +- tests/MagicMethodAnnotationTest.php | 4 +- tests/ReturnTypeTest.php | 8 ++-- tests/Template/ClassTemplateTest.php | 4 +- tests/Traits/ValidCodeAnalysisTestTrait.php | 5 ++- tests/TypeCombinationTest.php | 10 ++--- tests/TypeParseTest.php | 24 +++++------ tests/TypeReconciliation/ConditionalTest.php | 2 +- tests/TypeReconciliation/ReconcilerTest.php | 12 +++--- 87 files changed, 270 insertions(+), 486 deletions(-) create mode 100644 src/Psalm/Type/Atomic/TAssertionEmpty.php create mode 100644 src/Psalm/Type/Atomic/TAssertionFalsy.php diff --git a/src/Psalm/Internal/Analyzer/ClassAnalyzer.php b/src/Psalm/Internal/Analyzer/ClassAnalyzer.php index d45ae54f9b8..8bfdc01ab99 100644 --- a/src/Psalm/Internal/Analyzer/ClassAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/ClassAnalyzer.php @@ -1553,7 +1553,7 @@ private function checkForMissingPropertyType( $message .= ' - consider ' . str_replace( ['', ''], '', - (string)$suggested_type + $suggested_type->getId(false) ); } diff --git a/src/Psalm/Internal/Type/TypeParser.php b/src/Psalm/Internal/Type/TypeParser.php index 7795373a05b..bf10c2778eb 100644 --- a/src/Psalm/Internal/Type/TypeParser.php +++ b/src/Psalm/Internal/Type/TypeParser.php @@ -621,7 +621,7 @@ private static function getTypeFromGenericTree( || $generic_type_value === 'interface-string' || $generic_type_value === 'enum-string' ) { - $class_name = (string)$generic_params[0]; + $class_name = $generic_params[0]->getId(false); if (isset($template_type_map[$class_name])) { $first_class = array_keys($template_type_map[$class_name])[0]; @@ -685,7 +685,7 @@ private static function getTypeFromGenericTree( } if ($generic_type_value === 'key-of') { - $param_name = (string)$generic_params[0]; + $param_name = $generic_params[0]->getId(false); if (isset($template_type_map[$param_name])) { $defining_class = array_keys($template_type_map[$param_name])[0]; @@ -716,7 +716,7 @@ private static function getTypeFromGenericTree( } if ($generic_type_value === 'value-of') { - $param_name = (string)$generic_params[0]; + $param_name = $generic_params[0]->getId(false); $param_union_types = array_values($generic_params[0]->getAtomicTypes()); diff --git a/src/Psalm/Storage/FunctionLikeStorage.php b/src/Psalm/Storage/FunctionLikeStorage.php index b4614ad4607..916ba0e2970 100644 --- a/src/Psalm/Storage/FunctionLikeStorage.php +++ b/src/Psalm/Storage/FunctionLikeStorage.php @@ -250,7 +250,7 @@ public function getSignature(bool $allow_newlines): string array_map( fn(FunctionLikeParameter $param): string => ($newlines ? ' ' : '') - . ($param->type ?: 'mixed') + . ($param->type ? $param->type->getId(false) : 'mixed') . ' $' . $param->name, $this->params ) diff --git a/src/Psalm/Type/Atomic.php b/src/Psalm/Type/Atomic.php index 9754dbcbe16..703279556e4 100644 --- a/src/Psalm/Type/Atomic.php +++ b/src/Psalm/Type/Atomic.php @@ -77,8 +77,6 @@ abstract class Atomic implements TypeNode { - public const KEY = 'atomic'; - /** * Whether or not the type has been checked yet * @@ -325,6 +323,10 @@ public static function create( return new TNamedObject($value); } + /** + * This is the string that will be used to represent the type in Union::$types. This means that two types sharing + * the same getKey value will override themselves in an Union + */ abstract public function getKey(bool $include_extra = true): string; public function isNumericType(): bool @@ -548,9 +550,9 @@ public function replaceClassLike(string $old, string $new): void } } - public function __toString(): string + final public function __toString(): string { - return ''; + return $this->getId(); } public function __clone() @@ -572,18 +574,27 @@ public function __clone() } } - public function getId(bool $nested = false): string + /** + * This is the true identifier for the type. It defaults to self::getKey() but can be overrided to be more precise + */ + public function getId(bool $exact = true, bool $nested = false): string { - return $this->__toString(); + return $this->getKey(); } - + /** + * This string is used in order to transform a type into an string assertion for the assertion module + * Default to self::getId() + */ public function getAssertionString(): string { return $this->getId(); } /** - * @param array $aliased_classes + * Returns the detailed description of the type, either in phpdoc standard format or Psalm format depending on flag + * Default to self::getKey() + * + * @param array $aliased_classes */ public function toNamespacedString( ?string $namespace, @@ -595,6 +606,9 @@ public function toNamespacedString( } /** + * Returns a string representation of the type compatible with php signature or null if the type can't be expressed + * with the given php version + * * @param array $aliased_classes */ abstract public function toPhpString( diff --git a/src/Psalm/Type/Atomic/CallableTrait.php b/src/Psalm/Type/Atomic/CallableTrait.php index b7658725834..0b5252f0af3 100644 --- a/src/Psalm/Type/Atomic/CallableTrait.php +++ b/src/Psalm/Type/Atomic/CallableTrait.php @@ -63,7 +63,30 @@ public function __clone() public function getKey(bool $include_extra = true): string { - return $this->__toString(); + $param_string = ''; + $return_type_string = ''; + + if ($this->params !== null) { + $param_string .= '('; + foreach ($this->params as $i => $param) { + if ($i) { + $param_string .= ', '; + } + + $param_string .= $param->getId(); + } + + $param_string .= ')'; + } + + if ($this->return_type !== null) { + $return_type_multiple = count($this->return_type->getAtomicTypes()) > 1; + $return_type_string = ':' . ($return_type_multiple ? '(' : '') + . $this->return_type->getId() . ($return_type_multiple ? ')' : ''); + } + + return ($this->is_pure ? 'pure-' : ($this->is_pure === null ? '' : 'impure-')) + . $this->value . $param_string . $return_type_string; } /** @@ -147,7 +170,7 @@ public function toPhpString( return $this->value; } - public function getId(bool $nested = false): string + public function getId(bool $exact = true, bool $nested = false): string { $param_string = ''; $return_type_string = ''; @@ -168,18 +191,13 @@ public function getId(bool $nested = false): string if ($this->return_type !== null) { $return_type_multiple = count($this->return_type->getAtomicTypes()) > 1; $return_type_string = ':' . ($return_type_multiple ? '(' : '') - . $this->return_type->getId() . ($return_type_multiple ? ')' : ''); + . $this->return_type->getId($exact) . ($return_type_multiple ? ')' : ''); } return ($this->is_pure ? 'pure-' : ($this->is_pure === null ? '' : 'impure-')) . $this->value . $param_string . $return_type_string; } - public function __toString(): string - { - return $this->getId(); - } - public function replaceTemplateTypesWithStandins( TemplateResult $template_result, Codebase $codebase, diff --git a/src/Psalm/Type/Atomic/GenericTrait.php b/src/Psalm/Type/Atomic/GenericTrait.php index 8e1fabb7384..6e82cb64923 100644 --- a/src/Psalm/Type/Atomic/GenericTrait.php +++ b/src/Psalm/Type/Atomic/GenericTrait.php @@ -21,27 +21,11 @@ trait GenericTrait { - public function __toString(): string + public function getId(bool $exact = true, bool $nested = false): string { $s = ''; foreach ($this->type_params as $type_param) { - $s .= $type_param . ', '; - } - - $extra_types = ''; - - if ($this instanceof TNamedObject && $this->extra_types) { - $extra_types = '&' . implode('&', $this->extra_types); - } - - return $this->value . '<' . substr($s, 0, -2) . '>' . $extra_types; - } - - public function getId(bool $nested = false): string - { - $s = ''; - foreach ($this->type_params as $type_param) { - $s .= $type_param->getId() . ', '; + $s .= $type_param->getId($exact) . ', '; } $extra_types = ''; @@ -51,7 +35,7 @@ public function getId(bool $nested = false): string $extra_types = '&' . implode( '&', array_map( - fn($type) => $type->getId(true), + fn($type) => $type->getId($exact, true), $this->extra_types ) ); diff --git a/src/Psalm/Type/Atomic/TArrayKey.php b/src/Psalm/Type/Atomic/TArrayKey.php index 7c53bd1dc6c..bf317292958 100644 --- a/src/Psalm/Type/Atomic/TArrayKey.php +++ b/src/Psalm/Type/Atomic/TArrayKey.php @@ -7,11 +7,6 @@ */ class TArrayKey extends Scalar { - public function __toString(): string - { - return 'array-key'; - } - public function getKey(bool $include_extra = true): string { return 'array-key'; diff --git a/src/Psalm/Type/Atomic/TAssertionEmpty.php b/src/Psalm/Type/Atomic/TAssertionEmpty.php new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/Psalm/Type/Atomic/TAssertionFalsy.php b/src/Psalm/Type/Atomic/TAssertionFalsy.php new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/Psalm/Type/Atomic/TBool.php b/src/Psalm/Type/Atomic/TBool.php index 936085be193..ec7cbc06258 100644 --- a/src/Psalm/Type/Atomic/TBool.php +++ b/src/Psalm/Type/Atomic/TBool.php @@ -7,11 +7,6 @@ */ class TBool extends Scalar { - public function __toString(): string - { - return 'bool'; - } - public function getKey(bool $include_extra = true): string { return 'bool'; diff --git a/src/Psalm/Type/Atomic/TCallableObject.php b/src/Psalm/Type/Atomic/TCallableObject.php index ebbee0b3377..5657a51cf0c 100644 --- a/src/Psalm/Type/Atomic/TCallableObject.php +++ b/src/Psalm/Type/Atomic/TCallableObject.php @@ -7,11 +7,6 @@ */ class TCallableObject extends TObject { - public function __toString(): string - { - return 'callable-object'; - } - public function getKey(bool $include_extra = true): string { return 'callable-object'; diff --git a/src/Psalm/Type/Atomic/TCallableString.php b/src/Psalm/Type/Atomic/TCallableString.php index 0b49ca93f96..d2bf403bd41 100644 --- a/src/Psalm/Type/Atomic/TCallableString.php +++ b/src/Psalm/Type/Atomic/TCallableString.php @@ -13,11 +13,6 @@ public function getKey(bool $include_extra = true): string return 'callable-string'; } - public function getId(bool $nested = false): string - { - return $this->getKey(); - } - public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; diff --git a/src/Psalm/Type/Atomic/TClassConstant.php b/src/Psalm/Type/Atomic/TClassConstant.php index d93e076e407..cb357453dff 100644 --- a/src/Psalm/Type/Atomic/TClassConstant.php +++ b/src/Psalm/Type/Atomic/TClassConstant.php @@ -27,12 +27,7 @@ public function getKey(bool $include_extra = true): string return 'class-constant(' . $this->fq_classlike_name . '::' . $this->const_name . ')'; } - public function __toString(): string - { - return $this->fq_classlike_name . '::' . $this->const_name; - } - - public function getId(bool $nested = false): string + public function getId(bool $exact = true, bool $nested = false): string { return $this->fq_classlike_name . '::' . $this->const_name; } diff --git a/src/Psalm/Type/Atomic/TClassString.php b/src/Psalm/Type/Atomic/TClassString.php index f4dd549a74f..1124c9e6a78 100644 --- a/src/Psalm/Type/Atomic/TClassString.php +++ b/src/Psalm/Type/Atomic/TClassString.php @@ -61,12 +61,7 @@ public function getKey(bool $include_extra = true): string return $key . ($this->as === 'object' ? '' : '<' . $this->as_type . '>'); } - public function __toString(): string - { - return $this->getKey(); - } - - public function getId(bool $nested = false): string + public function getId(bool $exact = true, bool $nested = false): string { if ($this->is_interface) { $key = 'interface-string'; diff --git a/src/Psalm/Type/Atomic/TClassStringMap.php b/src/Psalm/Type/Atomic/TClassStringMap.php index 519df27bf65..6f2d9c788f3 100644 --- a/src/Psalm/Type/Atomic/TClassStringMap.php +++ b/src/Psalm/Type/Atomic/TClassStringMap.php @@ -34,8 +34,6 @@ class TClassStringMap extends Atomic */ public $value_param; - public const KEY = 'class-string-map'; - /** * Constructs a new instance of a list */ @@ -46,29 +44,16 @@ public function __construct(string $param_name, ?TNamedObject $as_type, Union $v $this->as_type = $as_type; } - public function __toString(): string - { - /** @psalm-suppress MixedOperand */ - return static::KEY - . '<' - . $this->param_name - . ' as ' - . ($this->as_type ? (string) $this->as_type : 'object') - . ', ' - . ((string) $this->value_param) - . '>'; - } - - public function getId(bool $nested = false): string + public function getId(bool $exact = true, bool $nested = false): string { /** @psalm-suppress MixedOperand */ - return static::KEY + return 'class-string-map' . '<' . $this->param_name . ' as ' - . ($this->as_type ? (string) $this->as_type : 'object') + . ($this->as_type ? $this->as_type->getId($exact) : 'object') . ', ' - . $this->value_param->getId() + . $this->value_param->getId($exact) . '>'; } @@ -98,7 +83,7 @@ public function toNamespacedString( } /** @psalm-suppress MixedOperand */ - return static::KEY + return 'class-string-map' . '<' . $this->param_name . ($this->as_type ? ' as ' . $this->as_type : '') diff --git a/src/Psalm/Type/Atomic/TClosedResource.php b/src/Psalm/Type/Atomic/TClosedResource.php index 8ebbbfaeffd..b8b2bc1811e 100644 --- a/src/Psalm/Type/Atomic/TClosedResource.php +++ b/src/Psalm/Type/Atomic/TClosedResource.php @@ -9,21 +9,11 @@ */ class TClosedResource extends Atomic { - public function __toString(): string - { - return 'closed-resource'; - } - public function getKey(bool $include_extra = true): string { return 'closed-resource'; } - public function getId(bool $nested = false): string - { - return 'closed-resource'; - } - /** * @param array $aliased_classes */ diff --git a/src/Psalm/Type/Atomic/TConditional.php b/src/Psalm/Type/Atomic/TConditional.php index 559d0e12dce..90f4bd9d0b4 100644 --- a/src/Psalm/Type/Atomic/TConditional.php +++ b/src/Psalm/Type/Atomic/TConditional.php @@ -59,16 +59,6 @@ public function __construct( $this->else_type = $else_type; } - public function __toString(): string - { - return '(' - . $this->param_name - . ' is ' . $this->conditional_type - . ' ? ' . $this->if_type - . ' : ' . $this->else_type - . ')'; - } - public function __clone() { $this->conditional_type = clone $this->conditional_type; @@ -79,7 +69,7 @@ public function __clone() public function getKey(bool $include_extra = true): string { - return $this->__toString(); + return 'TConditional<' . $this->param_name . '>'; } public function getAssertionString(): string @@ -87,13 +77,13 @@ public function getAssertionString(): string return ''; } - public function getId(bool $nested = false): string + public function getId(bool $exact = true, bool $nested = false): string { return '(' - . $this->param_name . ':' . $this->defining_class - . ' is ' . $this->conditional_type->getId() - . ' ? ' . $this->if_type->getId() - . ' : ' . $this->else_type->getId() + . $this->param_name + . ' is ' . $this->conditional_type->getId($exact) + . ' ? ' . $this->if_type->getId($exact) + . ' : ' . $this->else_type->getId($exact) . ')'; } diff --git a/src/Psalm/Type/Atomic/TDependentGetClass.php b/src/Psalm/Type/Atomic/TDependentGetClass.php index a22e8476132..5f47b315aa7 100644 --- a/src/Psalm/Type/Atomic/TDependentGetClass.php +++ b/src/Psalm/Type/Atomic/TDependentGetClass.php @@ -31,12 +31,12 @@ public function __construct(string $typeof, Union $as_type) $this->as_type = $as_type; } - public function getId(bool $nested = false): string + public function getId(bool $exact = true, bool $nested = false): string { return $this->as_type->isMixed() || $this->as_type->hasObject() ? 'class-string' - : 'class-string<' . $this->as_type->getId() . '>'; + : 'class-string<' . $this->as_type->getId($exact) . '>'; } public function getKey(bool $include_extra = true): string diff --git a/src/Psalm/Type/Atomic/TDependentListKey.php b/src/Psalm/Type/Atomic/TDependentListKey.php index 9037d627228..65d4a34e7d6 100644 --- a/src/Psalm/Type/Atomic/TDependentListKey.php +++ b/src/Psalm/Type/Atomic/TDependentListKey.php @@ -24,7 +24,7 @@ public function __construct(string $var_id) $this->var_id = $var_id; } - public function getId(bool $nested = false): string + public function getId(bool $exact = true, bool $nested = false): string { return 'list-key<' . $this->var_id . '>'; } diff --git a/src/Psalm/Type/Atomic/TEmptyMixed.php b/src/Psalm/Type/Atomic/TEmptyMixed.php index b5f5222057c..da93de38316 100644 --- a/src/Psalm/Type/Atomic/TEmptyMixed.php +++ b/src/Psalm/Type/Atomic/TEmptyMixed.php @@ -8,7 +8,7 @@ */ class TEmptyMixed extends TMixed { - public function getId(bool $nested = false): string + public function getId(bool $exact = true, bool $nested = false): string { return 'empty-mixed'; } diff --git a/src/Psalm/Type/Atomic/TEmptyNumeric.php b/src/Psalm/Type/Atomic/TEmptyNumeric.php index 3c970eca7f3..6d353e5da74 100644 --- a/src/Psalm/Type/Atomic/TEmptyNumeric.php +++ b/src/Psalm/Type/Atomic/TEmptyNumeric.php @@ -7,7 +7,7 @@ */ class TEmptyNumeric extends TNumeric { - public function getId(bool $nested = false): string + public function getId(bool $exact = true, bool $nested = false): string { return 'empty-numeric'; } diff --git a/src/Psalm/Type/Atomic/TEmptyScalar.php b/src/Psalm/Type/Atomic/TEmptyScalar.php index 21f014bbdcf..5df337e0d80 100644 --- a/src/Psalm/Type/Atomic/TEmptyScalar.php +++ b/src/Psalm/Type/Atomic/TEmptyScalar.php @@ -7,7 +7,7 @@ */ class TEmptyScalar extends TScalar { - public function getId(bool $nested = false): string + public function getId(bool $exact = true, bool $nested = false): string { return 'empty-scalar'; } diff --git a/src/Psalm/Type/Atomic/TEnumCase.php b/src/Psalm/Type/Atomic/TEnumCase.php index de6f0a52fe9..474d8bbe0a3 100644 --- a/src/Psalm/Type/Atomic/TEnumCase.php +++ b/src/Psalm/Type/Atomic/TEnumCase.php @@ -24,7 +24,7 @@ public function getKey(bool $include_extra = true): string return 'enum(' . $this->value . '::' . $this->case_name . ')'; } - public function getId(bool $nested = false): string + public function getId(bool $exact = true, bool $nested = false): string { return 'enum(' . $this->value . '::' . $this->case_name . ')'; } diff --git a/src/Psalm/Type/Atomic/TFalse.php b/src/Psalm/Type/Atomic/TFalse.php index c52fa09bed0..108d0f1136e 100644 --- a/src/Psalm/Type/Atomic/TFalse.php +++ b/src/Psalm/Type/Atomic/TFalse.php @@ -7,11 +7,6 @@ */ class TFalse extends TBool { - public function __toString(): string - { - return 'false'; - } - public function getKey(bool $include_extra = true): string { return 'false'; diff --git a/src/Psalm/Type/Atomic/TFloat.php b/src/Psalm/Type/Atomic/TFloat.php index 0acdbff07d0..f30592dd8fd 100644 --- a/src/Psalm/Type/Atomic/TFloat.php +++ b/src/Psalm/Type/Atomic/TFloat.php @@ -7,11 +7,6 @@ */ class TFloat extends Scalar { - public function __toString(): string - { - return 'float'; - } - public function getKey(bool $include_extra = true): string { return 'float'; diff --git a/src/Psalm/Type/Atomic/TInt.php b/src/Psalm/Type/Atomic/TInt.php index 5cdccd63a38..95f6506509a 100644 --- a/src/Psalm/Type/Atomic/TInt.php +++ b/src/Psalm/Type/Atomic/TInt.php @@ -7,11 +7,6 @@ */ class TInt extends Scalar { - public function __toString(): string - { - return 'int'; - } - public function getKey(bool $include_extra = true): string { return 'int'; diff --git a/src/Psalm/Type/Atomic/TIntMask.php b/src/Psalm/Type/Atomic/TIntMask.php index 86a4b5fccfe..2042e4768b5 100644 --- a/src/Psalm/Type/Atomic/TIntMask.php +++ b/src/Psalm/Type/Atomic/TIntMask.php @@ -30,12 +30,12 @@ public function getKey(bool $include_extra = true): string return 'int-mask<' . substr($s, 0, -2) . '>'; } - public function getId(bool $nested = false): string + public function getId(bool $exact = true, bool $nested = false): string { $s = ''; foreach ($this->values as $value) { - $s .= $value->getId() . ', '; + $s .= $value->getId($exact) . ', '; } return 'int-mask<' . substr($s, 0, -2) . '>'; diff --git a/src/Psalm/Type/Atomic/TIntMaskOf.php b/src/Psalm/Type/Atomic/TIntMaskOf.php index 512dd42bc3b..ec71060ff78 100644 --- a/src/Psalm/Type/Atomic/TIntMaskOf.php +++ b/src/Psalm/Type/Atomic/TIntMaskOf.php @@ -27,11 +27,6 @@ public function getKey(bool $include_extra = true): string return 'int-mask-of<' . $this->value->getKey() . '>'; } - public function getId(bool $nested = false): string - { - return $this->getKey(); - } - /** * @param array $aliased_classes */ diff --git a/src/Psalm/Type/Atomic/TIntRange.php b/src/Psalm/Type/Atomic/TIntRange.php index 64269371319..ffb6926c3e6 100644 --- a/src/Psalm/Type/Atomic/TIntRange.php +++ b/src/Psalm/Type/Atomic/TIntRange.php @@ -28,11 +28,6 @@ public function __construct(?int $min_bound, ?int $max_bound) $this->max_bound = $max_bound; } - public function __toString(): string - { - return $this->getKey(); - } - public function getKey(bool $include_extra = true): string { return 'int<' . ($this->min_bound ?? 'min') . ', ' . ($this->max_bound ?? 'max') . '>'; diff --git a/src/Psalm/Type/Atomic/TIterable.php b/src/Psalm/Type/Atomic/TIterable.php index d092da46681..927304971b4 100644 --- a/src/Psalm/Type/Atomic/TIterable.php +++ b/src/Psalm/Type/Atomic/TIterable.php @@ -61,11 +61,11 @@ public function getAssertionString(): string return 'iterable'; } - public function getId(bool $nested = false): string + public function getId(bool $exact = true, bool $nested = false): string { $s = ''; foreach ($this->type_params as $type_param) { - $s .= $type_param->getId() . ', '; + $s .= $type_param->getId($exact) . ', '; } $extra_types = ''; @@ -77,11 +77,6 @@ public function getId(bool $nested = false): string return $this->value . '<' . substr($s, 0, -2) . '>' . $extra_types; } - public function __toString(): string - { - return $this->getId(); - } - /** * @param array $aliased_classes */ diff --git a/src/Psalm/Type/Atomic/TKeyOfClassConstant.php b/src/Psalm/Type/Atomic/TKeyOfClassConstant.php index 621b010ff0a..5834db3e25c 100644 --- a/src/Psalm/Type/Atomic/TKeyOfClassConstant.php +++ b/src/Psalm/Type/Atomic/TKeyOfClassConstant.php @@ -30,16 +30,6 @@ public function getKey(bool $include_extra = true): string return 'key-of<' . $this->fq_classlike_name . '::' . $this->const_name . '>'; } - public function __toString(): string - { - return 'key-of<' . $this->fq_classlike_name . '::' . $this->const_name . '>'; - } - - public function getId(bool $nested = false): string - { - return $this->getKey(); - } - /** * @param array $aliased_classes */ diff --git a/src/Psalm/Type/Atomic/TKeyedArray.php b/src/Psalm/Type/Atomic/TKeyedArray.php index 528afc2fc67..124673e65e4 100644 --- a/src/Psalm/Type/Atomic/TKeyedArray.php +++ b/src/Psalm/Type/Atomic/TKeyedArray.php @@ -78,12 +78,12 @@ public function __construct(array $properties, ?array $class_strings = null) $this->class_strings = $class_strings; } - public function __toString(): string + public function getId(bool $exact = true, bool $nested = false): string { $property_strings = array_map( - function ($name, Union $type): string { + function ($name, Union $type) use ($exact): string { if ($this->is_list && $this->sealed) { - return (string) $type; + return $type->getId($exact); } $class_string_suffix = ''; @@ -93,36 +93,8 @@ function ($name, Union $type): string { $name = $this->escapeAndQuote($name); - return $name . $class_string_suffix . ($type->possibly_undefined ? '?' : '') . ': ' . $type; - }, - array_keys($this->properties), - $this->properties - ); - - if (!$this->is_list) { - sort($property_strings); - } - - /** @psalm-suppress MixedOperand */ - return static::KEY . '{' . implode(', ', $property_strings) . '}'; - } - - public function getId(bool $nested = false): string - { - $property_strings = array_map( - function ($name, Union $type): string { - if ($this->is_list && $this->sealed) { - return $type->getId(); - } - - $class_string_suffix = ''; - if (isset($this->class_strings[$name])) { - $class_string_suffix = '::class'; - } - - $name = $this->escapeAndQuote($name); - - return $name . $class_string_suffix . ($type->possibly_undefined ? '?' : '') . ': ' . $type->getId(); + return $name . $class_string_suffix . ($type->possibly_undefined ? '?' : '') + . ': ' . $type->getId($exact); }, array_keys($this->properties), $this->properties @@ -139,8 +111,8 @@ function ($name, Union $type): string { . ($this->previous_value_type && (!$this->previous_value_type->isMixed() || ($this->previous_key_type && !$this->previous_key_type->isArrayKey())) - ? '<' . ($this->previous_key_type ? $this->previous_key_type->getId() . ', ' : '') - . $this->previous_value_type->getId() . '>' + ? '<' . ($this->previous_key_type ? $this->previous_key_type->getId($exact) . ', ' : '') + . $this->previous_value_type->getId($exact) . '>' : ''); } diff --git a/src/Psalm/Type/Atomic/TList.php b/src/Psalm/Type/Atomic/TList.php index ac3293002db..e5389afaf30 100644 --- a/src/Psalm/Type/Atomic/TList.php +++ b/src/Psalm/Type/Atomic/TList.php @@ -36,16 +36,10 @@ public function __construct(Union $type_param) $this->type_param = $type_param; } - public function __toString(): string + public function getId(bool $exact = true, bool $nested = false): string { /** @psalm-suppress MixedOperand */ - return static::KEY . '<' . $this->type_param . '>'; - } - - public function getId(bool $nested = false): string - { - /** @psalm-suppress MixedOperand */ - return static::KEY . '<' . $this->type_param->getId() . '>'; + return static::KEY . '<' . $this->type_param->getId($exact) . '>'; } public function __clone() diff --git a/src/Psalm/Type/Atomic/TLiteralClassString.php b/src/Psalm/Type/Atomic/TLiteralClassString.php index bbb5c5e941e..cfae6aab4ac 100644 --- a/src/Psalm/Type/Atomic/TLiteralClassString.php +++ b/src/Psalm/Type/Atomic/TLiteralClassString.php @@ -25,11 +25,6 @@ public function __construct(string $value, bool $definite_class = false) $this->definite_class = $definite_class; } - public function __toString(): string - { - return 'class-string'; - } - public function getKey(bool $include_extra = true): string { return 'class-string(' . $this->value . ')'; @@ -52,8 +47,12 @@ public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool return false; } - public function getId(bool $nested = false): string + public function getId(bool $exact = true, bool $nested = false): string { + if (!$exact) { + return 'class-string'; + } + return $this->value . '::class'; } diff --git a/src/Psalm/Type/Atomic/TLiteralFloat.php b/src/Psalm/Type/Atomic/TLiteralFloat.php index 05a7819afcf..b8d4c54837d 100644 --- a/src/Psalm/Type/Atomic/TLiteralFloat.php +++ b/src/Psalm/Type/Atomic/TLiteralFloat.php @@ -20,8 +20,12 @@ public function getKey(bool $include_extra = true): string return 'float(' . $this->value . ')'; } - public function getId(bool $nested = false): string + public function getId(bool $exact = true, bool $nested = false): string { + if (!$exact) { + return 'float'; + } + return 'float(' . $this->value . ')'; } diff --git a/src/Psalm/Type/Atomic/TLiteralInt.php b/src/Psalm/Type/Atomic/TLiteralInt.php index d85ce02380b..4dfea9db9c7 100644 --- a/src/Psalm/Type/Atomic/TLiteralInt.php +++ b/src/Psalm/Type/Atomic/TLiteralInt.php @@ -20,8 +20,12 @@ public function getKey(bool $include_extra = true): string return 'int(' . $this->value . ')'; } - public function getId(bool $nested = false): string + public function getId(bool $exact = true, bool $nested = false): string { + if (!$exact) { + return 'int'; + } + return (string) $this->value; } diff --git a/src/Psalm/Type/Atomic/TLiteralString.php b/src/Psalm/Type/Atomic/TLiteralString.php index bb5c2b48baa..71ae7f73551 100644 --- a/src/Psalm/Type/Atomic/TLiteralString.php +++ b/src/Psalm/Type/Atomic/TLiteralString.php @@ -24,15 +24,18 @@ public function getKey(bool $include_extra = true): string return 'string(' . $this->value . ')'; } - public function getId(bool $nested = false): string + public function getId(bool $exact = true, bool $nested = false): string { + if (!$exact) { + return 'string'; + } // quote control characters, backslashes and double quote $no_newline_value = addcslashes($this->value, "\0..\37\\\""); if (mb_strlen($this->value) > 80) { - return '"' . mb_substr($no_newline_value, 0, 80) . '...' . '"'; + return "'" . mb_substr($no_newline_value, 0, 80) . '...' . "'"; } - return '"' . $no_newline_value . '"'; + return "'" . $no_newline_value . "'"; } public function getAssertionString(): string diff --git a/src/Psalm/Type/Atomic/TLowercaseString.php b/src/Psalm/Type/Atomic/TLowercaseString.php index 5fc884fe570..ad8d1a045db 100644 --- a/src/Psalm/Type/Atomic/TLowercaseString.php +++ b/src/Psalm/Type/Atomic/TLowercaseString.php @@ -4,7 +4,7 @@ class TLowercaseString extends TString { - public function getId(bool $nested = false): string + public function getId(bool $exact = true, bool $nested = false): string { return 'lowercase-string'; } diff --git a/src/Psalm/Type/Atomic/TMixed.php b/src/Psalm/Type/Atomic/TMixed.php index a2626a885f1..0c029645a47 100644 --- a/src/Psalm/Type/Atomic/TMixed.php +++ b/src/Psalm/Type/Atomic/TMixed.php @@ -17,11 +17,6 @@ public function __construct(bool $from_loop_isset = false) $this->from_loop_isset = $from_loop_isset; } - public function __toString(): string - { - return 'mixed'; - } - public function getKey(bool $include_extra = true): string { return 'mixed'; diff --git a/src/Psalm/Type/Atomic/TNamedObject.php b/src/Psalm/Type/Atomic/TNamedObject.php index 07e725f86ac..16bdaa3ee20 100644 --- a/src/Psalm/Type/Atomic/TNamedObject.php +++ b/src/Psalm/Type/Atomic/TNamedObject.php @@ -49,11 +49,6 @@ public function __construct(string $value, bool $is_static = false, bool $defini $this->definite_class = $definite_class; } - public function __toString(): string - { - return $this->getKey(); - } - public function getKey(bool $include_extra = true): string { if ($include_extra && $this->extra_types) { @@ -63,19 +58,19 @@ public function getKey(bool $include_extra = true): string return $this->value; } - public function getId(bool $nested = false): string + public function getId(bool $exact = true, bool $nested = false): string { if ($this->extra_types) { return $this->value . '&' . implode( '&', array_map( - fn($type) => $type->getId(true), + fn($type) => $type->getId($exact, true), $this->extra_types ) ); } - return $this->is_static ? $this->value . '&static' : $this->value; + return $this->is_static && $exact ? $this->value . '&static' : $this->value; } /** diff --git a/src/Psalm/Type/Atomic/TNever.php b/src/Psalm/Type/Atomic/TNever.php index 5e624c0ab49..f7de8a3fd1b 100644 --- a/src/Psalm/Type/Atomic/TNever.php +++ b/src/Psalm/Type/Atomic/TNever.php @@ -10,11 +10,6 @@ */ class TNever extends Atomic { - public function __toString(): string - { - return 'never'; - } - public function getKey(bool $include_extra = true): string { return 'never'; diff --git a/src/Psalm/Type/Atomic/TNonEmptyLowercaseString.php b/src/Psalm/Type/Atomic/TNonEmptyLowercaseString.php index 9769e7f605b..cc6edbdbad8 100644 --- a/src/Psalm/Type/Atomic/TNonEmptyLowercaseString.php +++ b/src/Psalm/Type/Atomic/TNonEmptyLowercaseString.php @@ -7,8 +7,12 @@ */ class TNonEmptyLowercaseString extends TNonEmptyString { - public function getId(bool $nested = false): string + public function getId(bool $exact = true, bool $nested = false): string { + if (!$exact) { + return 'string'; + } + return 'non-empty-lowercase-string'; } diff --git a/src/Psalm/Type/Atomic/TNonEmptyMixed.php b/src/Psalm/Type/Atomic/TNonEmptyMixed.php index bbf0ab43697..35bb9076407 100644 --- a/src/Psalm/Type/Atomic/TNonEmptyMixed.php +++ b/src/Psalm/Type/Atomic/TNonEmptyMixed.php @@ -8,7 +8,7 @@ */ class TNonEmptyMixed extends TMixed { - public function getId(bool $nested = false): string + public function getId(bool $exact = true, bool $nested = false): string { return 'non-empty-mixed'; } diff --git a/src/Psalm/Type/Atomic/TNonEmptyNonspecificLiteralString.php b/src/Psalm/Type/Atomic/TNonEmptyNonspecificLiteralString.php index b72b22b8304..6d4630c782e 100644 --- a/src/Psalm/Type/Atomic/TNonEmptyNonspecificLiteralString.php +++ b/src/Psalm/Type/Atomic/TNonEmptyNonspecificLiteralString.php @@ -8,8 +8,12 @@ */ class TNonEmptyNonspecificLiteralString extends TNonspecificLiteralString { - public function getId(bool $nested = false): string + public function getId(bool $exact = true, bool $nested = false): string { + if (!$exact) { + return 'string'; + } + return 'non-empty-literal-string'; } } diff --git a/src/Psalm/Type/Atomic/TNonEmptyScalar.php b/src/Psalm/Type/Atomic/TNonEmptyScalar.php index faa5536a605..f0e9ba43c87 100644 --- a/src/Psalm/Type/Atomic/TNonEmptyScalar.php +++ b/src/Psalm/Type/Atomic/TNonEmptyScalar.php @@ -7,7 +7,7 @@ */ class TNonEmptyScalar extends TScalar { - public function getId(bool $nested = false): string + public function getId(bool $exact = true, bool $nested = false): string { return 'non-empty-scalar'; } diff --git a/src/Psalm/Type/Atomic/TNonEmptyString.php b/src/Psalm/Type/Atomic/TNonEmptyString.php index 4063e48e803..2a1dbdcf8c4 100644 --- a/src/Psalm/Type/Atomic/TNonEmptyString.php +++ b/src/Psalm/Type/Atomic/TNonEmptyString.php @@ -7,8 +7,12 @@ */ class TNonEmptyString extends TString { - public function getId(bool $nested = false): string + public function getId(bool $exact = true, bool $nested = false): string { + if (!$exact) { + return 'string'; + } + return 'non-empty-string'; } } diff --git a/src/Psalm/Type/Atomic/TNonFalsyString.php b/src/Psalm/Type/Atomic/TNonFalsyString.php index 2f583152899..467951c1848 100644 --- a/src/Psalm/Type/Atomic/TNonFalsyString.php +++ b/src/Psalm/Type/Atomic/TNonFalsyString.php @@ -7,8 +7,12 @@ */ class TNonFalsyString extends TNonEmptyString { - public function getId(bool $nested = false): string + public function getId(bool $exact = true, bool $nested = false): string { + if (!$exact) { + return 'string'; + } + return 'non-falsy-string'; } } diff --git a/src/Psalm/Type/Atomic/TNonspecificLiteralInt.php b/src/Psalm/Type/Atomic/TNonspecificLiteralInt.php index 99da2397df4..90ac7892d03 100644 --- a/src/Psalm/Type/Atomic/TNonspecificLiteralInt.php +++ b/src/Psalm/Type/Atomic/TNonspecificLiteralInt.php @@ -8,7 +8,7 @@ */ class TNonspecificLiteralInt extends TInt { - public function __toString(): string + public function getId(bool $exact = true, bool $nested = true): string { return 'literal-int'; } diff --git a/src/Psalm/Type/Atomic/TNonspecificLiteralString.php b/src/Psalm/Type/Atomic/TNonspecificLiteralString.php index e4ea460e2fa..b946f0cc944 100644 --- a/src/Psalm/Type/Atomic/TNonspecificLiteralString.php +++ b/src/Psalm/Type/Atomic/TNonspecificLiteralString.php @@ -8,8 +8,12 @@ */ class TNonspecificLiteralString extends TString { - public function __toString(): string + public function getId(bool $exact = true, bool $nested = true): string { + if (!$exact) { + return 'string'; + } + return 'literal-string'; } diff --git a/src/Psalm/Type/Atomic/TNull.php b/src/Psalm/Type/Atomic/TNull.php index 2efc36d2417..afbbf88293e 100644 --- a/src/Psalm/Type/Atomic/TNull.php +++ b/src/Psalm/Type/Atomic/TNull.php @@ -9,11 +9,6 @@ */ class TNull extends Atomic { - public function __toString(): string - { - return 'null'; - } - public function getKey(bool $include_extra = true): string { return 'null'; diff --git a/src/Psalm/Type/Atomic/TNumeric.php b/src/Psalm/Type/Atomic/TNumeric.php index 6b988210a6d..2a0c70acf7f 100644 --- a/src/Psalm/Type/Atomic/TNumeric.php +++ b/src/Psalm/Type/Atomic/TNumeric.php @@ -7,11 +7,6 @@ */ class TNumeric extends Scalar { - public function __toString(): string - { - return 'numeric'; - } - public function getKey(bool $include_extra = true): string { return 'numeric'; diff --git a/src/Psalm/Type/Atomic/TNumericString.php b/src/Psalm/Type/Atomic/TNumericString.php index b76081311c3..b4d23ec1423 100644 --- a/src/Psalm/Type/Atomic/TNumericString.php +++ b/src/Psalm/Type/Atomic/TNumericString.php @@ -7,19 +7,18 @@ */ class TNumericString extends TNonEmptyString { - public function getKey(bool $include_extra = true): string + public function getId(bool $exact = true, bool $nested = false): string { - return 'numeric-string'; - } + if (!$exact) { + return 'string'; + } - public function __toString(): string - { return 'numeric-string'; } - public function getId(bool $nested = false): string + public function getKey(bool $include_extra = true): string { - return $this->getKey(); + return 'numeric-string'; } public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool diff --git a/src/Psalm/Type/Atomic/TObject.php b/src/Psalm/Type/Atomic/TObject.php index 5b8e81743ed..1725c136869 100644 --- a/src/Psalm/Type/Atomic/TObject.php +++ b/src/Psalm/Type/Atomic/TObject.php @@ -9,11 +9,6 @@ */ class TObject extends Atomic { - public function __toString(): string - { - return 'object'; - } - public function getKey(bool $include_extra = true): string { return 'object'; diff --git a/src/Psalm/Type/Atomic/TObjectWithProperties.php b/src/Psalm/Type/Atomic/TObjectWithProperties.php index 6375fb433a4..a69216820b6 100644 --- a/src/Psalm/Type/Atomic/TObjectWithProperties.php +++ b/src/Psalm/Type/Atomic/TObjectWithProperties.php @@ -46,7 +46,7 @@ public function __construct(array $properties, array $methods = []) $this->methods = $methods; } - public function __toString(): string + public function getId(bool $exact = true, bool $nested = false): string { $extra_types = ''; @@ -60,41 +60,8 @@ public function __toString(): string /** * @param string|int $name */ - fn($name, Union $type): string => $name . ($type->possibly_undefined ? '?' : '') . ':' . $type, - array_keys($this->properties), - $this->properties - ) - ); - - $methods_string = implode( - ', ', - array_map( - fn(string $name): string => $name . '()', - array_keys($this->methods) - ) - ); - - return 'object{' - . $properties_string . ($methods_string && $properties_string ? ', ' : '') - . $methods_string - . '}' . $extra_types; - } - - public function getId(bool $nested = false): string - { - $extra_types = ''; - - if ($this->extra_types) { - $extra_types = '&' . implode('&', $this->extra_types); - } - - $properties_string = implode( - ', ', - array_map( - /** - * @param string|int $name - */ - fn($name, Union $type): string => $name . ($type->possibly_undefined ? '?' : '') . ':' . $type->getId(), + fn($name, Union $type): string => $name . ($type->possibly_undefined ? '?' : '') . ':' + . $type->getId($exact), array_keys($this->properties), $this->properties ) diff --git a/src/Psalm/Type/Atomic/TPositiveInt.php b/src/Psalm/Type/Atomic/TPositiveInt.php index b8335df859a..5cda73c40c7 100644 --- a/src/Psalm/Type/Atomic/TPositiveInt.php +++ b/src/Psalm/Type/Atomic/TPositiveInt.php @@ -7,12 +7,7 @@ */ class TPositiveInt extends TInt { - public function getId(bool $nested = false): string - { - return 'positive-int'; - } - - public function __toString(): string + public function getId(bool $exact = true, bool $nested = false): string { return 'positive-int'; } diff --git a/src/Psalm/Type/Atomic/TResource.php b/src/Psalm/Type/Atomic/TResource.php index 47bde1d24aa..e564ebe4f82 100644 --- a/src/Psalm/Type/Atomic/TResource.php +++ b/src/Psalm/Type/Atomic/TResource.php @@ -9,11 +9,6 @@ */ class TResource extends Atomic { - public function __toString(): string - { - return 'resource'; - } - public function getKey(bool $include_extra = true): string { return 'resource'; diff --git a/src/Psalm/Type/Atomic/TScalar.php b/src/Psalm/Type/Atomic/TScalar.php index a9925e1fec5..5fc10c5b0a8 100644 --- a/src/Psalm/Type/Atomic/TScalar.php +++ b/src/Psalm/Type/Atomic/TScalar.php @@ -8,11 +8,6 @@ */ class TScalar extends Scalar { - public function __toString(): string - { - return 'scalar'; - } - public function getKey(bool $include_extra = true): string { return 'scalar'; diff --git a/src/Psalm/Type/Atomic/TString.php b/src/Psalm/Type/Atomic/TString.php index 88ddebd0a6f..ee08f110f43 100644 --- a/src/Psalm/Type/Atomic/TString.php +++ b/src/Psalm/Type/Atomic/TString.php @@ -19,11 +19,6 @@ public function toPhpString( return $analysis_php_version_id >= 7_00_00 ? 'string' : null; } - public function __toString(): string - { - return 'string'; - } - public function getKey(bool $include_extra = true): string { return 'string'; diff --git a/src/Psalm/Type/Atomic/TTemplateIndexedAccess.php b/src/Psalm/Type/Atomic/TTemplateIndexedAccess.php index 69de28a65d6..22778e60988 100644 --- a/src/Psalm/Type/Atomic/TTemplateIndexedAccess.php +++ b/src/Psalm/Type/Atomic/TTemplateIndexedAccess.php @@ -36,16 +36,6 @@ public function getKey(bool $include_extra = true): string return $this->array_param_name . '[' . $this->offset_param_name . ']'; } - public function __toString(): string - { - return $this->getKey(); - } - - public function getId(bool $nested = false): string - { - return $this->getKey(); - } - /** * @param array $aliased_classes */ diff --git a/src/Psalm/Type/Atomic/TTemplateKeyOf.php b/src/Psalm/Type/Atomic/TTemplateKeyOf.php index 01e1dbcd9a9..8aaed4356d7 100644 --- a/src/Psalm/Type/Atomic/TTemplateKeyOf.php +++ b/src/Psalm/Type/Atomic/TTemplateKeyOf.php @@ -39,14 +39,13 @@ public function getKey(bool $include_extra = true): string return 'key-of<' . $this->param_name . '>'; } - public function __toString(): string + public function getId(bool $exact = true, bool $nested = false): string { - return 'key-of<' . $this->param_name . '>'; - } + if (!$exact) { + return 'key-of<' . $this->param_name . '>'; + } - public function getId(bool $nested = false): string - { - return 'key-of<' . $this->param_name . ':' . $this->defining_class . ' as ' . $this->as->getId() . '>'; + return 'key-of<' . $this->param_name . ':' . $this->defining_class . ' as ' . $this->as->getId($exact) . '>'; } /** diff --git a/src/Psalm/Type/Atomic/TTemplateParam.php b/src/Psalm/Type/Atomic/TTemplateParam.php index 04d4da3b45a..3ce14741fbd 100644 --- a/src/Psalm/Type/Atomic/TTemplateParam.php +++ b/src/Psalm/Type/Atomic/TTemplateParam.php @@ -39,11 +39,6 @@ public function __construct(string $param_name, Union $extends, string $defining $this->defining_class = $defining_class; } - public function __toString(): string - { - return $this->param_name; - } - public function getKey(bool $include_extra = true): string { if ($include_extra && $this->extra_types) { @@ -58,16 +53,20 @@ public function getAssertionString(): string return $this->as->getId(); } - public function getId(bool $nested = false): string + public function getId(bool $exact = true, bool $nested = false): string { + if (!$exact) { + return $this->param_name; + } + if ($this->extra_types) { - return '(' . $this->param_name . ':' . $this->defining_class . ' as ' . $this->as->getId() - . ')&' . implode('&', array_map(fn($type) => $type->getId(true), $this->extra_types)); + return '(' . $this->param_name . ':' . $this->defining_class . ' as ' . $this->as->getId($exact) + . ')&' . implode('&', array_map(fn($type) => $type->getId($exact, true), $this->extra_types)); } return ($nested ? '(' : '') . $this->param_name . ':' . $this->defining_class - . ' as ' . $this->as->getId() . ($nested ? ')' : ''); + . ' as ' . $this->as->getId($exact) . ($nested ? ')' : ''); } /** diff --git a/src/Psalm/Type/Atomic/TTemplateParamClass.php b/src/Psalm/Type/Atomic/TTemplateParamClass.php index 02bb55464a2..2a46c0a49ba 100644 --- a/src/Psalm/Type/Atomic/TTemplateParamClass.php +++ b/src/Psalm/Type/Atomic/TTemplateParamClass.php @@ -34,15 +34,10 @@ public function getKey(bool $include_extra = true): string return 'class-string<' . $this->param_name . '>'; } - public function __toString(): string - { - return 'class-string<' . $this->param_name . '>'; - } - - public function getId(bool $nested = false): string + public function getId(bool $exact = true, bool $nested = false): string { return 'class-string<' . $this->param_name . ':' . $this->defining_class - . ' as ' . ($this->as_type ? $this->as_type->getId() : $this->as) . '>'; + . ' as ' . ($this->as_type ? $this->as_type->getId($exact) : $this->as) . '>'; } public function getAssertionString(): string diff --git a/src/Psalm/Type/Atomic/TTraitString.php b/src/Psalm/Type/Atomic/TTraitString.php index d06a057ec34..59aa4f03c51 100644 --- a/src/Psalm/Type/Atomic/TTraitString.php +++ b/src/Psalm/Type/Atomic/TTraitString.php @@ -12,16 +12,6 @@ public function getKey(bool $include_extra = true): string return 'trait-string'; } - public function __toString(): string - { - return $this->getKey(); - } - - public function getId(bool $nested = false): string - { - return $this->getKey(); - } - /** * @param array $aliased_classes */ diff --git a/src/Psalm/Type/Atomic/TTrue.php b/src/Psalm/Type/Atomic/TTrue.php index 637e52ba24b..911b062278b 100644 --- a/src/Psalm/Type/Atomic/TTrue.php +++ b/src/Psalm/Type/Atomic/TTrue.php @@ -7,11 +7,6 @@ */ class TTrue extends TBool { - public function __toString(): string - { - return 'true'; - } - public function getKey(bool $include_extra = true): string { return 'true'; diff --git a/src/Psalm/Type/Atomic/TTypeAlias.php b/src/Psalm/Type/Atomic/TTypeAlias.php index e90dc1271a9..b7b9d2c2515 100644 --- a/src/Psalm/Type/Atomic/TTypeAlias.php +++ b/src/Psalm/Type/Atomic/TTypeAlias.php @@ -31,28 +31,13 @@ public function getKey(bool $include_extra = true): string return 'type-alias(' . $this->declaring_fq_classlike_name . '::' . $this->alias_name . ')'; } - public function __toString(): string + public function getId(bool $exact = true, bool $nested = false): string { if ($this->extra_types) { return $this->getKey() . '&' . implode( '&', array_map( - 'strval', - $this->extra_types - ) - ); - } - - return $this->getKey(); - } - - public function getId(bool $nested = false): string - { - if ($this->extra_types) { - return $this->getKey() . '&' . implode( - '&', - array_map( - fn($type) => $type->getId(true), + fn($type) => $type->getId($exact, true), $this->extra_types ) ); diff --git a/src/Psalm/Type/Atomic/TValueOfClassConstant.php b/src/Psalm/Type/Atomic/TValueOfClassConstant.php index 1c5c23834ab..6f4afc9c5e0 100644 --- a/src/Psalm/Type/Atomic/TValueOfClassConstant.php +++ b/src/Psalm/Type/Atomic/TValueOfClassConstant.php @@ -27,16 +27,6 @@ public function getKey(bool $include_extra = true): string return 'value-of<' . $this->fq_classlike_name . '::' . $this->const_name . '>'; } - public function __toString(): string - { - return 'value-of<' . $this->fq_classlike_name . '::' . $this->const_name . '>'; - } - - public function getId(bool $nested = false): string - { - return $this->getKey(); - } - /** * @param array $aliased_classes */ diff --git a/src/Psalm/Type/Atomic/TVoid.php b/src/Psalm/Type/Atomic/TVoid.php index 9c5eb290f9c..4efdd4587c1 100644 --- a/src/Psalm/Type/Atomic/TVoid.php +++ b/src/Psalm/Type/Atomic/TVoid.php @@ -9,11 +9,6 @@ */ class TVoid extends Atomic { - public function __toString(): string - { - return 'void'; - } - public function getKey(bool $include_extra = true): string { return 'void'; diff --git a/src/Psalm/Type/Union.php b/src/Psalm/Type/Union.php index 479bfbdd630..84e8cdb0c2b 100644 --- a/src/Psalm/Type/Union.php +++ b/src/Psalm/Type/Union.php @@ -212,9 +212,19 @@ class Union implements TypeNode */ public $has_mutations = true; - /** @var null|string */ + /** + * This is a cache of getId on non-exact mode + * @var null|string + */ private $id; + /** + * This is a cache of getId on exact mode + * @var null|string + */ + private $exact_id; + + /** * @var array */ @@ -311,7 +321,7 @@ public function addType(Atomic $type): void } } - $this->id = null; + $this->bustCache(); } public function __clone() @@ -367,7 +377,7 @@ public function __toString(): string $printed_int = true; } - $types[] = (string)$type; + $types[] = $type->getId(false); } sort($types); @@ -413,16 +423,19 @@ public function getKey(): string return implode('|', $types); } - public function getId(): string + public function getId(bool $exact = true): string { - if ($this->id) { + if ($exact && $this->exact_id) { + return $this->exact_id; + } elseif (!$exact && $this->id) { return $this->id; } $types = []; foreach ($this->types as $type) { - $types[] = $type->getId(); + $types[] = $type->getId($exact); } + $types = array_unique($types); sort($types); if (count($types) > 1) { @@ -435,7 +448,11 @@ public function getId(): string $id = implode('|', $types); - $this->id = $id; + if ($exact) { + $this->exact_id = $id; + } else { + $this->id = $id; + } return $id; } @@ -597,7 +614,7 @@ public function removeType(string $type_string): bool ); } - $this->id = null; + $this->bustCache(); return true; } @@ -636,6 +653,7 @@ public function removeType(string $type_string): bool public function bustCache(): void { $this->id = null; + $this->exact_id = null; } public function hasType(string $type_string): bool @@ -1086,7 +1104,7 @@ public function substitute(Union $old_type, ?Union $new_type = null): void $this->types['mixed'] = new TMixed(); } - $this->id = null; + $this->bustCache(); } public function isSingle(): bool @@ -1427,6 +1445,10 @@ public function equals(Union $other_type, bool $ensure_source_equality = true): return false; } + if ($other_type->exact_id && $this->exact_id && $other_type->exact_id !== $this->exact_id) { + return false; + } + if ($this->possibly_undefined !== $other_type->possibly_undefined) { return false; } diff --git a/tests/ArrayAccessTest.php b/tests/ArrayAccessTest.php index eef2404dd00..d368979b190 100644 --- a/tests/ArrayAccessTest.php +++ b/tests/ArrayAccessTest.php @@ -1105,7 +1105,7 @@ function f($p): int { $a = ["a", "b"]; unset($a[0]); ', - 'assertions' => ['$a===' => 'array{1: "b"}'] + 'assertions' => ['$a===' => "array{1: 'b'}"] ], ]; } diff --git a/tests/ArrayFunctionCallTest.php b/tests/ArrayFunctionCallTest.php index 428e80d9ece..9e79fc07457 100644 --- a/tests/ArrayFunctionCallTest.php +++ b/tests/ArrayFunctionCallTest.php @@ -824,7 +824,7 @@ function (string $key): bool { ARRAY_FILTER_USE_KEY );', 'assertions' => [ - '$foo' => 'array', + '$foo' => 'array', ], ], 'ignoreFalsableCurrent' => [ diff --git a/tests/CallableTest.php b/tests/CallableTest.php index d760115f2c5..5e09cbf8b5c 100644 --- a/tests/CallableTest.php +++ b/tests/CallableTest.php @@ -671,12 +671,12 @@ function baz(string $a): string { $e = array_map([$a_instance, "bar"], ["one", "two"]); $f = array_map("baz", ["one", "two"]);', 'assertions' => [ - '$a' => 'array{string, string}', - '$b' => 'array{string, string}', - '$c' => 'array{string, string}', - '$d' => 'array{string, string}', - '$e' => 'array{string, string}', - '$f' => 'array{string, string}', + '$a' => 'array{string, string}', + '$b' => 'array{string, string}', + '$c' => 'array{string, string}', + '$d' => 'array{string, string}', + '$e' => 'array{string, string}', + '$f' => 'array{string, string}', ], ], 'arrayCallableMethod' => [ diff --git a/tests/ClosureTest.php b/tests/ClosureTest.php index 6a1e79c45f4..83e1365aa84 100644 --- a/tests/ClosureTest.php +++ b/tests/ClosureTest.php @@ -98,7 +98,7 @@ function(string $a) { $mirror = function(int $i) : int { return $i; }; $a = array_map($mirror, [1, 2, 3]);', 'assertions' => [ - '$a' => 'array{int, int, int}', + '$a' => 'array{int, int, int}', ], ], 'inlineCallableFunction' => [ @@ -344,7 +344,7 @@ function acceptsIntToBool(Closure $c): void {} $a = function() : Closure { return function() : string { return "hello"; }; }; $b = $a()();', 'assertions' => [ - '$a' => 'pure-Closure():pure-Closure():"hello"', + '$a' => 'pure-Closure():pure-Closure():string', '$b' => 'string', ], ], @@ -418,7 +418,7 @@ public function test() : Closure { $closure = Closure::fromCallable("strlen"); ', 'assertions' => [ - '$closure' => 'pure-Closure(string):(0|positive-int)', + '$closure' => 'pure-Closure(string):(int|positive-int)', ] ], 'allowClosureWithNarrowerReturn' => [ @@ -562,7 +562,7 @@ function maker(string $className) { $maker = maker(stdClass::class); $result = array_map($maker, ["abc"]);', 'assertions' => [ - '$result' => 'array{stdClass}' + '$result' => 'array{stdClass}' ], ], 'FirstClassCallable:NamedFunction:is_int' => [ @@ -583,7 +583,7 @@ function maker(string $className) { $result = $closure("test"); ', 'assertions' => [ - '$closure' => 'pure-Closure(string):(0|positive-int)', + '$closure' => 'pure-Closure(string):(int|positive-int)', '$result' => 'int|positive-int', ], 'ignored_issues' => [], @@ -660,7 +660,7 @@ public function __invoke(string $param): int { $closure = $closure(...); ', 'assertions' => [ - '$closure' => 'pure-Closure(string):(0|positive-int)', + '$closure' => 'pure-Closure(string):(int|positive-int)', ], 'ignored_issues' => [], 'php_version' => '8.1' @@ -722,9 +722,9 @@ public static function __callStatic(string $name, array $args): mixed { $result3 = array_map($closure(...), $array); ', 'assertions' => [ - '$result1' => 'array{null, null, null}', - '$result2' => 'array{string, string, string}', - '$result3' => 'array{int, int, int}', + '$result1' => 'array{null, null, null}', + '$result2' => 'array{string, string, string}', + '$result3' => 'array{int, int, int}', ], 'ignored_issues' => [], 'php_version' => '8.1' diff --git a/tests/Config/Plugin/Hook/StringProvider/TSqlSelectString.php b/tests/Config/Plugin/Hook/StringProvider/TSqlSelectString.php index 4be059215ef..41ab00d138d 100644 --- a/tests/Config/Plugin/Hook/StringProvider/TSqlSelectString.php +++ b/tests/Config/Plugin/Hook/StringProvider/TSqlSelectString.php @@ -14,7 +14,7 @@ public function getKey(bool $include_extra = true): string return 'sql-select-string'; } - public function getId(bool $nested = true): string + public function getId(bool $exact = true, bool $nested = true): string { return 'sql-select-string(' . $this->value . ')'; } diff --git a/tests/ConstantTest.php b/tests/ConstantTest.php index 3b63517821c..b03a87250d4 100644 --- a/tests/ConstantTest.php +++ b/tests/ConstantTest.php @@ -327,7 +327,7 @@ class Foo $foo = new Foo(); $_trace = $foo::BAR;', - 'assertions' => ['$_trace===' => '"bar"'], + 'assertions' => ['$_trace===' => "'bar'"], ], 'unsafeInferenceClassConstFetch' => [ 'code' => ' ['$_trace===' => '"bar"'], + 'assertions' => ['$_trace===' => "'bar'"], ], 'dynamicClassConstFetchClassString' => [ 'code' => ' [ - '$arr===' => 'array{10: "aa", 11: "zz", 5: "a", 6: "z"}', + '$arr===' => "array{10: 'aa', 11: 'zz', 5: 'a', 6: 'z'}", ], ], 'arrayKeysSequenceContinuesAfterNonIntKey' => [ @@ -1160,7 +1160,7 @@ class C { $arr = C::A; ', 'assertions' => [ - '$arr===' => 'array{5: "a", 6: "aa", zz: "z"}', + '$arr===' => "array{5: 'a', 6: 'aa', zz: 'z'}", ], ], 'unresolvedConstWithUnaryMinus' => [ diff --git a/tests/EnumTest.php b/tests/EnumTest.php index 66b4b7105cb..136bcc4df49 100644 --- a/tests/EnumTest.php +++ b/tests/EnumTest.php @@ -114,7 +114,7 @@ enum Status $a = Status::DRAFT->name; ', 'assertions' => [ - '$a===' => '"DRAFT"', + '$a===' => "'DRAFT'", ], 'ignored_issues' => [], 'php_version' => '8.1' diff --git a/tests/FunctionCallTest.php b/tests/FunctionCallTest.php index 48193fe1d83..df940d6faea 100644 --- a/tests/FunctionCallTest.php +++ b/tests/FunctionCallTest.php @@ -1490,12 +1490,12 @@ function test() : void { /** @psalm-suppress MixedArgument */ $F3 = date("F", $_GET["F3"]);', 'assertions' => [ - '$y' => 'numeric-string', - '$m' => 'numeric-string', - '$F' => 'string', - '$y2' => 'numeric-string', - '$F2' => 'string', - '$F3' => 'false|string', + '$y===' => 'numeric-string', + '$m===' => 'numeric-string', + '$F===' => 'string', + '$y2===' => 'numeric-string', + '$F2===' => 'string', + '$F3===' => 'false|string', ] ], 'sscanfReturnTypeWithTwoParameters' => [ diff --git a/tests/GeneratorTest.php b/tests/GeneratorTest.php index 3528d2e78c4..12ca3020f04 100644 --- a/tests/GeneratorTest.php +++ b/tests/GeneratorTest.php @@ -296,7 +296,7 @@ function generator(): Generator $_a = function() { return new RuntimeException(yield "a"); }; ', 'assertions' => [ - '$_a' => 'pure-Closure():Generator', + '$_a' => 'pure-Closure():Generator', ] ], 'detectYieldInArray' => [ @@ -305,7 +305,7 @@ function generator(): Generator $_a = function() { return [yield "a"]; }; ', 'assertions' => [ - '$_a' => 'pure-Closure():Generator', + '$_a' => 'pure-Closure():Generator', ] ], ]; diff --git a/tests/IntRangeTest.php b/tests/IntRangeTest.php index 4d5a0cba237..e77db5a1309 100644 --- a/tests/IntRangeTest.php +++ b/tests/IntRangeTest.php @@ -403,7 +403,7 @@ function getInt() $a = getInt(); $_arr[$a] = 12;', 'assertions' => [ - '$_arr===' => 'non-empty-array, "a"|"b"|"c"|12>' + '$_arr===' => "non-empty-array, 'a'|'b'|'c'|12>" ] ], 'integrateExistingArrayNegative' => [ @@ -418,7 +418,7 @@ function getInt() $a = getInt(); $_arr[$a] = 12;', 'assertions' => [ - '$_arr===' => 'non-empty-array, "a"|"b"|"c"|12>' + '$_arr===' => "non-empty-array, 'a'|'b'|'c'|12>" ] ], 'SKIPPED-statementsInLoopAffectsEverything' => [ diff --git a/tests/JsonOutputTest.php b/tests/JsonOutputTest.php index 8a4c84c2bdf..3341dfdf331 100644 --- a/tests/JsonOutputTest.php +++ b/tests/JsonOutputTest.php @@ -104,7 +104,7 @@ function fooFoo(Badger\Bodger $a): Badger\Bodger { function fooFoo() { return "hello"; }', - 'message' => 'Method fooFoo does not have a return type, expecting "hello"', + 'message' => "Method fooFoo does not have a return type, expecting 'hello'", 'line' => 2, 'error' => 'fooFoo', ], @@ -116,7 +116,7 @@ function fooFoo() { function fooFoo() { return "hello"; }', - 'message' => "The inferred type '\"hello\"' does not match the declared return type 'int' for fooFoo", + 'message' => "The inferred type ''hello'' does not match the declared return type 'int' for fooFoo", 'line' => 6, 'error' => '"hello"', ], diff --git a/tests/MagicMethodAnnotationTest.php b/tests/MagicMethodAnnotationTest.php index 9764bb2086f..d024c46a752 100644 --- a/tests/MagicMethodAnnotationTest.php +++ b/tests/MagicMethodAnnotationTest.php @@ -845,8 +845,8 @@ class B {} /** @var I $i */ $c = $i->foo();', [ - '$b' => 'A', - '$c' => 'I', + '$b' => 'A&static', + '$c' => 'I&static', ] ], 'genericsOfInheritedMethodsShouldBeResolved' => [ diff --git a/tests/ReturnTypeTest.php b/tests/ReturnTypeTest.php index 8e752c79a8a..cf9ab2a46da 100644 --- a/tests/ReturnTypeTest.php +++ b/tests/ReturnTypeTest.php @@ -768,7 +768,7 @@ function map(callable $predicate): callable { $res = map(function(int $i): string { return (string) $i; })([1,2,3]); ', 'assertions' => [ - '$res' => 'iterable', + '$res===' => 'iterable', ], ], 'infersArrowClosureReturnTypes' => [ @@ -808,7 +808,7 @@ function map(callable $predicate): callable { $res = map(function(int $i): string { return (string) $i; })([1,2,3]); ', 'assertions' => [ - '$res' => 'iterable', + '$res===' => 'iterable', ], ], 'infersCallableReturnTypes' => [ @@ -830,7 +830,7 @@ function map(callable $predicate): callable { $res = map(function(int $i): string { return (string) $i; })([1,2,3]); ', 'assertions' => [ - '$res' => 'iterable', + '$res===' => 'iterable', ], ], 'infersCallableReturnTypesWithPartialTypehinting' => [ @@ -852,7 +852,7 @@ function map(callable $predicate): callable { $res = map(function(int $i): string { return (string) $i; })([1,2,3]); ', 'assertions' => [ - '$res' => 'iterable', + '$res===' => 'iterable', ], ], 'mixedAssignmentWithUnderscore' => [ diff --git a/tests/Template/ClassTemplateTest.php b/tests/Template/ClassTemplateTest.php index 4c058f6eb43..d7ed98473e4 100644 --- a/tests/Template/ClassTemplateTest.php +++ b/tests/Template/ClassTemplateTest.php @@ -1049,7 +1049,7 @@ function __construct(string $t = "hello") { $c = new C();', 'assertions' => [ - '$c===' => 'C<"hello">', + '$c===' => "C<'hello'>", ], ], 'SKIPPED-templateDefaultConstant' => [ @@ -3921,7 +3921,7 @@ class CharacterRow extends Row {} $mario = new CharacterRow(["id" => 5, "name" => "Mario", "height" => 3.5]); $mario->ame = "Luigi";', - 'error_message' => 'InvalidArgument - src' . DIRECTORY_SEPARATOR . 'somefile.php:47:29 - Argument 1 of CharacterRow::__set expects "height"|"id"|"name", "ame" provided', + 'error_message' => 'InvalidArgument - src' . DIRECTORY_SEPARATOR . "somefile.php:47:29 - Argument 1 of CharacterRow::__set expects 'height'|'id'|'name', 'ame' provided", ], 'specialiseTypeBeforeReturning' => [ 'code' => 'vars_in_scope[$var])) { + $value = $context->vars_in_scope[$var]->getId($exact); if ($exact) { - $actual_vars[$var . '==='] = $context->vars_in_scope[$var]->getId(); + $actual_vars[$var . '==='] = $value; } else { - $actual_vars[$var] = (string)$context->vars_in_scope[$var]; + $actual_vars[$var] = $value; } } } diff --git a/tests/TypeCombinationTest.php b/tests/TypeCombinationTest.php index 022cccfe3f3..dc73951f9f4 100644 --- a/tests/TypeCombinationTest.php +++ b/tests/TypeCombinationTest.php @@ -370,28 +370,28 @@ public function providerTestValidTypeCombination(): array ], ], 'combineObjectTypeWithIntKeyedArray' => [ - 'array<"a"|int, int|string>', + "array<'a'|int, int|string>", [ 'array{a: int}', 'array', ], ], 'combineNestedObjectTypeWithTKeyedArrayIntKeyedArray' => [ - 'array{a: array<"a"|int, int|string>}', + "array{a: array<'a'|int, int|string>}", [ 'array{a: array{a: int}}', 'array{a: array}', ], ], 'combineIntKeyedObjectTypeWithNestedIntKeyedArray' => [ - 'array>', + "array>", [ 'array', 'array>', ], ], 'combineNestedObjectTypeWithNestedIntKeyedArray' => [ - 'array<"a"|int, array<"a"|int, int|string>>', + "array<'a'|int, array<'a'|int, int|string>>", [ 'array{a: array{a: int}}', 'array>', @@ -462,7 +462,7 @@ public function providerTestValidTypeCombination(): array ], ], 'objectLikePlusArrayEqualsArray' => [ - 'array<"a"|"b"|"c", 1|2|3>', + "array<'a'|'b'|'c', 1|2|3>", [ 'array<"a"|"b"|"c", 1|2|3>', 'array{a: 1|2, b: 2|3, c: 1|3}', diff --git a/tests/TypeParseTest.php b/tests/TypeParseTest.php index d2f29297ecc..00186b2b0b3 100644 --- a/tests/TypeParseTest.php +++ b/tests/TypeParseTest.php @@ -516,7 +516,7 @@ public function testConditionalTypeWithUnion(): void { $this->assertSame( '(T is string|true ? int|string : int)', - (string) Type::parseString('(T is "hello"|true ? string|int : int)', null, ['T' => ['' => Type::getArray()]]) + Type::parseString('(T is "hello"|true ? string|int : int)', null, ['T' => ['' => Type::getArray()]])->getId(false) ); } @@ -733,7 +733,7 @@ public function testCallableWithoutReturn(): void public function testCombineLiteralStringWithClassString(): void { $this->assertSame( - '"array"|class-string', + "'array'|class-string", Type::parseString('"array"|class-string')->getId() ); } @@ -758,7 +758,7 @@ public function testKeyOfTemplate(): void { $this->assertSame( 'key-of', - (string)Type::parseString('key-of', null, ['T' => ['' => Type::getArray()]]) + Type::parseString('key-of', null, ['T' => ['' => Type::getArray()]])->getId(false) ); } @@ -791,7 +791,7 @@ public function testClassStringMap(): void { $this->assertSame( 'class-string-map', - (string)Type::parseString('class-string-map') + Type::parseString('class-string-map')->getId(false) ); } @@ -881,15 +881,15 @@ public function testLongUtf8LiteralString(): void $string = "АаБбВвГгДдЕеЁёЖжЗзИиЙйКкЛлМмНнОоПпРрСсТтУуФфХхЦцЧчШшЩщЪъЫыЬьЭэЮюЯя"; $string .= $string; $expected = mb_substr($string, 0, 80); - $this->assertSame("\"$expected...\"", Type::parseString("'$string'")->getId()); - $this->assertSame("\"$expected...\"", Type::parseString("\"$string\"")->getId()); + $this->assertSame("'$expected...'", Type::parseString("'$string'")->getId()); + $this->assertSame("'$expected...'", Type::parseString("\"$string\"")->getId()); } public function testSingleLiteralString(): void { $this->assertSame( - 'string', - (string)Type::parseString('"var"') + "'var'", + Type::parseString('"var"')->getId() ); } @@ -904,16 +904,16 @@ public function testEmptyArrayShape(): void public function testSingleLiteralInt(): void { $this->assertSame( - 'int', - (string)Type::parseString('6') + '6', + Type::parseString('6')->getId() ); } public function testSingleLiteralFloat(): void { $this->assertSame( - 'float', - (string)Type::parseString('6.315') + 'float(6.315)', + Type::parseString('6.315')->getId() ); } diff --git a/tests/TypeReconciliation/ConditionalTest.php b/tests/TypeReconciliation/ConditionalTest.php index a67be8b687c..f9b18f2f8c5 100644 --- a/tests/TypeReconciliation/ConditionalTest.php +++ b/tests/TypeReconciliation/ConditionalTest.php @@ -2679,7 +2679,7 @@ function ($_valid): void {}; $b = rand(0,1) ? "" : "a"; $b === "a" ? $_a = "Y" : $_a = "N";', 'assertions' => [ - '$_a===' => '"N"|"Y"', + '$_a===' => "'N'|'Y'", ] ], 'assertionsWorksBothWays' => [ diff --git a/tests/TypeReconciliation/ReconcilerTest.php b/tests/TypeReconciliation/ReconcilerTest.php index 4b25ae69093..1d8ebde693d 100644 --- a/tests/TypeReconciliation/ReconcilerTest.php +++ b/tests/TypeReconciliation/ReconcilerTest.php @@ -130,7 +130,7 @@ public function providerTestReconcilation(): array 'falsyWithSomeClassPipeBool' => ['false', new Falsy(), 'SomeClass|bool'], 'falsyWithMixed' => ['empty-mixed', new Falsy(), 'mixed'], 'falsyWithBool' => ['false', new Falsy(), 'bool'], - 'falsyWithStringOrNull' => ['""|"0"|null', new Falsy(), 'string|null'], + 'falsyWithStringOrNull' => ["''|'0'|null", new Falsy(), 'string|null'], 'falsyWithScalarOrNull' => ['empty-scalar', new Falsy(), 'scalar'], 'trueWithBool' => ['true', new IsType(new TTrue()), 'bool'], 'falseWithBool' => ['false', new IsType(new TFalse()), 'bool'], @@ -261,23 +261,23 @@ public function constantAssertions(): array return [ 'constant-with-prefix' => [ new IsType(new TClassConstant('ReconciliationTest\\Foo', 'PREFIX_*')), - '"bar"|"baz"', + "'bar'|'baz'", ], 'single-class-constant' => [ new IsType(new TClassConstant('ReconciliationTest\\Foo', 'PREFIX_BAR')), - '"bar"', + "'bar'", ], 'referencing-another-class-constant' => [ new IsType(new TClassConstant('ReconciliationTest\\Foo', 'PREFIX_QOO')), - '"bar"', + "'bar'", ], 'referencing-all-class-constants' => [ new IsType(new TClassConstant('ReconciliationTest\\Foo', '*')), - '"bar"|"baz"', + "'bar'|'baz'", ], 'referencing-some-class-constants-with-wildcard' => [ new IsType(new TClassConstant('ReconciliationTest\\Foo', 'PREFIX_B*')), - '"bar"|"baz"', + "'bar'|'baz'", ], ]; }