diff --git a/config.xsd b/config.xsd
index 9f8676ce8..a79c23f21 100644
--- a/config.xsd
+++ b/config.xsd
@@ -51,14 +51,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 6a84f2074..03fcd77f4 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 958430211..3f6579aef 100644
--- a/src/Psalm/Config.php
+++ b/src/Psalm/Config.php
@@ -315,11 +315,6 @@ class Config
/** @var bool */
public $use_igbinary = false;
- /**
- * @var bool
- */
- public $allow_phpstorm_generics = false;
-
/**
* @var bool
*/
@@ -887,7 +882,6 @@ class Config
'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 c293367f7..819984068 100644
--- a/src/Psalm/Internal/Codebase/Populator.php
+++ b/src/Psalm/Internal/Codebase/Populator.php
@@ -14,11 +14,6 @@ use Psalm\IssueBuffer;
use Psalm\Progress\Progress;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Storage\FileStorage;
-use Psalm\Type;
-use Psalm\Type\Atomic\TArray;
-use Psalm\Type\Atomic\TGenericObject;
-use Psalm\Type\Atomic\TIterable;
-use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Union;
@@ -110,26 +105,6 @@ class Populator
}
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);
@@ -141,22 +116,6 @@ class Populator
}
}
- 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();
@@ -991,65 +950,6 @@ class Populator
$storage->populated = true;
}
- private function convertPhpStormGenericToPsalmGeneric(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 TIterable
- || ($type instanceof 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 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 TIterable($generic_params);
- } else {
- if (strtolower($iterator_name) === 'generator') {
- $generic_params[] = Type::getMixed();
- $generic_params[] = Type::getMixed();
- }
- $generic_iterator = new 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 99fbeffff..f6f0e2d76 100644
--- a/src/Psalm/Internal/Type/TypeCombiner.php
+++ b/src/Psalm/Internal/Type/TypeCombiner.php
@@ -180,8 +180,7 @@ class TypeCombiner
&& (isset($combination->named_object_types['Traversable'])
|| isset($combination->builtin_type_params['Traversable']))
&& (
- ($codebase && $codebase->config->allow_phpstorm_generics)
- || isset($combination->builtin_type_params['Traversable'])
+ 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 9c65da93b..62e36d016 100644
--- a/tests/AnnotationTest.php
+++ b/tests/AnnotationTest.php
@@ -22,149 +22,6 @@ class AnnotationTest extends TestCase
$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(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 testLessSpecificImplementedReturnTypeWithDocblockOnMultipleLines(): void
{
$this->expectException(CodeException::class);
@@ -236,25 +93,6 @@ class AnnotationTest extends TestCase
$this->analyzeFile('somefile.php', new Context());
}
- public function testPhpStormGenericsNoTypehint(): void
- {
- $this->expectException(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(CodeException::class);