Updated Rector to commit 682df75fc015d0f267780ec5363aa74f82dba58b

682df75fc0 [CodingStyle][Namespace_] Support constant imports (#4612)
This commit is contained in:
Tomas Votruba 2023-07-28 13:10:47 +00:00
parent 55435b8ef5
commit 1d52a6cf83
12 changed files with 100 additions and 54 deletions

View File

@ -24,6 +24,10 @@ final class UseNodesToAddCollector implements NodeCollectorInterface
* @var \Rector\Naming\Naming\UseImportsResolver
*/
private $useImportsResolver;
/**
* @var array<string, FullyQualifiedObjectType[]>
*/
private $constantUseImportTypesInFilePath = [];
/**
* @var array<string, FullyQualifiedObjectType[]>
*/
@ -47,6 +51,12 @@ final class UseNodesToAddCollector implements NodeCollectorInterface
$file = $this->currentFileProvider->getFile();
$this->useImportTypesInFilePath[$file->getFilePath()][] = $fullyQualifiedObjectType;
}
public function addConstantUseImport(FullyQualifiedObjectType $fullyQualifiedObjectType) : void
{
/** @var File $file */
$file = $this->currentFileProvider->getFile();
$this->constantUseImportTypesInFilePath[$file->getFilePath()][] = $fullyQualifiedObjectType;
}
public function addFunctionUseImport(FullyQualifiedObjectType $fullyQualifiedObjectType) : void
{
/** @var File $file */
@ -90,6 +100,12 @@ final class UseNodesToAddCollector implements NodeCollectorInterface
if ($this->isShortClassImported($filePath, $shortName)) {
return \true;
}
$fileConstantUseImportTypes = $this->constantUseImportTypesInFilePath[$filePath] ?? [];
foreach ($fileConstantUseImportTypes as $fileConstantUseImportType) {
if ($fileConstantUseImportType->getShortName() === $shortName) {
return \true;
}
}
$fileFunctionUseImportTypes = $this->functionUseImportTypesInFilePath[$filePath] ?? [];
foreach ($fileFunctionUseImportTypes as $fileFunctionUseImportType) {
if ($fileFunctionUseImportType->getShortName() === $shortName) {
@ -107,6 +123,12 @@ final class UseNodesToAddCollector implements NodeCollectorInterface
return \true;
}
}
$constantImports = $this->constantUseImportTypesInFilePath[$filePath] ?? [];
foreach ($constantImports as $constantImport) {
if ($fullyQualifiedObjectType->equals($constantImport)) {
return \true;
}
}
$functionImports = $this->functionUseImportTypesInFilePath[$filePath] ?? [];
foreach ($functionImports as $functionImport) {
if ($fullyQualifiedObjectType->equals($functionImport)) {
@ -122,6 +144,13 @@ final class UseNodesToAddCollector implements NodeCollectorInterface
{
return $this->useImportTypesInFilePath[$filePath] ?? [];
}
/**
* @return FullyQualifiedObjectType[]
*/
public function getConstantImportsByFilePath(string $filePath) : array
{
return $this->constantUseImportTypesInFilePath[$filePath] ?? [];
}
/**
* @return FullyQualifiedObjectType[]
*/

View File

@ -66,8 +66,9 @@ final class UseAddingPostRector extends \Rector\PostRector\Rector\AbstractPostRe
throw new ShouldNotHappenException();
}
$useImportTypes = $this->useNodesToAddCollector->getObjectImportsByFilePath($file->getFilePath());
$constantUseImportTypes = $this->useNodesToAddCollector->getConstantImportsByFilePath($file->getFilePath());
$functionUseImportTypes = $this->useNodesToAddCollector->getFunctionImportsByFilePath($file->getFilePath());
if ($useImportTypes === [] && $functionUseImportTypes === []) {
if ($useImportTypes === [] && $constantUseImportTypes === [] && $functionUseImportTypes === []) {
return $nodes;
}
/** @var FullyQualifiedObjectType[] $useImportTypes */
@ -78,7 +79,7 @@ final class UseAddingPostRector extends \Rector\PostRector\Rector\AbstractPostRe
if (!$rootNode instanceof FileWithoutNamespace && !$rootNode instanceof Namespace_) {
return $nodes;
}
return $this->resolveNodesWithImportedUses($nodes, $useImportTypes, $functionUseImportTypes, $rootNode);
return $this->resolveNodesWithImportedUses($nodes, $useImportTypes, $constantUseImportTypes, $functionUseImportTypes, $rootNode);
}
public function getRuleDefinition() : RuleDefinition
{
@ -105,22 +106,23 @@ CODE_SAMPLE
/**
* @param Stmt[] $nodes
* @param FullyQualifiedObjectType[] $useImportTypes
* @param FullyQualifiedObjectType[] $constantUseImportTypes
* @param FullyQualifiedObjectType[] $functionUseImportTypes
* @return Stmt[]
* @param \Rector\Core\PhpParser\Node\CustomNode\FileWithoutNamespace|\PhpParser\Node\Stmt\Namespace_ $namespace
*/
private function resolveNodesWithImportedUses(array $nodes, array $useImportTypes, array $functionUseImportTypes, $namespace) : array
private function resolveNodesWithImportedUses(array $nodes, array $useImportTypes, array $constantUseImportTypes, array $functionUseImportTypes, $namespace) : array
{
// A. has namespace? add under it
if ($namespace instanceof Namespace_) {
// then add, to prevent adding + removing false positive of same short use
$this->useImportsAdder->addImportsToNamespace($namespace, $useImportTypes, $functionUseImportTypes);
$this->useImportsAdder->addImportsToNamespace($namespace, $useImportTypes, $constantUseImportTypes, $functionUseImportTypes);
return $nodes;
}
// B. no namespace? add in the top
$useImportTypes = $this->filterOutNonNamespacedNames($useImportTypes);
// then add, to prevent adding + removing false positive of same short use
return $this->useImportsAdder->addImportsToStmts($namespace, $nodes, $useImportTypes, $functionUseImportTypes);
return $this->useImportsAdder->addImportsToStmts($namespace, $nodes, $useImportTypes, $constantUseImportTypes, $functionUseImportTypes);
}
/**
* Prevents

View File

@ -29,12 +29,16 @@ final class AliasedObjectType extends ObjectType
{
return $this->fullyQualifiedClass;
}
public function getUseNode() : Use_
public function getUseNode(?int $useType = null) : Use_
{
$name = new Name($this->fullyQualifiedClass);
$name->setAttribute(AttributeKey::IS_USEUSE_NAME, \true);
$useUse = new UseUse($name, $this->getClassName());
return new Use_([$useUse]);
$use = new Use_([$useUse]);
if ($useType !== null) {
$use->type = $useType;
}
return $use;
}
public function getShortName() : string
{
@ -47,15 +51,6 @@ final class AliasedObjectType extends ObjectType
{
return $this->getShortName() === $comparedObjectType->getShortName();
}
public function getFunctionUseNode() : Use_
{
$name = new Name($this->fullyQualifiedClass);
$name->setAttribute(AttributeKey::IS_USEUSE_NAME, \true);
$useUse = new UseUse($name, $this->getClassName());
$use = new Use_([$useUse]);
$use->type = Use_::TYPE_FUNCTION;
return $use;
}
public function equals(Type $type) : bool
{
// compare with FQN classes

View File

@ -42,20 +42,15 @@ final class FullyQualifiedObjectType extends ObjectType
$name->setAttribute(AttributeKey::NAMESPACED_NAME, $this->getClassName());
return $name;
}
public function getUseNode() : Use_
public function getUseNode(?int $useType = null) : Use_
{
$name = new Name($this->getClassName());
$name->setAttribute(AttributeKey::IS_USEUSE_NAME, \true);
$useUse = new UseUse($name);
return new Use_([$useUse]);
}
public function getFunctionUseNode() : Use_
{
$name = new Name($this->getClassName());
$name->setAttribute(AttributeKey::IS_USEUSE_NAME, \true);
$useUse = new UseUse($name, null);
$use = new Use_([$useUse]);
$use->type = Use_::TYPE_FUNCTION;
if ($useType !== null) {
$use->type = $useType;
}
return $use;
}
public function getShortNameLowered() : string

View File

@ -37,16 +37,19 @@ final class UseImportsAdder
/**
* @param Stmt[] $stmts
* @param array<FullyQualifiedObjectType|AliasedObjectType> $useImportTypes
* @param array<FullyQualifiedObjectType|AliasedObjectType> $constantUseImportTypes
* @param array<FullyQualifiedObjectType|AliasedObjectType> $functionUseImportTypes
* @return Stmt[]
*/
public function addImportsToStmts(FileWithoutNamespace $fileWithoutNamespace, array $stmts, array $useImportTypes, array $functionUseImportTypes) : array
public function addImportsToStmts(FileWithoutNamespace $fileWithoutNamespace, array $stmts, array $useImportTypes, array $constantUseImportTypes, array $functionUseImportTypes) : array
{
$existingUseImportTypes = $this->usedImportsResolver->resolveForStmts($stmts);
$existingConstantUseImports = $this->usedImportsResolver->resolveConstantImportsForStmts($stmts);
$existingFunctionUseImports = $this->usedImportsResolver->resolveFunctionImportsForStmts($stmts);
$useImportTypes = $this->diffFullyQualifiedObjectTypes($useImportTypes, $existingUseImportTypes);
$constantUseImportTypes = $this->diffFullyQualifiedObjectTypes($constantUseImportTypes, $existingConstantUseImports);
$functionUseImportTypes = $this->diffFullyQualifiedObjectTypes($functionUseImportTypes, $existingFunctionUseImports);
$newUses = $this->createUses($useImportTypes, $functionUseImportTypes, null);
$newUses = $this->createUses($useImportTypes, $constantUseImportTypes, $functionUseImportTypes, null);
if ($newUses === []) {
return $stmts;
}
@ -74,17 +77,20 @@ final class UseImportsAdder
}
/**
* @param FullyQualifiedObjectType[] $useImportTypes
* @param FullyQualifiedObjectType[] $constantUseImportTypes
* @param FullyQualifiedObjectType[] $functionUseImportTypes
*/
public function addImportsToNamespace(Namespace_ $namespace, array $useImportTypes, array $functionUseImportTypes) : void
public function addImportsToNamespace(Namespace_ $namespace, array $useImportTypes, array $constantUseImportTypes, array $functionUseImportTypes) : void
{
$namespaceName = $this->getNamespaceName($namespace);
$existingUseImportTypes = $this->usedImportsResolver->resolveForStmts($namespace->stmts);
$existingConstantUseImportTypes = $this->usedImportsResolver->resolveConstantImportsForStmts($namespace->stmts);
$existingFunctionUseImportTypes = $this->usedImportsResolver->resolveFunctionImportsForStmts($namespace->stmts);
$existingUseImportTypes = $this->typeFactory->uniquateTypes($existingUseImportTypes);
$useImportTypes = $this->diffFullyQualifiedObjectTypes($useImportTypes, $existingUseImportTypes);
$constantUseImportTypes = $this->diffFullyQualifiedObjectTypes($constantUseImportTypes, $existingConstantUseImportTypes);
$functionUseImportTypes = $this->diffFullyQualifiedObjectTypes($functionUseImportTypes, $existingFunctionUseImportTypes);
$newUses = $this->createUses($useImportTypes, $functionUseImportTypes, $namespaceName);
$newUses = $this->createUses($useImportTypes, $constantUseImportTypes, $functionUseImportTypes, $namespaceName);
if ($newUses === []) {
return;
}
@ -127,25 +133,22 @@ final class UseImportsAdder
}
/**
* @param array<AliasedObjectType|FullyQualifiedObjectType> $useImportTypes
* @param array<FullyQualifiedObjectType|AliasedObjectType> $constantUseImportTypes
* @param array<FullyQualifiedObjectType|AliasedObjectType> $functionUseImportTypes
* @return Use_[]
*/
private function createUses(array $useImportTypes, array $functionUseImportTypes, ?string $namespaceName) : array
private function createUses(array $useImportTypes, array $constantUseImportTypes, array $functionUseImportTypes, ?string $namespaceName) : array
{
$newUses = [];
foreach ($useImportTypes as $useImportType) {
if ($namespaceName !== null && $this->isCurrentNamespace($namespaceName, $useImportType)) {
continue;
$importsMapping = [Use_::TYPE_NORMAL => $useImportTypes, Use_::TYPE_CONSTANT => $constantUseImportTypes, Use_::TYPE_FUNCTION => $functionUseImportTypes];
foreach ($importsMapping as $type => $importTypes) {
foreach ($importTypes as $importType) {
if ($namespaceName !== null && $this->isCurrentNamespace($namespaceName, $importType)) {
continue;
}
// already imported in previous cycle
$newUses[] = $importType->getUseNode($type);
}
// already imported in previous cycle
$newUses[] = $useImportType->getUseNode();
}
foreach ($functionUseImportTypes as $functionUseImportType) {
if ($namespaceName !== null && $this->isCurrentNamespace($namespaceName, $functionUseImportType)) {
continue;
}
// already imported in previous cycle
$newUses[] = $functionUseImportType->getFunctionUseNode();
}
return $newUses;
}

View File

@ -35,6 +35,14 @@ final class UseImportsTraverser
{
$this->traverseForType($stmts, $callable, Use_::TYPE_NORMAL);
}
/**
* @param Stmt[] $stmts
* @param callable(UseUse $useUse, string $name): void $callable
*/
public function traverserStmtsForConstants(array $stmts, callable $callable) : void
{
$this->traverseForType($stmts, $callable, Use_::TYPE_CONSTANT);
}
/**
* @param Stmt[] $stmts
* @param callable(UseUse $useUse, string $name): void $callable

View File

@ -58,6 +58,18 @@ final class UsedImportsResolver
});
return $usedImports;
}
/**
* @param Stmt[] $stmts
* @return FullyQualifiedObjectType[]
*/
public function resolveConstantImportsForStmts(array $stmts) : array
{
$usedConstImports = [];
$this->useImportsTraverser->traverserStmtsForConstants($stmts, static function (UseUse $useUse, string $name) use(&$usedConstImports) : void {
$usedConstImports[] = new FullyQualifiedObjectType($name);
});
return $usedConstImports;
}
/**
* @param Stmt[] $stmts
* @return FullyQualifiedObjectType[]

View File

@ -117,6 +117,8 @@ final class NameImporter
}
if ($name->getAttribute(AttributeKey::IS_FUNCCALL_NAME) === \true) {
$this->useNodesToAddCollector->addFunctionUseImport($fullyQualifiedObjectType);
} elseif ($name->getAttribute(AttributeKey::IS_CONSTFETCH_NAME) === \true) {
$this->useNodesToAddCollector->addConstantUseImport($fullyQualifiedObjectType);
} else {
$this->useNodesToAddCollector->addUseImport($fullyQualifiedObjectType);
}

View File

@ -19,12 +19,12 @@ final class VersionResolver
* @api
* @var string
*/
public const PACKAGE_VERSION = 'dcfa7111b4523e63d70bbbeed7dff206d0291014';
public const PACKAGE_VERSION = '682df75fc015d0f267780ec5363aa74f82dba58b';
/**
* @api
* @var string
*/
public const RELEASE_DATE = '2023-07-27 22:50:41';
public const RELEASE_DATE = '2023-07-28 20:06:56';
/**
* @var int
*/

2
vendor/autoload.php vendored
View File

@ -22,4 +22,4 @@ if (PHP_VERSION_ID < 50600) {
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInita92b3f997a0c81d93e1bdb1d8ef669f2::getLoader();
return ComposerAutoloaderInit0650de368f938e31f14223145acdb538::getLoader();

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInita92b3f997a0c81d93e1bdb1d8ef669f2
class ComposerAutoloaderInit0650de368f938e31f14223145acdb538
{
private static $loader;
@ -22,17 +22,17 @@ class ComposerAutoloaderInita92b3f997a0c81d93e1bdb1d8ef669f2
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInita92b3f997a0c81d93e1bdb1d8ef669f2', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInit0650de368f938e31f14223145acdb538', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInita92b3f997a0c81d93e1bdb1d8ef669f2', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInit0650de368f938e31f14223145acdb538', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInita92b3f997a0c81d93e1bdb1d8ef669f2::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticInit0650de368f938e31f14223145acdb538::getInitializer($loader));
$loader->setClassMapAuthoritative(true);
$loader->register(true);
$filesToLoad = \Composer\Autoload\ComposerStaticInita92b3f997a0c81d93e1bdb1d8ef669f2::$files;
$filesToLoad = \Composer\Autoload\ComposerStaticInit0650de368f938e31f14223145acdb538::$files;
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;

View File

@ -4,7 +4,7 @@
namespace Composer\Autoload;
class ComposerStaticInita92b3f997a0c81d93e1bdb1d8ef669f2
class ComposerStaticInit0650de368f938e31f14223145acdb538
{
public static $files = array (
'ad155f8f1cf0d418fe49e248db8c661b' => __DIR__ . '/..' . '/react/promise/src/functions_include.php',
@ -3023,9 +3023,9 @@ class ComposerStaticInita92b3f997a0c81d93e1bdb1d8ef669f2
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInita92b3f997a0c81d93e1bdb1d8ef669f2::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInita92b3f997a0c81d93e1bdb1d8ef669f2::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInita92b3f997a0c81d93e1bdb1d8ef669f2::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInit0650de368f938e31f14223145acdb538::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit0650de368f938e31f14223145acdb538::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit0650de368f938e31f14223145acdb538::$classMap;
}, null, ClassLoader::class);
}