mirror of
https://github.com/rectorphp/rector.git
synced 2025-01-17 21:38:22 +01:00
Updated Rector to commit f7e1b1f57e8746e07627799b5d9813e12c1c7b56
f7e1b1f57e
[NodeAnalyzer] Use PHPStan ClassReflection to detect anonymous class on ClassAnalyzer (#3543)
This commit is contained in:
parent
817a8ccc28
commit
0e412b55cb
@ -12,11 +12,11 @@ use PhpParser\Node\Stmt\ClassLike;
|
||||
use PhpParser\Node\Stmt\Namespace_;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
|
||||
use PHPStan\Reflection\ClassReflection;
|
||||
use PHPStan\Reflection\ReflectionProvider;
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
|
||||
use Rector\CodingStyle\NodeAnalyzer\UseImportNameMatcher;
|
||||
use Rector\Core\NodeAnalyzer\ClassAnalyzer;
|
||||
use Rector\Core\PhpParser\Node\BetterNodeFinder;
|
||||
use Rector\Core\Util\StringUtils;
|
||||
use Rector\Core\ValueObject\Application\File;
|
||||
@ -69,19 +69,13 @@ final class ShortNameResolver
|
||||
* @var \Rector\CodingStyle\NodeAnalyzer\UseImportNameMatcher
|
||||
*/
|
||||
private $useImportNameMatcher;
|
||||
/**
|
||||
* @readonly
|
||||
* @var \Rector\Core\NodeAnalyzer\ClassAnalyzer
|
||||
*/
|
||||
private $classAnalyzer;
|
||||
public function __construct(SimpleCallableNodeTraverser $simpleCallableNodeTraverser, NodeNameResolver $nodeNameResolver, ReflectionProvider $reflectionProvider, BetterNodeFinder $betterNodeFinder, UseImportNameMatcher $useImportNameMatcher, ClassAnalyzer $classAnalyzer)
|
||||
public function __construct(SimpleCallableNodeTraverser $simpleCallableNodeTraverser, NodeNameResolver $nodeNameResolver, ReflectionProvider $reflectionProvider, BetterNodeFinder $betterNodeFinder, UseImportNameMatcher $useImportNameMatcher)
|
||||
{
|
||||
$this->simpleCallableNodeTraverser = $simpleCallableNodeTraverser;
|
||||
$this->nodeNameResolver = $nodeNameResolver;
|
||||
$this->reflectionProvider = $reflectionProvider;
|
||||
$this->betterNodeFinder = $betterNodeFinder;
|
||||
$this->useImportNameMatcher = $useImportNameMatcher;
|
||||
$this->classAnalyzer = $classAnalyzer;
|
||||
}
|
||||
// Avoids circular reference
|
||||
/**
|
||||
@ -165,7 +159,7 @@ final class ShortNameResolver
|
||||
*/
|
||||
private function resolveFromStmtsDocBlocks(array $stmts) : array
|
||||
{
|
||||
$reflectionClass = $this->resolveNativeClassReflection($stmts);
|
||||
$classReflection = $this->resolveClassReflection($stmts);
|
||||
$shortNames = [];
|
||||
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($stmts, function (Node $node) use(&$shortNames) {
|
||||
// speed up for nodes that are
|
||||
@ -189,12 +183,12 @@ final class ShortNameResolver
|
||||
});
|
||||
return null;
|
||||
});
|
||||
return $this->fqnizeShortNames($shortNames, $reflectionClass, $stmts);
|
||||
return $this->fqnizeShortNames($shortNames, $classReflection, $stmts);
|
||||
}
|
||||
/**
|
||||
* @param Node[] $stmts
|
||||
*/
|
||||
private function resolveNativeClassReflection(array $stmts) : ?ReflectionClass
|
||||
private function resolveClassReflection(array $stmts) : ?ClassReflection
|
||||
{
|
||||
$firstClassLike = $this->betterNodeFinder->findFirstInstanceOf($stmts, ClassLike::class);
|
||||
if (!$firstClassLike instanceof ClassLike) {
|
||||
@ -204,21 +198,21 @@ final class ShortNameResolver
|
||||
if (!$this->reflectionProvider->hasClass($className)) {
|
||||
return null;
|
||||
}
|
||||
$classReflection = $this->reflectionProvider->getClass($className);
|
||||
return $classReflection->getNativeReflection();
|
||||
return $this->reflectionProvider->getClass($className);
|
||||
}
|
||||
/**
|
||||
* @param string[] $shortNames
|
||||
* @param Stmt[] $stmts
|
||||
* @return array<string, string>
|
||||
*/
|
||||
private function fqnizeShortNames(array $shortNames, ?ReflectionClass $reflectionClass, array $stmts) : array
|
||||
private function fqnizeShortNames(array $shortNames, ?ClassReflection $classReflection, array $stmts) : array
|
||||
{
|
||||
$shortNamesToFullyQualifiedNames = [];
|
||||
$nativeReflectionClass = $classReflection instanceof ClassReflection && !$classReflection->isAnonymous() ? $classReflection->getNativeReflection() : null;
|
||||
foreach ($shortNames as $shortName) {
|
||||
$stmtsMatchedName = $this->useImportNameMatcher->matchNameWithStmts($shortName, $stmts);
|
||||
if ($reflectionClass instanceof ReflectionClass && !$this->classAnalyzer->isAnonymousClassName($reflectionClass->getShortName())) {
|
||||
$fullyQualifiedName = Reflection::expandClassName($shortName, $reflectionClass);
|
||||
if ($nativeReflectionClass instanceof ReflectionClass) {
|
||||
$fullyQualifiedName = Reflection::expandClassName($shortName, $nativeReflectionClass);
|
||||
} elseif (\is_string($stmtsMatchedName)) {
|
||||
$fullyQualifiedName = $stmtsMatchedName;
|
||||
} else {
|
||||
|
@ -19,12 +19,12 @@ final class VersionResolver
|
||||
* @api
|
||||
* @var string
|
||||
*/
|
||||
public const PACKAGE_VERSION = '58d862b6f54529f25ecb994ea5e7d2c3eb69f210';
|
||||
public const PACKAGE_VERSION = 'f7e1b1f57e8746e07627799b5d9813e12c1c7b56';
|
||||
/**
|
||||
* @api
|
||||
* @var string
|
||||
*/
|
||||
public const RELEASE_DATE = '2023-03-31 03:39:54';
|
||||
public const RELEASE_DATE = '2023-04-01 04:37:43';
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
|
@ -4,48 +4,28 @@ declare (strict_types=1);
|
||||
namespace Rector\Core\NodeAnalyzer;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\New_;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use Rector\Core\Util\StringUtils;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Reflection\ClassReflection;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
final class ClassAnalyzer
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
* @see https://regex101.com/r/FQH6RT/2
|
||||
*/
|
||||
private const ANONYMOUS_CLASS_REGEX = '#^AnonymousClass\\w+$#';
|
||||
/**
|
||||
* @readonly
|
||||
* @var \Rector\NodeNameResolver\NodeNameResolver
|
||||
*/
|
||||
private $nodeNameResolver;
|
||||
public function __construct(NodeNameResolver $nodeNameResolver)
|
||||
{
|
||||
$this->nodeNameResolver = $nodeNameResolver;
|
||||
}
|
||||
public function isAnonymousClassName(string $className) : bool
|
||||
{
|
||||
return StringUtils::isMatch($className, self::ANONYMOUS_CLASS_REGEX);
|
||||
}
|
||||
public function isAnonymousClass(Node $node) : bool
|
||||
{
|
||||
if (!$node instanceof Class_) {
|
||||
return \false;
|
||||
}
|
||||
$parentNode = $node->getAttribute(AttributeKey::PARENT_NODE);
|
||||
if (!$parentNode instanceof New_) {
|
||||
return \false;
|
||||
}
|
||||
if ($node->isAnonymous()) {
|
||||
return \true;
|
||||
}
|
||||
$className = $this->nodeNameResolver->getName($node);
|
||||
if ($className === null) {
|
||||
return \true;
|
||||
$scope = $node->getAttribute(AttributeKey::SCOPE);
|
||||
if (!$scope instanceof Scope) {
|
||||
return \false;
|
||||
}
|
||||
// match PHPStan pattern for anonymous classes
|
||||
return StringUtils::isMatch($className, self::ANONYMOUS_CLASS_REGEX);
|
||||
$classReflection = $scope->getClassReflection();
|
||||
if ($classReflection instanceof ClassReflection) {
|
||||
return $classReflection->isAnonymous();
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
}
|
||||
|
2
vendor/autoload.php
vendored
2
vendor/autoload.php
vendored
@ -22,4 +22,4 @@ if (PHP_VERSION_ID < 50600) {
|
||||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInitfbb79adddead867277f9db7383d4e715::getLoader();
|
||||
return ComposerAutoloaderInit1d2c34c788e254b6ac517d40b0c38046::getLoader();
|
||||
|
10
vendor/composer/autoload_real.php
vendored
10
vendor/composer/autoload_real.php
vendored
@ -2,7 +2,7 @@
|
||||
|
||||
// autoload_real.php @generated by Composer
|
||||
|
||||
class ComposerAutoloaderInitfbb79adddead867277f9db7383d4e715
|
||||
class ComposerAutoloaderInit1d2c34c788e254b6ac517d40b0c38046
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
@ -22,17 +22,17 @@ class ComposerAutoloaderInitfbb79adddead867277f9db7383d4e715
|
||||
return self::$loader;
|
||||
}
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInitfbb79adddead867277f9db7383d4e715', 'loadClassLoader'), true, true);
|
||||
spl_autoload_register(array('ComposerAutoloaderInit1d2c34c788e254b6ac517d40b0c38046', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInitfbb79adddead867277f9db7383d4e715', 'loadClassLoader'));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInit1d2c34c788e254b6ac517d40b0c38046', 'loadClassLoader'));
|
||||
|
||||
require __DIR__ . '/autoload_static.php';
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInitfbb79adddead867277f9db7383d4e715::getInitializer($loader));
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInit1d2c34c788e254b6ac517d40b0c38046::getInitializer($loader));
|
||||
|
||||
$loader->setClassMapAuthoritative(true);
|
||||
$loader->register(true);
|
||||
|
||||
$filesToLoad = \Composer\Autoload\ComposerStaticInitfbb79adddead867277f9db7383d4e715::$files;
|
||||
$filesToLoad = \Composer\Autoload\ComposerStaticInit1d2c34c788e254b6ac517d40b0c38046::$files;
|
||||
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
|
||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||
|
8
vendor/composer/autoload_static.php
vendored
8
vendor/composer/autoload_static.php
vendored
@ -4,7 +4,7 @@
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
class ComposerStaticInitfbb79adddead867277f9db7383d4e715
|
||||
class ComposerStaticInit1d2c34c788e254b6ac517d40b0c38046
|
||||
{
|
||||
public static $files = array (
|
||||
'ad155f8f1cf0d418fe49e248db8c661b' => __DIR__ . '/..' . '/react/promise/src/functions_include.php',
|
||||
@ -3130,9 +3130,9 @@ class ComposerStaticInitfbb79adddead867277f9db7383d4e715
|
||||
public static function getInitializer(ClassLoader $loader)
|
||||
{
|
||||
return \Closure::bind(function () use ($loader) {
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInitfbb79adddead867277f9db7383d4e715::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInitfbb79adddead867277f9db7383d4e715::$prefixDirsPsr4;
|
||||
$loader->classMap = ComposerStaticInitfbb79adddead867277f9db7383d4e715::$classMap;
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInit1d2c34c788e254b6ac517d40b0c38046::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInit1d2c34c788e254b6ac517d40b0c38046::$prefixDirsPsr4;
|
||||
$loader->classMap = ComposerStaticInit1d2c34c788e254b6ac517d40b0c38046::$classMap;
|
||||
|
||||
}, null, ClassLoader::class);
|
||||
}
|
||||
|
44
vendor/composer/installed.json
vendored
44
vendor/composer/installed.json
vendored
@ -2343,17 +2343,17 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony\/console",
|
||||
"version": "v6.2.7",
|
||||
"version_normalized": "6.2.7.0",
|
||||
"version": "v6.2.8",
|
||||
"version_normalized": "6.2.8.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https:\/\/github.com\/symfony\/console.git",
|
||||
"reference": "cbad09eb8925b6ad4fb721c7a179344dc4a19d45"
|
||||
"reference": "3582d68a64a86ec25240aaa521ec8bc2342b369b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https:\/\/api.github.com\/repos\/symfony\/console\/zipball\/cbad09eb8925b6ad4fb721c7a179344dc4a19d45",
|
||||
"reference": "cbad09eb8925b6ad4fb721c7a179344dc4a19d45",
|
||||
"url": "https:\/\/api.github.com\/repos\/symfony\/console\/zipball\/3582d68a64a86ec25240aaa521ec8bc2342b369b",
|
||||
"reference": "3582d68a64a86ec25240aaa521ec8bc2342b369b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -2388,7 +2388,7 @@
|
||||
"symfony\/lock": "",
|
||||
"symfony\/process": ""
|
||||
},
|
||||
"time": "2023-02-25T17:00:03+00:00",
|
||||
"time": "2023-03-29T21:42:15+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
@ -2417,12 +2417,12 @@
|
||||
"homepage": "https:\/\/symfony.com",
|
||||
"keywords": [
|
||||
"cli",
|
||||
"command line",
|
||||
"command-line",
|
||||
"console",
|
||||
"terminal"
|
||||
],
|
||||
"support": {
|
||||
"source": "https:\/\/github.com\/symfony\/console\/tree\/v6.2.7"
|
||||
"source": "https:\/\/github.com\/symfony\/console\/tree\/v6.2.8"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -2947,23 +2947,23 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony\/process",
|
||||
"version": "v6.2.7",
|
||||
"version_normalized": "6.2.7.0",
|
||||
"version": "v6.2.8",
|
||||
"version_normalized": "6.2.8.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https:\/\/github.com\/symfony\/process.git",
|
||||
"reference": "680e8a2ea6b3f87aecc07a6a65a203ae573d1902"
|
||||
"reference": "75ed64103df4f6615e15a7fe38b8111099f47416"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https:\/\/api.github.com\/repos\/symfony\/process\/zipball\/680e8a2ea6b3f87aecc07a6a65a203ae573d1902",
|
||||
"reference": "680e8a2ea6b3f87aecc07a6a65a203ae573d1902",
|
||||
"url": "https:\/\/api.github.com\/repos\/symfony\/process\/zipball\/75ed64103df4f6615e15a7fe38b8111099f47416",
|
||||
"reference": "75ed64103df4f6615e15a7fe38b8111099f47416",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.1"
|
||||
},
|
||||
"time": "2023-02-24T10:42:00+00:00",
|
||||
"time": "2023-03-09T16:20:02+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
@ -2991,7 +2991,7 @@
|
||||
"description": "Executes commands in sub-processes",
|
||||
"homepage": "https:\/\/symfony.com",
|
||||
"support": {
|
||||
"source": "https:\/\/github.com\/symfony\/process\/tree\/v6.2.7"
|
||||
"source": "https:\/\/github.com\/symfony\/process\/tree\/v6.2.8"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -3011,17 +3011,17 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony\/string",
|
||||
"version": "v6.2.7",
|
||||
"version_normalized": "6.2.7.0",
|
||||
"version": "v6.2.8",
|
||||
"version_normalized": "6.2.8.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https:\/\/github.com\/symfony\/string.git",
|
||||
"reference": "67b8c1eec78296b85dc1c7d9743830160218993d"
|
||||
"reference": "193e83bbd6617d6b2151c37fff10fa7168ebddef"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https:\/\/api.github.com\/repos\/symfony\/string\/zipball\/67b8c1eec78296b85dc1c7d9743830160218993d",
|
||||
"reference": "67b8c1eec78296b85dc1c7d9743830160218993d",
|
||||
"url": "https:\/\/api.github.com\/repos\/symfony\/string\/zipball\/193e83bbd6617d6b2151c37fff10fa7168ebddef",
|
||||
"reference": "193e83bbd6617d6b2151c37fff10fa7168ebddef",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -3041,7 +3041,7 @@
|
||||
"symfony\/translation-contracts": "^2.0|^3.0",
|
||||
"symfony\/var-exporter": "^5.4|^6.0"
|
||||
},
|
||||
"time": "2023-02-24T10:42:00+00:00",
|
||||
"time": "2023-03-20T16:06:02+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
@ -3080,7 +3080,7 @@
|
||||
"utf8"
|
||||
],
|
||||
"support": {
|
||||
"source": "https:\/\/github.com\/symfony\/string\/tree\/v6.2.7"
|
||||
"source": "https:\/\/github.com\/symfony\/string\/tree\/v6.2.8"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
2
vendor/composer/installed.php
vendored
2
vendor/composer/installed.php
vendored
File diff suppressed because one or more lines are too long
@ -53,9 +53,10 @@ final class DumpCompletionCommand extends Command
|
||||
[$rcFile, $completionFile] = ['~/.bashrc', "/etc/bash_completion.d/{$commandName}"];
|
||||
break;
|
||||
}
|
||||
$supportedShells = \implode(', ', $this->getSupportedShells());
|
||||
$this->setHelp(<<<EOH
|
||||
The <info>%command.name%</> command dumps the shell completion script required
|
||||
to use shell autocompletion (currently, bash and fish completion is supported).
|
||||
to use shell autocompletion (currently, {$supportedShells} completion are supported).
|
||||
|
||||
<comment>Static installation
|
||||
-------------------</>
|
||||
|
@ -89,7 +89,7 @@ class OutputFormatterStyle implements OutputFormatterStyleInterface
|
||||
}
|
||||
public function apply(string $text) : string
|
||||
{
|
||||
$this->handlesHrefGracefully = $this->handlesHrefGracefully ?? 'JetBrains-JediTerm' !== \getenv('TERMINAL_EMULATOR') && (!\getenv('KONSOLE_VERSION') || (int) \getenv('KONSOLE_VERSION') > 201100);
|
||||
$this->handlesHrefGracefully = $this->handlesHrefGracefully ?? 'JetBrains-JediTerm' !== \getenv('TERMINAL_EMULATOR') && (!\getenv('KONSOLE_VERSION') || (int) \getenv('KONSOLE_VERSION') > 201100) && !isset($_SERVER['IDEA_INITIAL_DIRECTORY']);
|
||||
if (null !== $this->href && $this->handlesHrefGracefully) {
|
||||
$text = "\x1b]8;;{$this->href}\x1b\\{$text}\x1b]8;;\x1b\\";
|
||||
}
|
||||
|
2
vendor/symfony/console/composer.json
vendored
2
vendor/symfony/console/composer.json
vendored
@ -5,7 +5,7 @@
|
||||
"keywords": [
|
||||
"console",
|
||||
"cli",
|
||||
"command line",
|
||||
"command-line",
|
||||
"terminal"
|
||||
],
|
||||
"homepage": "https:\/\/symfony.com",
|
||||
|
@ -43,12 +43,16 @@ final class EnglishInflector implements InflectorInterface
|
||||
['nexo', 4, \false, \false, 'ox'],
|
||||
// indices (index), appendices (appendix), prices (price)
|
||||
['seci', 4, \false, \true, ['ex', 'ix', 'ice']],
|
||||
// codes (code)
|
||||
['sedoc', 5, \false, \true, 'code'],
|
||||
// selfies (selfie)
|
||||
['seifles', 7, \true, \true, 'selfie'],
|
||||
// zombies (zombie)
|
||||
['seibmoz', 7, \true, \true, 'zombie'],
|
||||
// movies (movie)
|
||||
['seivom', 6, \true, \true, 'movie'],
|
||||
// names (name)
|
||||
['seman', 5, \true, \false, 'name'],
|
||||
// conspectuses (conspectus), prospectuses (prospectus)
|
||||
['sesutcep', 8, \true, \true, 'pectus'],
|
||||
// feet (foot)
|
||||
|
Loading…
x
Reference in New Issue
Block a user