diff --git a/config.xsd b/config.xsd index 417073f7223..3cf2fa0b785 100644 --- a/config.xsd +++ b/config.xsd @@ -44,14 +44,6 @@ - - - - - Deprecated. PHPStorm now supports generics for the most part and @psalm- annotations can be used - - - diff --git a/docs/running_psalm/configuration.md b/docs/running_psalm/configuration.md index 6a84f20742e..03fcd77f44d 100644 --- a/docs/running_psalm/configuration.md +++ b/docs/running_psalm/configuration.md @@ -134,17 +134,6 @@ If true we force strict typing on numerical and string operations (see https://g ``` Setting this to `false` means that any function calls will cause Psalm to forget anything it knew about object properties within the scope of the function it's currently analysing. This duplicates functionality that Hack has. Defaults to `true`. -#### allowPhpStormGenerics - -```xml - -``` -Allows you to specify whether or not to use the typed iterator docblock format supported by PHP Storm e.g. `ArrayIterator|string[]`, which Psalm transforms to `ArrayIterator`. Defaults to `false`. - -This flag is deprecated and will be removed in Psalm 5 - #### allowStringToStandInForClass ```xml diff --git a/src/Psalm/Config.php b/src/Psalm/Config.php index 559b469a2aa..3999818a2b1 100644 --- a/src/Psalm/Config.php +++ b/src/Psalm/Config.php @@ -301,11 +301,6 @@ class Config /** @var bool */ public $use_igbinary = false; - /** - * @var bool - */ - public $allow_phpstorm_generics = false; - /** * @var bool */ @@ -830,7 +825,6 @@ private static function fromXmlAndPaths( 'allowFileIncludes' => 'allow_includes', 'strictBinaryOperands' => 'strict_binary_operands', 'rememberPropertyAssignmentsAfterCall' => 'remember_property_assignments_after_call', - 'allowPhpStormGenerics' => 'allow_phpstorm_generics', 'allowStringToStandInForClass' => 'allow_string_standin_for_class', 'usePhpDocMethodsWithoutMagicCall' => 'use_phpdoc_method_without_magic_or_parent', 'usePhpDocPropertiesWithoutMagicCall' => 'use_phpdoc_property_without_magic_or_parent', diff --git a/src/Psalm/Internal/Codebase/Populator.php b/src/Psalm/Internal/Codebase/Populator.php index 086125a79e0..98d638b09dc 100644 --- a/src/Psalm/Internal/Codebase/Populator.php +++ b/src/Psalm/Internal/Codebase/Populator.php @@ -98,26 +98,6 @@ public function populateCodebase(): void } foreach ($this->classlike_storage_provider->getNew() as $class_storage) { - if ($this->config->allow_phpstorm_generics) { - foreach ($class_storage->properties as $property_storage) { - if ($property_storage->type) { - $this->convertPhpStormGenericToPsalmGeneric($property_storage->type, true); - } - } - - foreach ($class_storage->methods as $method_storage) { - if ($method_storage->return_type) { - $this->convertPhpStormGenericToPsalmGeneric($method_storage->return_type); - } - - foreach ($method_storage->params as $param_storage) { - if ($param_storage->type) { - $this->convertPhpStormGenericToPsalmGeneric($param_storage->type); - } - } - } - } - foreach ($class_storage->dependent_classlikes as $dependent_classlike_lc => $_) { try { $dependee_storage = $this->classlike_storage_provider->get($dependent_classlike_lc); @@ -129,22 +109,6 @@ public function populateCodebase(): void } } - if ($this->config->allow_phpstorm_generics) { - foreach ($all_file_storage as $file_storage) { - foreach ($file_storage->functions as $function_storage) { - if ($function_storage->return_type) { - $this->convertPhpStormGenericToPsalmGeneric($function_storage->return_type); - } - - foreach ($function_storage->params as $param_storage) { - if ($param_storage->type) { - $this->convertPhpStormGenericToPsalmGeneric($param_storage->type); - } - } - } - } - } - $this->progress->debug('FileStorage is populated' . "\n"); ClassLikeStorageProvider::populated(); @@ -979,65 +943,6 @@ private function populateFileStorage(FileStorage $storage, array $dependent_file $storage->populated = true; } - private function convertPhpStormGenericToPsalmGeneric(Type\Union $candidate, bool $is_property = false): void - { - if (!$candidate->from_docblock) { - //never convert a type that comes from a signature - return; - } - - $atomic_types = $candidate->getAtomicTypes(); - - if (isset($atomic_types['array']) && count($atomic_types) > 1 && !isset($atomic_types['null'])) { - $iterator_name = null; - $generic_params = null; - $iterator_key = null; - - try { - foreach ($atomic_types as $type_key => $type) { - if ($type instanceof Type\Atomic\TIterable - || ($type instanceof Type\Atomic\TNamedObject - && (!$type->from_docblock || $is_property) - && ( - strtolower($type->value) === 'traversable' - || $this->classlikes->interfaceExtends( - $type->value, - 'Traversable' - ) - || $this->classlikes->classImplements( - $type->value, - 'Traversable' - ) - )) - ) { - $iterator_name = $type->value; - $iterator_key = $type_key; - } elseif ($type instanceof Type\Atomic\TArray) { - $generic_params = $type->type_params; - } - } - } catch (\InvalidArgumentException $e) { - // ignore class-not-found issues - } - - if ($iterator_name && $iterator_key && $generic_params) { - if ($iterator_name === 'iterable') { - $generic_iterator = new Type\Atomic\TIterable($generic_params); - } else { - if (strtolower($iterator_name) === 'generator') { - $generic_params[] = Type::getMixed(); - $generic_params[] = Type::getMixed(); - } - $generic_iterator = new Type\Atomic\TGenericObject($iterator_name, $generic_params); - } - - $candidate->removeType('array'); - $candidate->removeType($iterator_key); - $candidate->addType($generic_iterator); - } - } - } - protected function inheritMethodsFromParent( ClassLikeStorage $storage, ClassLikeStorage $parent_storage diff --git a/src/Psalm/Internal/Type/TypeCombiner.php b/src/Psalm/Internal/Type/TypeCombiner.php index 8c86dd9c7c2..ef66da70a60 100644 --- a/src/Psalm/Internal/Type/TypeCombiner.php +++ b/src/Psalm/Internal/Type/TypeCombiner.php @@ -178,7 +178,7 @@ public static function combine( && (isset($combination->named_object_types['Traversable']) || isset($combination->builtin_type_params['Traversable'])) && ( - ($codebase && !$codebase->config->allow_phpstorm_generics) + $codebase || isset($combination->builtin_type_params['Traversable']) || (isset($combination->named_object_types['Traversable']) && $combination->named_object_types['Traversable']->from_docblock) diff --git a/tests/AnnotationTest.php b/tests/AnnotationTest.php index 56bcffaff7f..c9d29d323f7 100644 --- a/tests/AnnotationTest.php +++ b/tests/AnnotationTest.php @@ -18,168 +18,6 @@ public function setUp(): void $codebase->reportUnusedVariables(); } - public function testPhpStormGenericsWithValidArrayIteratorArgument(): void - { - Config::getInstance()->allow_phpstorm_generics = true; - - $this->addFile( - 'somefile.php', - 'offsetGet("a"); - takesString($s); - - foreach ($i as $s2) { - takesString($s2); - } - }' - ); - - $this->analyzeFile('somefile.php', new Context()); - } - - public function testPhpStormGenericsWithTypeInSignature(): void - { - Config::getInstance()->allow_phpstorm_generics = true; - - $this->addFile( - 'somefile.php', - 'analyzeFile('somefile.php', new Context()); - } - - public function testPhpStormGenericsWithValidTraversableArgument(): void - { - Config::getInstance()->allow_phpstorm_generics = true; - - $this->addFile( - 'somefile.php', - 'analyzeFile('somefile.php', new Context()); - } - - public function testPhpStormGenericsWithClassProperty(): void - { - Config::getInstance()->allow_phpstorm_generics = true; - - $this->addFile( - 'somefile.php', - 'bar; - } - }' - ); - - $this->analyzeFile('somefile.php', new Context()); - } - - public function testPhpStormGenericsWithGeneratorArray(): void - { - Config::getInstance()->allow_phpstorm_generics = true; - - $this->addFile( - 'somefile.php', - 'analyzeFile('somefile.php', new Context()); - } - - public function testPhpStormGenericsWithValidIterableArgument(): void - { - Config::getInstance()->allow_phpstorm_generics = true; - - $this->addFile( - 'somefile.php', - 'analyzeFile('somefile.php', new Context()); - } - - public function testPhpStormGenericsInvalidArgument(): void - { - $this->expectException(\Psalm\Exception\CodeException::class); - $this->expectExceptionMessage('InvalidScalarArgument'); - - Config::getInstance()->allow_phpstorm_generics = true; - - $this->addFile( - 'somefile.php', - 'offsetGet("a"); - takesInt($s); - }' - ); - - $this->analyzeFile('somefile.php', new Context()); - } - - public function testPhpStormGenericsNoTypehint(): void - { - $this->expectException(\Psalm\Exception\CodeException::class); - $this->expectExceptionMessage('PossiblyInvalidMethodCall'); - - Config::getInstance()->allow_phpstorm_generics = true; - - $this->addFile( - 'somefile.php', - 'offsetGet("a"); - }' - ); - - $this->analyzeFile('somefile.php', new Context()); - } - public function testInvalidParamDefault(): void { $this->expectException(\Psalm\Exception\CodeException::class);