From 835466f1d528fc3dba6d3f78e8de87ce17aa39e8 Mon Sep 17 00:00:00 2001 From: Ivan Fedorov Date: Wed, 30 Jun 2021 20:05:44 +0300 Subject: [PATCH] change nullable types to union types in attributes --- PDO/PDO.php | 2 +- Phar/Phar.php | 2 +- SPL/SPL.php | 2 +- dom/dom_c.php | 78 ++++++++++++++++++------------------ gettext/gettext.php | 4 +- intl/intl.php | 4 +- mysqli/mysqli.php | 16 ++++---- soap/soap.php | 4 +- tests/BaseStubsTest.php | 11 +++++ tests/StubsTest.php | 22 +++++++--- tests/StubsTypeHintsTest.php | 11 ----- 11 files changed, 84 insertions(+), 72 deletions(-) diff --git a/PDO/PDO.php b/PDO/PDO.php index 1802f7d6..67739789 100644 --- a/PDO/PDO.php +++ b/PDO/PDO.php @@ -15,7 +15,7 @@ use JetBrains\PhpStorm\Pure; */ class PDOException extends RuntimeException { - #[LanguageLevelTypeAware(['8.1' => '?array'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'array|null'], default: '')] public $errorInfo; } diff --git a/Phar/Phar.php b/Phar/Phar.php index a41c7296..c8d01397 100644 --- a/Phar/Phar.php +++ b/Phar/Phar.php @@ -808,7 +808,7 @@ class Phar extends RecursiveDirectoryIterator implements RecursiveIterator, Seek final public static function webPhar( ?string $alias = null, ?string $index = "index.php", - #[LanguageLevelTypeAware(['8.0' => '?string'], default: 'string')] $fileNotFoundScript = null, + #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: 'string')] $fileNotFoundScript = null, array $mimeTypes = null, ?callable $rewrite = null ) {} diff --git a/SPL/SPL.php b/SPL/SPL.php index 81aa7469..7ba2d27a 100644 --- a/SPL/SPL.php +++ b/SPL/SPL.php @@ -1075,7 +1075,7 @@ class RegexIterator extends FilterIterator public const INVERT_MATCH = 2; - #[LanguageLevelTypeAware(['8.1' => '?string'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $replacement; /** diff --git a/dom/dom_c.php b/dom/dom_c.php index 93fe9fb8..a6ea8349 100644 --- a/dom/dom_c.php +++ b/dom/dom_c.php @@ -23,7 +23,7 @@ class DOMNode * The value of this node, depending on its type * @link https://php.net/manual/en/class.domnode.php#domnode.props.nodevalue */ - #[LanguageLevelTypeAware(['8.1' => '?string'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $nodeValue; /** @@ -40,7 +40,7 @@ class DOMNode * The parent of this node. If there is no such node, this returns NULL. * @link https://php.net/manual/en/class.domnode.php#domnode.props.parentnode */ - #[LanguageLevelTypeAware(['8.1' => '?DOMNode'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'DOMNode|null'], default: '')] public $parentNode; /** @@ -56,7 +56,7 @@ class DOMNode * The first child of this node. If there is no such node, this returns NULL. * @link https://php.net/manual/en/class.domnode.php#domnode.props.firstchild */ - #[LanguageLevelTypeAware(['8.1' => '?DOMNode'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'DOMNode|null'], default: '')] public $firstChild; /** @@ -64,7 +64,7 @@ class DOMNode * The last child of this node. If there is no such node, this returns NULL. * @link https://php.net/manual/en/class.domnode.php#domnode.props.lastchild */ - #[LanguageLevelTypeAware(['8.1' => '?DOMNode'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'DOMNode|null'], default: '')] public $lastChild; /** @@ -72,7 +72,7 @@ class DOMNode * The node immediately preceding this node. If there is no such node, this returns NULL. * @link https://php.net/manual/en/class.domnode.php#domnode.props.previoussibling */ - #[LanguageLevelTypeAware(['8.1' => '?DOMNode'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'DOMNode|null'], default: '')] public $previousSibling; /** @@ -80,7 +80,7 @@ class DOMNode * The node immediately following this node. If there is no such node, this returns NULL. * @link https://php.net/manual/en/class.domnode.php#domnode.props.nextsibling */ - #[LanguageLevelTypeAware(['8.1' => '?DOMNode'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'DOMNode|null'], default: '')] public $nextSibling; /** @@ -88,7 +88,7 @@ class DOMNode * A DOMNamedNodeMap containing the attributes of this node (if it is a DOMElement) or NULL otherwise. * @link https://php.net/manual/en/class.domnode.php#domnode.props.attributes */ - #[LanguageLevelTypeAware(['8.1' => '?DOMNamedNodeMap'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'DOMNamedNodeMap|null'], default: '')] public $attributes; /** @@ -96,7 +96,7 @@ class DOMNode * The DOMDocument object associated with this node, or NULL if this node is a DOMDocument. * @link https://php.net/manual/en/class.domnode.php#domnode.props.ownerdocument */ - #[LanguageLevelTypeAware(['8.1' => '?DOMDocument'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'DOMDocument|null'], default: '')] public $ownerDocument; /** @@ -104,7 +104,7 @@ class DOMNode * The namespace URI of this node, or NULL if it is unspecified. * @link https://php.net/manual/en/class.domnode.php#domnode.props.namespaceuri */ - #[LanguageLevelTypeAware(['8.1' => '?string'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $namespaceURI; /** @@ -120,7 +120,7 @@ class DOMNode * Returns the local part of the qualified name of this node. * @link https://php.net/manual/en/class.domnode.php#domnode.props.localname */ - #[LanguageLevelTypeAware(['8.1' => '?string'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $localName; /** @@ -128,7 +128,7 @@ class DOMNode * The absolute base URI of this node or NULL if the implementation wasn't able to obtain an absolute URI. * @link https://php.net/manual/en/class.domnode.php#domnode.props.baseuri */ - #[LanguageLevelTypeAware(['8.1' => '?string'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $baseURI; /** @@ -491,19 +491,19 @@ class DOMImplementation class DOMNameSpaceNode { - #[LanguageLevelTypeAware(['8.1' => '?DOMNode'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'DOMNode|null'], default: '')] public $parentNode; - #[LanguageLevelTypeAware(['8.1' => '?DOMDocument'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'DOMDocument|null'], default: '')] public $ownerDocument; - #[LanguageLevelTypeAware(['8.1' => '?string'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $namespaceURI; - #[LanguageLevelTypeAware(['8.1' => '?string'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $localName; #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $prefix; #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $nodeType; - #[LanguageLevelTypeAware(['8.1' => '?string'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $nodeValue; #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $nodeName; @@ -518,10 +518,10 @@ class DOMDocumentFragment extends DOMNode implements DOMParentNode #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $childElementCount; - #[LanguageLevelTypeAware(['8.1' => '?DOMElement'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'DOMElement|null'], default: '')] public $lastElementChild; - #[LanguageLevelTypeAware(['8.1' => '?DOMElement'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'DOMElement|null'], default: '')] public $firstElementChild; public function __construct() {} @@ -559,7 +559,7 @@ class DOMDocument extends DOMNode implements DOMParentNode * @link https://php.net/manual/en/class.domdocument.php#domdocument.props.actualencoding */ #[Deprecated("Actual encoding of the document, is a readonly equivalent to encoding.")] - #[LanguageLevelTypeAware(['8.1' => '?string'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $actualEncoding; /** @@ -576,7 +576,7 @@ class DOMDocument extends DOMNode implements DOMParentNode * The Document Type Declaration associated with this document. * @link https://php.net/manual/en/class.domdocument.php#domdocument.props.doctype */ - #[LanguageLevelTypeAware(['8.1' => '?DOMDocumentType'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'DOMDocumentType|null'], default: '')] public $doctype; /** @@ -585,7 +585,7 @@ class DOMDocument extends DOMNode implements DOMParentNode * that is the document element of the document. * @link https://php.net/manual/en/class.domdocument.php#domdocument.props.documentelement */ - #[LanguageLevelTypeAware(['8.1' => '?DOMElement'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'DOMElement|null'], default: '')] public $documentElement; /** @@ -593,7 +593,7 @@ class DOMDocument extends DOMNode implements DOMParentNode * The location of the document or NULL if undefined. * @link https://php.net/manual/en/class.domdocument.php#domdocument.props.documenturi */ - #[LanguageLevelTypeAware(['8.1' => '?string'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $documentURI; /** @@ -603,7 +603,7 @@ class DOMDocument extends DOMNode implements DOMParentNode * encoding in this implementation. * @link https://php.net/manual/en/class.domdocument.php#domdocument.props.encoding */ - #[LanguageLevelTypeAware(['8.1' => '?string'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $encoding; /** @@ -686,7 +686,7 @@ class DOMDocument extends DOMNode implements DOMParentNode * @link https://php.net/manual/en/class.domdocument.php#domdocument.props.version */ #[Deprecated('Version of XML, corresponds to xmlVersion')] - #[LanguageLevelTypeAware(['8.1' => '?string'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $version; /** @@ -695,7 +695,7 @@ class DOMDocument extends DOMNode implements DOMParentNode * unspecified or when it is not known, such as when the Document was created in memory. * @link https://php.net/manual/en/class.domdocument.php#domdocument.props.xmlencoding */ - #[LanguageLevelTypeAware(['8.1' => '?string'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $xmlEncoding; /** @@ -713,16 +713,16 @@ class DOMDocument extends DOMNode implements DOMParentNode * declaration and if this document supports the "XML" feature, the value is "1.0". * @link https://php.net/manual/en/class.domdocument.php#domdocument.props.xmlversion */ - #[LanguageLevelTypeAware(['8.1' => '?string'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $xmlVersion; #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $childElementCount; - #[LanguageLevelTypeAware(['8.1' => '?DOMElement'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'DOMElement|null'], default: '')] public $lastElementChild; - #[LanguageLevelTypeAware(['8.1' => '?DOMElement'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'DOMElement|null'], default: '')] public $firstElementChild; /** @@ -1267,10 +1267,10 @@ class DOMCharacterData extends DOMNode implements DOMChildNode #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $length; - #[LanguageLevelTypeAware(['8.1' => '?DOMElement'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'DOMElement|null'], default: '')] public $nextElementSibling; - #[LanguageLevelTypeAware(['8.1' => '?DOMElement'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'DOMElement|null'], default: '')] public $previousElementSibling; /** @@ -1386,7 +1386,7 @@ class DOMAttr extends DOMNode * The element which contains the attribute * @link https://php.net/manual/en/class.domattr.php#domattr.props.ownerelement */ - #[LanguageLevelTypeAware(['8.1' => '?DOMElement'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'DOMElement|null'], default: '')] public $ownerElement; /** @@ -1489,19 +1489,19 @@ class DOMElement extends DOMNode implements DOMParentNode, DOMChildNode #[LanguageLevelTypeAware(['8.1' => 'string'], default: '')] public $tagName; - #[LanguageLevelTypeAware(['8.1' => '?DOMElement'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'DOMElement|null'], default: '')] public $firstElementChild; - #[LanguageLevelTypeAware(['8.1' => '?DOMElement'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'DOMElement|null'], default: '')] public $lastElementChild; #[LanguageLevelTypeAware(['8.1' => 'int'], default: '')] public $childElementCount; - #[LanguageLevelTypeAware(['8.1' => '?DOMElement'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'DOMElement|null'], default: '')] public $previousElementSibling; - #[LanguageLevelTypeAware(['8.1' => '?DOMElement'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'DOMElement|null'], default: '')] public $nextElementSibling; /** @@ -1953,7 +1953,7 @@ class DOMDocumentType extends DOMNode * The internal subset as a string, or null if there is none. This is does not contain the delimiting square brackets. * @link https://php.net/manual/en/class.domdocumenttype.php#domdocumenttype.props.internalsubset */ - #[LanguageLevelTypeAware(['8.1' => '?string'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $internalSubset; } @@ -1991,7 +1991,7 @@ class DOMEntity extends DOMNode * The public identifier associated with the entity if specified, and NULL otherwise. * @link https://php.net/manual/en/class.domentity.php#domentity.props.publicid */ - #[LanguageLevelTypeAware(['8.1' => '?string'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $publicId; /** @@ -2000,7 +2000,7 @@ class DOMEntity extends DOMNode * absolute URI or not. * @link https://php.net/manual/en/class.domentity.php#domentity.props.systemid */ - #[LanguageLevelTypeAware(['8.1' => '?string'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $systemId; /** @@ -2008,7 +2008,7 @@ class DOMEntity extends DOMNode * For unparsed entities, the name of the notation for the entity. For parsed entities, this is NULL. * @link https://php.net/manual/en/class.domentity.php#domentity.props.notationname */ - #[LanguageLevelTypeAware(['8.1' => '?string'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $notationName; /** diff --git a/gettext/gettext.php b/gettext/gettext.php index 351766f8..8e79d396 100644 --- a/gettext/gettext.php +++ b/gettext/gettext.php @@ -80,7 +80,7 @@ function dcgettext(string $domain, string $message, int $category): string {} *

* @return string|false The full pathname for the domain currently being set. */ -function bindtextdomain(string $domain, #[LanguageLevelTypeAware(['8.0' => '?string'], default: 'string')] $directory): string|false {} +function bindtextdomain(string $domain, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: 'string')] $directory): string|false {} /** * Plural version of gettext @@ -135,6 +135,6 @@ function dcngettext(string $domain, string $singular, string $plural, int $count *

* @return string|false A string on success. */ -function bind_textdomain_codeset(string $domain, #[LanguageLevelTypeAware(['8.0' => '?string'], default: 'string')] $codeset): string|false {} +function bind_textdomain_codeset(string $domain, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: 'string')] $codeset): string|false {} // End of gettext v. diff --git a/intl/intl.php b/intl/intl.php index be679a26..f8f589cb 100644 --- a/intl/intl.php +++ b/intl/intl.php @@ -3611,7 +3611,7 @@ function collator_get_sort_key(Collator $object, string $string): string|false { * @return NumberFormatter|false|null NumberFormatter object or FALSE on error. */ #[Pure] -function numfmt_create(string $locale, int $style, #[LanguageLevelTypeAware(['8.0' => '?string'], default: 'string')] $pattern = null): ?NumberFormatter {} +function numfmt_create(string $locale, int $style, #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: 'string')] $pattern = null): ?NumberFormatter {} /** * (PHP 5 >= 5.3.0, PECL intl >= 1.0.0)
@@ -4299,7 +4299,7 @@ function datefmt_create( int $timeType, $timezone = null, IntlCalendar|int|null $calendar = null, - #[LanguageLevelTypeAware(['8.0' => '?string'], default: 'string')] $pattern = null + #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: 'string')] $pattern = null ): ?IntlDateFormatter {} /** diff --git a/mysqli/mysqli.php b/mysqli/mysqli.php index b2414455..7fed8fb3 100644 --- a/mysqli/mysqli.php +++ b/mysqli/mysqli.php @@ -95,7 +95,7 @@ class mysqli /** * @var string */ - #[LanguageLevelTypeAware(['8.1' => '?string'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $connect_error; /** * @var int @@ -120,7 +120,7 @@ class mysqli /** * @var string */ - #[LanguageLevelTypeAware(['8.1' => '?string'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'string|null'], default: '')] public $info; /** * @var int|string @@ -848,7 +848,7 @@ class mysqli_result implements IteratorAggregate /** * @var array */ - #[LanguageLevelTypeAware(['8.1' => '?array'], default: '')] + #[LanguageLevelTypeAware(['8.1' => 'array|null'], default: '')] public $lengths; /** * @var int @@ -2450,11 +2450,11 @@ function mysqli_stat(mysqli $mysql): string|false {} */ function mysqli_ssl_set( mysqli $mysql, - #[LanguageLevelTypeAware(['8.0' => '?string'], default: 'string')] $key, - #[LanguageLevelTypeAware(['8.0' => '?string'], default: 'string')] $certificate, - #[LanguageLevelTypeAware(['8.0' => '?string'], default: 'string')] $ca_certificate, - #[LanguageLevelTypeAware(['8.0' => '?string'], default: 'string')] $ca_path, - #[LanguageLevelTypeAware(['8.0' => '?string'], default: 'string')] $cipher_algos + #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: 'string')] $key, + #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: 'string')] $certificate, + #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: 'string')] $ca_certificate, + #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: 'string')] $ca_path, + #[LanguageLevelTypeAware(['8.0' => 'string|null'], default: 'string')] $cipher_algos ): bool {} /** diff --git a/soap/soap.php b/soap/soap.php index c77e7dc2..edd21f44 100644 --- a/soap/soap.php +++ b/soap/soap.php @@ -410,7 +410,7 @@ class SoapClient * @return void No value is returned. * @since 5.0.4 */ - public function __setCookie($name, #[LanguageLevelTypeAware(["8.0" => "?string"], default: "string")] $value) {} + public function __setCookie($name, #[LanguageLevelTypeAware(["8.0" => "string|null"], default: "string")] $value) {} /** * Sets the location of the Web service to use @@ -466,7 +466,7 @@ class SoapVar *

* @since 5.0.1 */ - public function __construct($data, #[LanguageLevelTypeAware(["7.1" => "?int"], default: "int")] $encoding, #[LanguageLevelTypeAware(["8.0" => "?string"], default: "string")] $typeName, $typeNamespace = '', $nodeName = '', $nodeNamespace = '') {} + public function __construct($data, #[LanguageLevelTypeAware(["7.1" => "int|null"], default: "int")] $encoding, #[LanguageLevelTypeAware(["8.0" => "string|null"], default: "string")] $typeName, $typeNamespace = '', $nodeName = '', $nodeNamespace = '') {} /** * SoapVar constructor diff --git a/tests/BaseStubsTest.php b/tests/BaseStubsTest.php index fefd4856..436d6151 100644 --- a/tests/BaseStubsTest.php +++ b/tests/BaseStubsTest.php @@ -37,4 +37,15 @@ abstract class BaseStubsTest extends TestCase } return $resultString; } + + public static function convertNullableTypesToUnion($typesToProcess, array &$resultArray) + { + array_walk($typesToProcess, function (string $type) use (&$resultArray) { + if (str_contains($type, '?')) { + array_push($resultArray, 'null', ltrim($type, '?')); + } else { + array_push($resultArray, $type); + } + }); + } } diff --git a/tests/StubsTest.php b/tests/StubsTest.php index 5fbf0122..fbef166d 100644 --- a/tests/StubsTest.php +++ b/tests/StubsTest.php @@ -502,13 +502,25 @@ class StubsTest extends BaseStubsTest $className = $class->name; $stubProperty = PhpStormStubsSingleton::getPhpStormStubs()->getClass($class->name)->properties[$property->name]; $propertyName = $stubProperty->name; - $conditionToCompareWithSignature = self::ifReflectionTypesExistInSignature($property->typesFromSignature, $stubProperty->typesFromSignature); - $conditionToCompareWithAttribute = self::ifReflectionTypesExistInAttributes($property->typesFromSignature, $stubProperty->typesFromAttribute); + $unifiedStubsPropertyTypes = []; + $unifiedStubsAttributesPropertyTypes = []; + $unifiedReflectionPropertyTypes = []; + self::convertNullableTypesToUnion($property->typesFromSignature, $unifiedReflectionPropertyTypes); + if (!empty($stubProperty->typesFromSignature)) { + self::convertNullableTypesToUnion($stubProperty->typesFromSignature, $unifiedStubsPropertyTypes); + } else { + foreach ($stubProperty->typesFromAttribute as $languageVersion => $listOfTypes) { + $unifiedStubsAttributesPropertyTypes[$languageVersion] = []; + self::convertNullableTypesToUnion($listOfTypes, $unifiedStubsAttributesPropertyTypes[$languageVersion]); + } + } + $conditionToCompareWithSignature = self::ifReflectionTypesExistInSignature($unifiedReflectionPropertyTypes, $unifiedStubsPropertyTypes); + $conditionToCompareWithAttribute = self::ifReflectionTypesExistInAttributes($unifiedReflectionPropertyTypes, $unifiedStubsAttributesPropertyTypes); $testCondition = $conditionToCompareWithSignature || $conditionToCompareWithAttribute; self::assertTrue($testCondition, "Property $className::$propertyName has invalid typehint. - Reflection property has type " . implode('|', $property->typesFromSignature) . ' but stubs has type ' . - implode('|', $stubProperty->typesFromSignature) . ' in signature and attribute has types ' . - self::getStringRepresentationOfTypeHintsFromAttributes($stubProperty->typesFromAttribute)); + Reflection property has type " . implode('|', $unifiedReflectionPropertyTypes) . ' but stubs has type ' . + implode('|', $unifiedStubsPropertyTypes) . ' in signature and attribute has types ' . + self::getStringRepresentationOfTypeHintsFromAttributes($unifiedStubsAttributesPropertyTypes)); } /** diff --git a/tests/StubsTypeHintsTest.php b/tests/StubsTypeHintsTest.php index bc5e6b12..1fdf1d9d 100644 --- a/tests/StubsTypeHintsTest.php +++ b/tests/StubsTypeHintsTest.php @@ -351,15 +351,4 @@ class StubsTypeHintsTest extends BaseStubsTest "' but stub parameter has type '" . implode('|', $unifiedStubsParameterTypes) . "' in signature and " . BaseStubsTest::getStringRepresentationOfTypeHintsFromAttributes($unifiedStubsAttributesParameterTypes) . ' in attribute'); } - - private static function convertNullableTypesToUnion($typesToProcess, array &$resultArray) - { - array_walk($typesToProcess, function (string $type) use (&$resultArray) { - if (str_contains($type, '?')) { - array_push($resultArray, 'null', ltrim($type, '?')); - } else { - array_push($resultArray, $type); - } - }); - } }