mirror of
https://github.com/rectorphp/rector.git
synced 2025-01-17 05:18:18 +01:00
[Generics] Add GenericsPHPStormMethodAnnotationRector (#5365)
Co-authored-by: rector-bot <tomas@getrector.org>
This commit is contained in:
parent
033b2a38e9
commit
024ec4ba93
@ -1,7 +1,12 @@
|
||||
{
|
||||
"name": "rector/rector",
|
||||
"description": "Instant upgrade and refactoring of your PHP code",
|
||||
"keywords": ["instant upgrades", "instant refactoring", "ast", "automated refactoring"],
|
||||
"keywords": [
|
||||
"instant upgrades",
|
||||
"instant refactoring",
|
||||
"ast",
|
||||
"automated refactoring"
|
||||
],
|
||||
"homepage": "https://getrector.org",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
@ -38,8 +43,8 @@
|
||||
"sebastian/diff": "^4.0",
|
||||
"symfony/cache": "^4.4.8|^5.1",
|
||||
"symfony/console": "^4.4.8|^5.1",
|
||||
"symfony/expression-language": "^4.4|^5.1",
|
||||
"symfony/dependency-injection": "^5.1",
|
||||
"symfony/expression-language": "^4.4|^5.1",
|
||||
"symfony/finder": "^4.4.8|^5.1",
|
||||
"symfony/http-kernel": "^4.4.8|^5.1",
|
||||
"symfony/process": "^4.4.8|^5.1",
|
||||
@ -49,7 +54,7 @@
|
||||
"symplify/package-builder": "^9.0.34",
|
||||
"symplify/rule-doc-generator": "^9.0.34",
|
||||
"symplify/set-config-resolver": "^9.0.34",
|
||||
"symplify/simple-php-doc-parser": "^9.0.34",
|
||||
"symplify/simple-php-doc-parser": "^9.0",
|
||||
"symplify/skipper": "^9.0.34",
|
||||
"symplify/smart-file-system": "^9.0.34",
|
||||
"symplify/symfony-php-config": "^9.0.34",
|
||||
@ -176,7 +181,8 @@
|
||||
"Rector\\Twig\\": "rules/twig/src",
|
||||
"Rector\\TypeDeclaration\\": "rules/type-declaration/src",
|
||||
"Rector\\VendorLocker\\": "packages/vendor-locker/src",
|
||||
"Rector\\Carbon\\": "rules/carbon/src"
|
||||
"Rector\\Carbon\\": "rules/carbon/src",
|
||||
"Rector\\Generics\\": "rules/generics/src"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
@ -300,7 +306,8 @@
|
||||
"Rector\\Utils\\NodeDocumentationGenerator\\Tests\\": "utils/node-documentation-generator/tests",
|
||||
"Rector\\Utils\\PHPStanTypeMapperChecker\\": "utils/phpstan-type-mapper-checker/src",
|
||||
"Rector\\Utils\\ProjectValidator\\": "utils/project-validator/src",
|
||||
"Rector\\Carbon\\Tests\\": "rules/carbon/tests"
|
||||
"Rector\\Carbon\\Tests\\": "rules/carbon/tests",
|
||||
"Rector\\Generics\\Tests\\": "rules/generics/tests"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
|
@ -4,7 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
use Rector\Php71\Rector\Assign\AssignArrayToStringRector;
|
||||
use Rector\Php71\Rector\BinaryOp\BinaryOpBetweenNumberAndStringRector;
|
||||
use Rector\Php71\Rector\BinaryOp\IsIterableRector;
|
||||
use Rector\Php71\Rector\BooleanOr\IsIterableRector;
|
||||
use Rector\Php71\Rector\FuncCall\CountOnNullRector;
|
||||
use Rector\Php71\Rector\FuncCall\RemoveExtraParametersRector;
|
||||
use Rector\Php71\Rector\List_\ListToArrayDestructRector;
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\Php73\Rector\BinaryOp\IsCountableRector;
|
||||
use Rector\Php73\Rector\BooleanOr\IsCountableRector;
|
||||
use Rector\Php73\Rector\ConstFetch\SensitiveConstantNameRector;
|
||||
use Rector\Php73\Rector\FuncCall\ArrayKeyFirstLastRector;
|
||||
use Rector\Php73\Rector\FuncCall\JsonThrowOnErrorRector;
|
||||
|
@ -2,13 +2,13 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\Generic\ValueObject\PseudoNamespaceToNamespace;
|
||||
use Rector\PHPUnit\Rector\ClassMethod\AddDoesNotPerformAssertionToNonAssertingTestRector;
|
||||
use Rector\PHPUnit\Rector\MethodCall\GetMockBuilderGetMockToCreateMockRector;
|
||||
use Rector\Renaming\Rector\FileWithoutNamespace\PseudoNamespaceToNamespaceRector;
|
||||
use Rector\Renaming\Rector\MethodCall\RenameMethodRector;
|
||||
use Rector\Renaming\Rector\Name\RenameClassRector;
|
||||
use Rector\Renaming\ValueObject\MethodCallRename;
|
||||
use Rector\Renaming\ValueObject\PseudoNamespaceToNamespace;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
use Symplify\SymfonyPhpConfig\ValueObjectInliner;
|
||||
|
||||
|
@ -2,9 +2,9 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\Generic\ValueObject\PseudoNamespaceToNamespace;
|
||||
use Rector\Renaming\Rector\FileWithoutNamespace\PseudoNamespaceToNamespaceRector;
|
||||
use Rector\Renaming\Rector\Name\RenameClassRector;
|
||||
use Rector\Renaming\ValueObject\PseudoNamespaceToNamespace;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
use Symplify\SymfonyPhpConfig\ValueObjectInliner;
|
||||
|
||||
|
@ -12024,7 +12024,7 @@ Changes `count()` on null to safe ternary check
|
||||
|
||||
Changes `is_array` + Traversable check to `is_iterable`
|
||||
|
||||
- class: `Rector\Php71\Rector\BinaryOp\IsIterableRector`
|
||||
- class: `Rector\Php71\Rector\BooleanOr\IsIterableRector`
|
||||
|
||||
```diff
|
||||
-is_array($foo) || $foo instanceof Traversable;
|
||||
@ -12353,7 +12353,7 @@ Make use of `array_key_first()` and `array_key_last()`
|
||||
|
||||
Changes `is_array` + Countable check to `is_countable`
|
||||
|
||||
- class: `Rector\Php73\Rector\BinaryOp\IsCountableRector`
|
||||
- class: `Rector\Php73\Rector\BooleanOr\IsCountableRector`
|
||||
|
||||
```diff
|
||||
-is_array($foo) || $foo instanceof Countable;
|
||||
@ -14197,7 +14197,7 @@ Replaces defined Pseudo_Namespaces by Namespace\Ones.
|
||||
- class: `Rector\Renaming\Rector\FileWithoutNamespace\PseudoNamespaceToNamespaceRector`
|
||||
|
||||
```php
|
||||
use Rector\Generic\ValueObject\PseudoNamespaceToNamespace;
|
||||
use Rector\Renaming\ValueObject\PseudoNamespaceToNamespace;
|
||||
use Rector\Renaming\Rector\FileWithoutNamespace\PseudoNamespaceToNamespaceRector;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
use Symplify\SymfonyPhpConfig\ValueObjectInliner;
|
||||
|
@ -12,4 +12,13 @@ use Rector\BetterPhpDocParser\Contract\PhpDocNode\TypeAwareTagValueNodeInterface
|
||||
final class AttributeAwareGenericTypeNode extends GenericTypeNode implements AttributeAwareNodeInterface, TypeAwareTagValueNodeInterface
|
||||
{
|
||||
use AttributeTrait;
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
if ($this->genericTypes !== []) {
|
||||
return parent::__toString();
|
||||
}
|
||||
|
||||
return (string) $this->type;
|
||||
}
|
||||
}
|
||||
|
@ -6,10 +6,12 @@ namespace Rector\BetterPhpDocParser\PhpDocInfo;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\GenericTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\MethodTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocChildNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PropertyTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\TemplateTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode;
|
||||
@ -39,12 +41,14 @@ use Rector\StaticTypeMapper\ValueObject\Type\ShortenedObjectType;
|
||||
final class PhpDocInfo
|
||||
{
|
||||
/**
|
||||
* @var array<string, string>
|
||||
* @var array<class-string<PhpDocTagValueNode>, string>
|
||||
*/
|
||||
private const TAGS_TYPES_TO_NAMES = [
|
||||
ReturnTagValueNode::class => '@return',
|
||||
ParamTagValueNode::class => '@param',
|
||||
VarTagValueNode::class => '@var',
|
||||
MethodTagValueNode::class => '@method',
|
||||
PropertyTagValueNode::class => '@property',
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -11,7 +11,7 @@ use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
|
||||
use Rector\Generic\ValueObject\PseudoNamespaceToNamespace;
|
||||
use Rector\Renaming\ValueObject\PseudoNamespaceToNamespace;
|
||||
use Rector\StaticTypeMapper\StaticTypeMapper;
|
||||
use Symplify\SimplePhpDocParser\PhpDocNodeTraverser;
|
||||
|
||||
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Rector\PHPStanStaticTypeMapper\TypeMapper;
|
||||
|
||||
use Nette\Utils\Strings;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Name\FullyQualified;
|
||||
@ -50,7 +51,12 @@ final class ObjectTypeMapper implements TypeMapperInterface, PHPStanStaticTypeMa
|
||||
}
|
||||
|
||||
if ($type instanceof GenericObjectType) {
|
||||
$identifierTypeNode = new IdentifierTypeNode('\\' . $type->getClassName());
|
||||
if (Strings::contains($type->getClassName(), '\\')) {
|
||||
$name = '\\' . $type->getClassName();
|
||||
} else {
|
||||
$name = $type->getClassName();
|
||||
}
|
||||
$identifierTypeNode = new IdentifierTypeNode($name);
|
||||
|
||||
$genericTypeNodes = [];
|
||||
foreach ($type->getTypes() as $genericType) {
|
||||
|
@ -7,9 +7,11 @@ namespace Rector\PHPStanStaticTypeMapper\TypeMapper;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Name;
|
||||
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
|
||||
use PHPStan\Type\Generic\TemplateObjectWithoutClassType;
|
||||
use PHPStan\Type\ObjectWithoutClassType;
|
||||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\VerbosityLevel;
|
||||
use Rector\AttributeAwarePhpDoc\Ast\Type\AttributeAwareGenericTypeNode;
|
||||
use Rector\AttributeAwarePhpDoc\Ast\Type\AttributeAwareIdentifierTypeNode;
|
||||
use Rector\Core\Php\PhpVersionProvider;
|
||||
use Rector\Core\ValueObject\PhpVersionFeature;
|
||||
@ -44,6 +46,11 @@ final class ObjectWithoutClassTypeMapper implements TypeMapperInterface, PHPStan
|
||||
*/
|
||||
public function mapToPHPStanPhpDocTypeNode(Type $type): TypeNode
|
||||
{
|
||||
if ($type instanceof TemplateObjectWithoutClassType) {
|
||||
$attributeAwareIdentifierTypeNode = new AttributeAwareIdentifierTypeNode($type->getName());
|
||||
return new AttributeAwareGenericTypeNode($attributeAwareIdentifierTypeNode, []);
|
||||
}
|
||||
|
||||
return new AttributeAwareIdentifierTypeNode('object');
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ use Rector\StaticTypeMapper\ValueObject\Type\FalseBooleanType;
|
||||
final class ScalarStringToTypeMapper
|
||||
{
|
||||
/**
|
||||
* @var string[][]
|
||||
* @var array<class-string<Type>, string[]>
|
||||
*/
|
||||
private const SCALAR_NAME_BY_TYPE = [
|
||||
StringType::class => ['string'],
|
||||
|
@ -46,7 +46,6 @@ final class PhpDocTypeMapper
|
||||
}
|
||||
|
||||
// fallback to PHPStan resolver
|
||||
|
||||
return $this->typeNodeResolver->resolve($typeNode, $nameScope);
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Contract;
|
||||
|
||||
interface IsAbleFuncCallInterface
|
||||
{
|
||||
public function getFuncName(): string;
|
||||
|
||||
public function getPhpVersion(): int;
|
||||
|
||||
public function getType(): string;
|
||||
}
|
17
rules/generics/config/config.php
Normal file
17
rules/generics/config/config.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$services = $containerConfigurator->services();
|
||||
|
||||
$services->defaults()
|
||||
->public()
|
||||
->autowire()
|
||||
->autoconfigure();
|
||||
|
||||
$services->load('Rector\Generics\\', __DIR__ . '/../src')
|
||||
->exclude([__DIR__ . '/../src/Rector']);
|
||||
};
|
@ -0,0 +1,156 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generics\Rector\Class_;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Reflection\ClassReflection;
|
||||
use PHPStan\Type\Generic\TemplateTypeHelper;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Generics\Reflection\ClassGenericMethodResolver;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
/**
|
||||
* @see https://github.com/phpstan/phpstan/issues/3167
|
||||
*
|
||||
* @see \Rector\Generics\Tests\Rector\Class_\GenericsPHPStormMethodAnnotationRector\GenericsPHPStormMethodAnnotationRectorTest
|
||||
*/
|
||||
final class GenericsPHPStormMethodAnnotationRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var ClassGenericMethodResolver
|
||||
*/
|
||||
private $classGenericMethodResolver;
|
||||
|
||||
public function __construct(ClassGenericMethodResolver $classGenericMethodResolver)
|
||||
{
|
||||
$this->classGenericMethodResolver = $classGenericMethodResolver;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition(
|
||||
'Complete PHPStorm @method annotations, to make it understand the PHPStan/Psalm generics',
|
||||
[
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
/**
|
||||
* @template TEntity as object
|
||||
*/
|
||||
abstract class AbstractRepository
|
||||
{
|
||||
/**
|
||||
* @return TEntity
|
||||
*/
|
||||
public function find($id)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @template TEntity as SomeObject
|
||||
* @extends AbstractRepository<TEntity>
|
||||
*/
|
||||
final class AndroidDeviceRepository extends AbstractRepository
|
||||
{
|
||||
}
|
||||
CODE_SAMPLE
|
||||
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
/**
|
||||
* @template TEntity as object
|
||||
*/
|
||||
abstract class AbstractRepository
|
||||
{
|
||||
/**
|
||||
* @return TEntity
|
||||
*/
|
||||
public function find($id)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @template TEntity as SomeObject
|
||||
* @extends AbstractRepository<TEntity>
|
||||
* @method SomeObject find($id)
|
||||
*/
|
||||
final class AndroidDeviceRepository extends AbstractRepository
|
||||
{
|
||||
}
|
||||
CODE_SAMPLE
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [Class_::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Class_ $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if ($node->extends === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$scope = $node->getAttribute(AttributeKey::SCOPE);
|
||||
if (! $scope instanceof Scope) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$classReflection = $scope->getClassReflection();
|
||||
if (! $classReflection instanceof ClassReflection) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$parentClassReflection = $classReflection->getParentClass();
|
||||
if (! $parentClassReflection instanceof ClassReflection) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $parentClassReflection->isGeneric()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// resolve generic method from parent
|
||||
$methodTagValueNodes = $this->classGenericMethodResolver->resolveFromClass($parentClassReflection);
|
||||
|
||||
$templateTypeMap = $classReflection->getTemplateTypeMap();
|
||||
|
||||
// @todo replace TTypes with specific types
|
||||
foreach ($methodTagValueNodes as $methodTagValueNode) {
|
||||
if ($methodTagValueNode->returnType === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$returnType = $this->staticTypeMapper->mapPHPStanPhpDocTypeNodeToPHPStanType(
|
||||
$methodTagValueNode->returnType,
|
||||
$node
|
||||
);
|
||||
|
||||
$resolvedType = TemplateTypeHelper::resolveTemplateTypes($returnType, $templateTypeMap);
|
||||
$resolvedTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode($resolvedType);
|
||||
$methodTagValueNode->returnType = $resolvedTypeNode;
|
||||
}
|
||||
|
||||
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
|
||||
foreach ($methodTagValueNodes as $methodTagValueNode) {
|
||||
$phpDocInfo->addTagValueNode($methodTagValueNode);
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
}
|
91
rules/generics/src/Reflection/ClassGenericMethodResolver.php
Normal file
91
rules/generics/src/Reflection/ClassGenericMethodResolver.php
Normal file
@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generics\Reflection;
|
||||
|
||||
use Nette\Utils\Strings;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\MethodTagValueNode;
|
||||
use PHPStan\Reflection\ClassReflection;
|
||||
use PHPStan\Reflection\MethodReflection;
|
||||
use Rector\Generics\TagValueNodeFactory\MethodTagValueNodeFactory;
|
||||
use Symplify\SimplePhpDocParser\SimplePhpDocParser;
|
||||
use Symplify\SimplePhpDocParser\ValueObject\Ast\PhpDoc\SimplePhpDocNode;
|
||||
|
||||
final class ClassGenericMethodResolver
|
||||
{
|
||||
/**
|
||||
* @var SimplePhpDocParser
|
||||
*/
|
||||
private $simplePhpDocParser;
|
||||
|
||||
/**
|
||||
* @var MethodTagValueNodeFactory
|
||||
*/
|
||||
private $methodTagValueNodeFactory;
|
||||
|
||||
public function __construct(
|
||||
SimplePhpDocParser $simplePhpDocParser,
|
||||
MethodTagValueNodeFactory $methodTagValueNodeFactory
|
||||
) {
|
||||
$this->simplePhpDocParser = $simplePhpDocParser;
|
||||
$this->methodTagValueNodeFactory = $methodTagValueNodeFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MethodTagValueNode[]
|
||||
*/
|
||||
public function resolveFromClass(ClassReflection $classReflection): array
|
||||
{
|
||||
$methodTagValueNodes = [];
|
||||
|
||||
$templateNames = array_keys($classReflection->getTemplateTags());
|
||||
|
||||
foreach ($classReflection->getNativeMethods() as $methodReflection) {
|
||||
$parentMethodDocComment = $methodReflection->getDocComment();
|
||||
if ($parentMethodDocComment === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// how to parse?
|
||||
$parentMethodSimplePhpDocNode = $this->simplePhpDocParser->parseDocBlock($parentMethodDocComment);
|
||||
$methodTagValueNode = $this->resolveMethodTagValueNode(
|
||||
$parentMethodSimplePhpDocNode,
|
||||
$templateNames,
|
||||
$methodReflection
|
||||
);
|
||||
if (! $methodTagValueNode instanceof MethodTagValueNode) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$methodTagValueNodes[] = $methodTagValueNode;
|
||||
}
|
||||
|
||||
return $methodTagValueNodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $templateNames
|
||||
*/
|
||||
private function resolveMethodTagValueNode(
|
||||
SimplePhpDocNode $simplePhpDocNode,
|
||||
array $templateNames,
|
||||
MethodReflection $methodReflection
|
||||
): ?MethodTagValueNode {
|
||||
foreach ($simplePhpDocNode->getReturnTagValues() as $returnTagValueNode) {
|
||||
foreach ($templateNames as $templateName) {
|
||||
$typeAsString = (string) $returnTagValueNode->type;
|
||||
if (! Strings::match($typeAsString, '#\b' . preg_quote($templateName, '#') . '\b#')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return $this->methodTagValueNodeFactory->createFromMethodReflectionAndReturnTagValueNode(
|
||||
$methodReflection,
|
||||
$returnTagValueNode
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generics\TagValueNodeFactory;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\MethodTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\MethodTagValueParameterNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
|
||||
use PHPStan\Reflection\MethodReflection;
|
||||
use PHPStan\Reflection\ParameterReflection;
|
||||
use PHPStan\Type\Type;
|
||||
use Rector\StaticTypeMapper\StaticTypeMapper;
|
||||
|
||||
final class MethodTagValueNodeFactory
|
||||
{
|
||||
/**
|
||||
* @var MethodTagValueParameterNodeFactory
|
||||
*/
|
||||
private $methodTagValueParameterNodeFactory;
|
||||
|
||||
/**
|
||||
* @var StaticTypeMapper
|
||||
*/
|
||||
private $staticTypeMapper;
|
||||
|
||||
public function __construct(
|
||||
StaticTypeMapper $staticTypeMapper,
|
||||
MethodTagValueParameterNodeFactory $methodTagValueParameterNodeFactory
|
||||
) {
|
||||
$this->methodTagValueParameterNodeFactory = $methodTagValueParameterNodeFactory;
|
||||
$this->staticTypeMapper = $staticTypeMapper;
|
||||
}
|
||||
|
||||
public function createFromMethodReflectionAndReturnTagValueNode(
|
||||
MethodReflection $methodReflection,
|
||||
ReturnTagValueNode $returnTagValueNode
|
||||
): MethodTagValueNode {
|
||||
$parameterReflections = $methodReflection->getVariants()[0]
|
||||
->getParameters();
|
||||
|
||||
$stringParameters = $this->resolveStringParameters($parameterReflections);
|
||||
|
||||
$classReflection = $methodReflection->getDeclaringClass();
|
||||
$templateTypeMap = $classReflection->getTemplateTypeMap();
|
||||
|
||||
$returnTagTypeNode = $returnTagValueNode->type;
|
||||
|
||||
if ($returnTagValueNode->type instanceof IdentifierTypeNode) {
|
||||
$typeName = $returnTagValueNode->type->name;
|
||||
$genericType = $templateTypeMap->getType($typeName);
|
||||
|
||||
if ($genericType instanceof Type) {
|
||||
$returnTagType = $genericType;
|
||||
$returnTagTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode($returnTagType);
|
||||
}
|
||||
}
|
||||
|
||||
return new MethodTagValueNode(
|
||||
false,
|
||||
$returnTagTypeNode,
|
||||
$methodReflection->getName(),
|
||||
$stringParameters,
|
||||
''
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ParameterReflection[] $parameterReflections
|
||||
* @return MethodTagValueParameterNode[]
|
||||
*/
|
||||
private function resolveStringParameters(array $parameterReflections): array
|
||||
{
|
||||
$stringParameters = [];
|
||||
|
||||
foreach ($parameterReflections as $parameterReflection) {
|
||||
$stringParameters[] = $this->methodTagValueParameterNodeFactory->createFromParamReflection(
|
||||
$parameterReflection
|
||||
);
|
||||
}
|
||||
|
||||
return $stringParameters;
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generics\TagValueNodeFactory;
|
||||
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\MethodTagValueParameterNode;
|
||||
use PHPStan\Reflection\ParameterReflection;
|
||||
use PHPStan\Type\MixedType;
|
||||
use Rector\StaticTypeMapper\StaticTypeMapper;
|
||||
|
||||
final class MethodTagValueParameterNodeFactory
|
||||
{
|
||||
/**
|
||||
* @var StaticTypeMapper
|
||||
*/
|
||||
private $staticTypeMapper;
|
||||
|
||||
public function __construct(StaticTypeMapper $staticTypeMapper)
|
||||
{
|
||||
$this->staticTypeMapper = $staticTypeMapper;
|
||||
}
|
||||
|
||||
public function createFromParamReflection(ParameterReflection $parameterReflection): MethodTagValueParameterNode
|
||||
{
|
||||
$parameterType = $parameterReflection->getType();
|
||||
if ($parameterType instanceof MixedType && ! $parameterType->isExplicitMixed()) {
|
||||
$parameterTypeNode = null;
|
||||
} else {
|
||||
$parameterTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode($parameterType);
|
||||
}
|
||||
|
||||
return new MethodTagValueParameterNode(
|
||||
$parameterTypeNode,
|
||||
$parameterReflection->passedByReference()
|
||||
->yes(),
|
||||
$parameterReflection->isVariadic(),
|
||||
'$' . $parameterReflection->getName(),
|
||||
// @todo resolve
|
||||
null
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generics\Tests\Rector\Class_\GenericsPHPStormMethodAnnotationRector\Fixture;
|
||||
|
||||
use Rector\Generics\Tests\Rector\Class_\GenericsPHPStormMethodAnnotationRector\Source\RealObject;
|
||||
|
||||
/**
|
||||
* @template TEntity as object
|
||||
*/
|
||||
abstract class AbstractRepository
|
||||
{
|
||||
/**
|
||||
* @return TEntity
|
||||
*/
|
||||
public function find($id)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @template TEntity as RealObject
|
||||
* @extends AbstractRepository<TEntity>
|
||||
*/
|
||||
final class AndroidDeviceRepository extends AbstractRepository
|
||||
{
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generics\Tests\Rector\Class_\GenericsPHPStormMethodAnnotationRector\Fixture;
|
||||
|
||||
use Rector\Generics\Tests\Rector\Class_\GenericsPHPStormMethodAnnotationRector\Source\RealObject;
|
||||
|
||||
/**
|
||||
* @template TEntity as object
|
||||
*/
|
||||
abstract class AbstractRepository
|
||||
{
|
||||
/**
|
||||
* @return TEntity
|
||||
*/
|
||||
public function find($id)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @template TEntity as RealObject
|
||||
* @extends AbstractRepository<TEntity>
|
||||
* @method RealObject find($id)
|
||||
*/
|
||||
final class AndroidDeviceRepository extends AbstractRepository
|
||||
{
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generics\Tests\Rector\Class_\GenericsPHPStormMethodAnnotationRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Generics\Rector\Class_\GenericsPHPStormMethodAnnotationRector;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
final class GenericsPHPStormMethodAnnotationRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function test(SmartFileInfo $fileInfo): void
|
||||
{
|
||||
$this->doTestFileInfo($fileInfo);
|
||||
}
|
||||
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
|
||||
}
|
||||
|
||||
protected function getRectorClass(): string
|
||||
{
|
||||
return GenericsPHPStormMethodAnnotationRector::class;
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generics\Tests\Rector\Class_\GenericsPHPStormMethodAnnotationRector\Source;
|
||||
|
||||
final class RealObject
|
||||
{
|
||||
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Php71\Rector\BinaryOp;
|
||||
|
||||
use Rector\Core\ValueObject\PhpVersionFeature;
|
||||
use Rector\Generic\Rector\AbstractIsAbleFunCallRector;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
/**
|
||||
* @see \Rector\Php71\Tests\Rector\BinaryOp\IsIterableRector\IsIterableRectorTest
|
||||
*/
|
||||
final class IsIterableRector extends AbstractIsAbleFunCallRector
|
||||
{
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition(
|
||||
'Changes is_array + Traversable check to is_iterable',
|
||||
[new CodeSample('is_array($foo) || $foo instanceof Traversable;', 'is_iterable($foo);')]);
|
||||
}
|
||||
|
||||
public function getFuncName(): string
|
||||
{
|
||||
return 'is_iterable';
|
||||
}
|
||||
|
||||
public function getPhpVersion(): int
|
||||
{
|
||||
return PhpVersionFeature::IS_ITERABLE;
|
||||
}
|
||||
|
||||
public function getType(): string
|
||||
{
|
||||
return 'Traversable';
|
||||
}
|
||||
}
|
@ -2,15 +2,20 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Rector;
|
||||
namespace Rector\Php71\Rector\BooleanOr;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\BinaryOp\BooleanOr;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Generic\Contract\IsAbleFuncCallInterface;
|
||||
use Rector\Core\ValueObject\PhpVersionFeature;
|
||||
use Rector\Php71\IsArrayAndDualCheckToAble;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
abstract class AbstractIsAbleFunCallRector extends AbstractRector implements IsAbleFuncCallInterface
|
||||
/**
|
||||
* @see \Rector\Php71\Tests\Rector\BooleanOr\IsIterableRector\IsIterableRectorTest
|
||||
*/
|
||||
final class IsIterableRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var IsArrayAndDualCheckToAble
|
||||
@ -22,6 +27,13 @@ abstract class AbstractIsAbleFunCallRector extends AbstractRector implements IsA
|
||||
$this->isArrayAndDualCheckToAble = $isArrayAndDualCheckToAble;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition(
|
||||
'Changes is_array + Traversable check to is_iterable',
|
||||
[new CodeSample('is_array($foo) || $foo instanceof Traversable;', 'is_iterable($foo);')]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
@ -39,19 +51,15 @@ abstract class AbstractIsAbleFunCallRector extends AbstractRector implements IsA
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->isArrayAndDualCheckToAble->processBooleanOr(
|
||||
$node,
|
||||
$this->getType(),
|
||||
$this->getFuncName()
|
||||
) ?: $node;
|
||||
return $this->isArrayAndDualCheckToAble->processBooleanOr($node, 'Traversable', 'is_iterable') ?: $node;
|
||||
}
|
||||
|
||||
private function shouldSkip(): bool
|
||||
{
|
||||
if (function_exists($this->getFuncName())) {
|
||||
if (function_exists('is_iterable')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->isAtLeastPhpVersion($this->getPhpVersion());
|
||||
return ! $this->isAtLeastPhpVersion(PhpVersionFeature::IS_ITERABLE);
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Php71\Tests\Rector\BinaryOp\IsIterableRector\Fixture;
|
||||
namespace Rector\Php71\Tests\Rector\BooleanOr\IsIterableRector\Fixture;
|
||||
|
||||
use Traversable;
|
||||
|
||||
@ -19,7 +19,7 @@ function isIterable()
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Php71\Tests\Rector\BinaryOp\IsIterableRector\Fixture;
|
||||
namespace Rector\Php71\Tests\Rector\BooleanOr\IsIterableRector\Fixture;
|
||||
|
||||
use Traversable;
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Php71\Tests\Rector\BinaryOp\IsIterableRector\Fixture;
|
||||
namespace Rector\Php71\Tests\Rector\BooleanOr\IsIterableRector\Fixture;
|
||||
|
||||
use Traversable;
|
||||
|
||||
@ -24,7 +24,7 @@ if (! function_exists('is_iterable')) {
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Php71\Tests\Rector\BinaryOp\IsIterableRector\Fixture;
|
||||
namespace Rector\Php71\Tests\Rector\BooleanOr\IsIterableRector\Fixture;
|
||||
|
||||
use Traversable;
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Php71\Tests\Rector\BinaryOp\IsIterableRector;
|
||||
namespace Rector\Php71\Tests\Rector\BooleanOr\IsIterableRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Php71\Rector\BinaryOp\IsIterableRector;
|
||||
use Rector\Php71\Rector\BooleanOr\IsIterableRector;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Php71\Tests\Rector\BinaryOp\IsIterableRector;
|
||||
namespace Rector\Php71\Tests\Rector\BooleanOr\IsIterableRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Core\ValueObject\PhpVersionFeature;
|
||||
use Rector\Php71\Rector\BinaryOp\IsIterableRector;
|
||||
use Rector\Php71\Rector\BooleanOr\IsIterableRector;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
@ -1,49 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Php73\Rector\BinaryOp;
|
||||
|
||||
use Rector\Core\ValueObject\PhpVersionFeature;
|
||||
use Rector\Generic\Rector\AbstractIsAbleFunCallRector;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
/**
|
||||
* @see \Rector\Php73\Tests\Rector\BinaryOp\IsCountableRector\IsCountableRectorTest
|
||||
*/
|
||||
final class IsCountableRector extends AbstractIsAbleFunCallRector
|
||||
{
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition(
|
||||
'Changes is_array + Countable check to is_countable',
|
||||
[
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
is_array($foo) || $foo instanceof Countable;
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
is_countable($foo);
|
||||
CODE_SAMPLE
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function getType(): string
|
||||
{
|
||||
return 'Countable';
|
||||
}
|
||||
|
||||
public function getFuncName(): string
|
||||
{
|
||||
return 'is_countable';
|
||||
}
|
||||
|
||||
public function getPhpVersion(): int
|
||||
{
|
||||
return PhpVersionFeature::IS_COUNTABLE;
|
||||
}
|
||||
}
|
76
rules/php73/src/Rector/BooleanOr/IsCountableRector.php
Normal file
76
rules/php73/src/Rector/BooleanOr/IsCountableRector.php
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Php73\Rector\BooleanOr;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\BinaryOp\BooleanOr;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\ValueObject\PhpVersionFeature;
|
||||
use Rector\Php71\IsArrayAndDualCheckToAble;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
/**
|
||||
* @see \Rector\Php73\Tests\Rector\BinaryOr\IsCountableRector\IsCountableRectorTest
|
||||
*/
|
||||
final class IsCountableRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var IsArrayAndDualCheckToAble
|
||||
*/
|
||||
private $isArrayAndDualCheckToAble;
|
||||
|
||||
public function __construct(IsArrayAndDualCheckToAble $isArrayAndDualCheckToAble)
|
||||
{
|
||||
$this->isArrayAndDualCheckToAble = $isArrayAndDualCheckToAble;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition(
|
||||
'Changes is_array + Countable check to is_countable',
|
||||
[
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
is_array($foo) || $foo instanceof Countable;
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
is_countable($foo);
|
||||
CODE_SAMPLE
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [BooleanOr::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BooleanOr $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if ($this->shouldSkip()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->isArrayAndDualCheckToAble->processBooleanOr($node, 'Countable', 'is_countable') ?: $node;
|
||||
}
|
||||
|
||||
private function shouldSkip(): bool
|
||||
{
|
||||
if (function_exists('is_countable')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->isAtLeastPhpVersion(PhpVersionFeature::IS_COUNTABLE);
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Php73\Tests\Rector\BinaryOp\IsCountableRector\Fixture;
|
||||
namespace Rector\Php73\Tests\Rector\BinaryOr\IsCountableRector\Fixture;
|
||||
|
||||
class Fixture73
|
||||
{
|
||||
@ -14,7 +14,7 @@ class Fixture73
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Php73\Tests\Rector\BinaryOp\IsCountableRector\Fixture;
|
||||
namespace Rector\Php73\Tests\Rector\BinaryOr\IsCountableRector\Fixture;
|
||||
|
||||
class Fixture73
|
||||
{
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Php73\Tests\Rector\BinaryOp\IsCountableRector\Fixture;
|
||||
namespace Rector\Php73\Tests\Rector\BinaryOr\IsCountableRector\Fixture;
|
||||
|
||||
use Countable;
|
||||
|
||||
@ -24,7 +24,7 @@ if (! function_exists('is_countable')) {
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Php73\Tests\Rector\BinaryOp\IsCountableRector\Fixture;
|
||||
namespace Rector\Php73\Tests\Rector\BinaryOr\IsCountableRector\Fixture;
|
||||
|
||||
use Countable;
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Php73\Tests\Rector\BinaryOp\IsCountableRector;
|
||||
namespace Rector\Php73\Tests\Rector\BinaryOr\IsCountableRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Php73\Rector\BinaryOp\IsCountableRector;
|
||||
use Rector\Php73\Rector\BooleanOr\IsCountableRector;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Php73\Tests\Rector\BinaryOp\IsCountableRector;
|
||||
namespace Rector\Php73\Tests\Rector\BinaryOr\IsCountableRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Core\ValueObject\PhpVersionFeature;
|
||||
use Rector\Php73\Rector\BinaryOp\IsCountableRector;
|
||||
use Rector\Php73\Rector\BooleanOr\IsCountableRector;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
@ -18,9 +18,9 @@ use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\PhpParser\Node\CustomNode\FileWithoutNamespace;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\Util\StaticInstanceOf;
|
||||
use Rector\Generic\ValueObject\PseudoNamespaceToNamespace;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\NodeTypeResolver\PhpDoc\PhpDocTypeRenamer;
|
||||
use Rector\Renaming\ValueObject\PseudoNamespaceToNamespace;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
use Webmozart\Assert\Assert;
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\ValueObject;
|
||||
namespace Rector\Renaming\ValueObject;
|
||||
|
||||
final class PseudoNamespaceToNamespace
|
||||
{
|
@ -5,8 +5,8 @@ declare(strict_types=1);
|
||||
namespace Rector\Renaming\Tests\Rector\FileWithoutNamespace\PseudoNamespaceToNamespaceRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Generic\ValueObject\PseudoNamespaceToNamespace;
|
||||
use Rector\Renaming\Rector\FileWithoutNamespace\PseudoNamespaceToNamespaceRector;
|
||||
use Rector\Renaming\ValueObject\PseudoNamespaceToNamespace;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user