Updated Rector to commit 6f7805560bab246e796debde6dece3a224ec65a8

6f7805560b [NodeTypeResolver] Handle hang on @template-extends in dependent Files (#1044)
This commit is contained in:
Tomas Votruba 2021-10-23 08:35:53 +00:00
parent f24d3a51b1
commit c5c32118fc
7 changed files with 89 additions and 23 deletions

View File

@ -11,10 +11,10 @@ use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Interface_;
use PhpParser\Node\Stmt\Trait_;
use PhpParser\NodeTraverser;
use PhpParser\Parser;
use PHPStan\AnalysedCodeException;
use PHPStan\Analyser\MutatingScope;
use PHPStan\Analyser\NodeScopeResolver;
use PHPStan\Analyser\Scope;
use PHPStan\Analyser\ScopeContext;
use PHPStan\BetterReflection\Reflection\Exception\NotAnInterfaceReflection;
use PHPStan\BetterReflection\Reflector\ClassReflector;
@ -25,15 +25,19 @@ use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Type\ObjectType;
use Rector\Caching\Detector\ChangedFilesDetector;
use Rector\Caching\FileSystem\DependencyResolver;
use Rector\Core\Application\FileProcessor;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Core\PhpParser\Printer\BetterStandardPrinter;
use Rector\Core\StaticReflection\SourceLocator\ParentAttributeSourceLocator;
use Rector\Core\StaticReflection\SourceLocator\RenamedClassesSourceLocator;
use Rector\Core\Stubs\DummyTraitClass;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\PHPStan\Scope\NodeVisitor\RemoveDeepChainMethodCallNodeVisitor;
use ReflectionClass;
use RectorPrefix20211023\Symplify\PackageBuilder\Reflection\PrivatesAccessor;
use Symplify\SmartFileSystem\SmartFileInfo;
use RectorPrefix20211023\Symplify\SmartFileSystem\SmartFileSystem;
use Throwable;
/**
* @inspired by https://github.com/silverstripe/silverstripe-upgrader/blob/532182b23e854d02e0b27e68ebc394f436de0682/src/UpgradeRule/PHP/Visitor/PHPStanScopeVisitor.php
@ -91,7 +95,19 @@ final class PHPStanNodeScopeResolver
* @var \Rector\Core\PhpParser\Node\BetterNodeFinder
*/
private $betterNodeFinder;
public function __construct(\Rector\Caching\Detector\ChangedFilesDetector $changedFilesDetector, \Rector\Caching\FileSystem\DependencyResolver $dependencyResolver, \PHPStan\Analyser\NodeScopeResolver $nodeScopeResolver, \PHPStan\Reflection\ReflectionProvider $reflectionProvider, \Rector\NodeTypeResolver\PHPStan\Scope\NodeVisitor\RemoveDeepChainMethodCallNodeVisitor $removeDeepChainMethodCallNodeVisitor, \Rector\NodeTypeResolver\PHPStan\Scope\ScopeFactory $scopeFactory, \RectorPrefix20211023\Symplify\PackageBuilder\Reflection\PrivatesAccessor $privatesAccessor, \Rector\Core\StaticReflection\SourceLocator\RenamedClassesSourceLocator $renamedClassesSourceLocator, \Rector\Core\StaticReflection\SourceLocator\ParentAttributeSourceLocator $parentAttributeSourceLocator, \Rector\Core\PhpParser\Node\BetterNodeFinder $betterNodeFinder)
/**
* @var \PhpParser\Parser
*/
private $parser;
/**
* @var \Rector\Core\PhpParser\Printer\BetterStandardPrinter
*/
private $betterStandardPrinter;
/**
* @var \Symplify\SmartFileSystem\SmartFileSystem
*/
private $smartFileSystem;
public function __construct(\Rector\Caching\Detector\ChangedFilesDetector $changedFilesDetector, \Rector\Caching\FileSystem\DependencyResolver $dependencyResolver, \PHPStan\Analyser\NodeScopeResolver $nodeScopeResolver, \PHPStan\Reflection\ReflectionProvider $reflectionProvider, \Rector\NodeTypeResolver\PHPStan\Scope\NodeVisitor\RemoveDeepChainMethodCallNodeVisitor $removeDeepChainMethodCallNodeVisitor, \Rector\NodeTypeResolver\PHPStan\Scope\ScopeFactory $scopeFactory, \RectorPrefix20211023\Symplify\PackageBuilder\Reflection\PrivatesAccessor $privatesAccessor, \Rector\Core\StaticReflection\SourceLocator\RenamedClassesSourceLocator $renamedClassesSourceLocator, \Rector\Core\StaticReflection\SourceLocator\ParentAttributeSourceLocator $parentAttributeSourceLocator, \Rector\Core\PhpParser\Node\BetterNodeFinder $betterNodeFinder, \PhpParser\Parser $parser, \Rector\Core\PhpParser\Printer\BetterStandardPrinter $betterStandardPrinter, \RectorPrefix20211023\Symplify\SmartFileSystem\SmartFileSystem $smartFileSystem)
{
$this->changedFilesDetector = $changedFilesDetector;
$this->dependencyResolver = $dependencyResolver;
@ -103,6 +119,13 @@ final class PHPStanNodeScopeResolver
$this->renamedClassesSourceLocator = $renamedClassesSourceLocator;
$this->parentAttributeSourceLocator = $parentAttributeSourceLocator;
$this->betterNodeFinder = $betterNodeFinder;
/**
* use \PhpParser\Parser on purpose instead of extended \Rector\Core\PhpParser\Parser\Parser
* as detecting `@template-extends` too early on dependent files
*/
$this->parser = $parser;
$this->betterStandardPrinter = $betterStandardPrinter;
$this->smartFileSystem = $smartFileSystem;
}
/**
* @param Stmt[] $nodes
@ -140,8 +163,51 @@ final class PHPStanNodeScopeResolver
}
};
$this->decoratePHPStanNodeScopeResolverWithRenamedClassSourceLocator($this->nodeScopeResolver);
// it needs to be checked early before `@mixin` check as
// ReflectionProvider already hang when check class with `@template-extends`
if ($this->isTemplateExtendsInSource($nodes, $smartFileInfo->getFilename())) {
return $nodes;
}
return $this->processNodesWithMixinHandling($smartFileInfo, $nodes, $scope, $nodeCallback);
}
/**
* @param Node[] $nodes
*/
private function isTemplateExtendsInSource(array $nodes, string $currentFileName) : bool
{
return (bool) $this->betterNodeFinder->findFirst($nodes, function (\PhpParser\Node $node) use($currentFileName) : bool {
if (!$node instanceof \PhpParser\Node\Name\FullyQualified) {
return \false;
}
$className = $node->toString();
// fix error in parallel test
// use function_exists on purpose as using reflectionProvider broke the test in parallel
if (\function_exists($className)) {
return \false;
}
// use class_exists as PHPStan ReflectionProvider hang on check className with `@template-extends`
if (!\class_exists($className)) {
return \false;
}
// use native ReflectionClass as PHPStan ReflectionProvider hang on check className with `@template-extends`
$reflectionClass = new \ReflectionClass($className);
if ($reflectionClass->isInternal()) {
return \false;
}
$fileName = (string) $reflectionClass->getFileName();
if (!$this->smartFileSystem->exists($fileName)) {
return \false;
}
// already checked in FileProcessor::parseFileInfoToLocalCache()
if ($fileName === $currentFileName) {
return \false;
}
$content = $this->smartFileSystem->readFile($fileName);
$fileNodes = $this->parser->parse($content);
$print = $this->betterStandardPrinter->print($fileNodes);
return (bool) \RectorPrefix20211023\Nette\Utils\Strings::match($print, \Rector\Core\Application\FileProcessor::TEMPLATE_EXTENDS_REGEX);
});
}
/**
* @param Stmt[] $nodes
* @return Stmt[]
@ -221,7 +287,7 @@ final class PHPStanNodeScopeResolver
/**
* @param \PhpParser\Node\Stmt\Class_|\PhpParser\Node\Stmt\Interface_ $classLike
*/
private function resolveClassOrInterfaceScope($classLike, \PHPStan\Analyser\MutatingScope $mutatingScope) : \PHPStan\Analyser\Scope
private function resolveClassOrInterfaceScope($classLike, \PHPStan\Analyser\MutatingScope $mutatingScope) : \PHPStan\Analyser\MutatingScope
{
$className = $this->resolveClassName($classLike);
// is anonymous class? - not possible to enter it since PHPStan 0.12.33, see https://github.com/phpstan/phpstan-src/commit/e87fb0ec26f9c8552bbeef26a868b1e5d8185e91

View File

@ -18,7 +18,7 @@ final class FileProcessor
* @var string
* @see https://regex101.com/r/ozPuC9/1
*/
private const TEMPLATE_EXTENDS_REGEX = '#(\\*|\\/\\/)\\s+\\@template-extends\\s+\\\\?\\w+#';
public const TEMPLATE_EXTENDS_REGEX = '#(\\*|\\/\\/)\\s+\\@template-extends\\s+\\\\?\\w+#';
/**
* @var \Rector\ChangesReporting\Collector\AffectedFilesCollector
*/

View File

@ -16,11 +16,11 @@ final class VersionResolver
/**
* @var string
*/
public const PACKAGE_VERSION = 'f9fdebfe589e145aacb7b4d4e99f2be80589d2b2';
public const PACKAGE_VERSION = '6f7805560bab246e796debde6dece3a224ec65a8';
/**
* @var string
*/
public const RELEASE_DATE = '2021-10-23 08:43:48';
public const RELEASE_DATE = '2021-10-23 10:19:10';
public static function resolvePackageVersion() : string
{
$process = new \RectorPrefix20211023\Symfony\Component\Process\Process(['git', 'log', '--pretty="%H"', '-n1', 'HEAD'], __DIR__);

2
vendor/autoload.php vendored
View File

@ -4,4 +4,4 @@
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInite3debac64aaa6a8fa330817c6d733ea8::getLoader();
return ComposerAutoloaderInit28ec809d5b0e2f07c00408e939bd1df2::getLoader();

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInite3debac64aaa6a8fa330817c6d733ea8
class ComposerAutoloaderInit28ec809d5b0e2f07c00408e939bd1df2
{
private static $loader;
@ -22,15 +22,15 @@ class ComposerAutoloaderInite3debac64aaa6a8fa330817c6d733ea8
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInite3debac64aaa6a8fa330817c6d733ea8', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInit28ec809d5b0e2f07c00408e939bd1df2', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
spl_autoload_unregister(array('ComposerAutoloaderInite3debac64aaa6a8fa330817c6d733ea8', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInit28ec809d5b0e2f07c00408e939bd1df2', 'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) {
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInite3debac64aaa6a8fa330817c6d733ea8::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticInit28ec809d5b0e2f07c00408e939bd1df2::getInitializer($loader));
} else {
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
@ -42,19 +42,19 @@ class ComposerAutoloaderInite3debac64aaa6a8fa330817c6d733ea8
$loader->register(true);
if ($useStaticLoader) {
$includeFiles = Composer\Autoload\ComposerStaticInite3debac64aaa6a8fa330817c6d733ea8::$files;
$includeFiles = Composer\Autoload\ComposerStaticInit28ec809d5b0e2f07c00408e939bd1df2::$files;
} else {
$includeFiles = require __DIR__ . '/autoload_files.php';
}
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequiree3debac64aaa6a8fa330817c6d733ea8($fileIdentifier, $file);
composerRequire28ec809d5b0e2f07c00408e939bd1df2($fileIdentifier, $file);
}
return $loader;
}
}
function composerRequiree3debac64aaa6a8fa330817c6d733ea8($fileIdentifier, $file)
function composerRequire28ec809d5b0e2f07c00408e939bd1df2($fileIdentifier, $file)
{
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
require $file;

View File

@ -4,7 +4,7 @@
namespace Composer\Autoload;
class ComposerStaticInite3debac64aaa6a8fa330817c6d733ea8
class ComposerStaticInit28ec809d5b0e2f07c00408e939bd1df2
{
public static $files = array (
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
@ -3910,9 +3910,9 @@ class ComposerStaticInite3debac64aaa6a8fa330817c6d733ea8
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInite3debac64aaa6a8fa330817c6d733ea8::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInite3debac64aaa6a8fa330817c6d733ea8::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInite3debac64aaa6a8fa330817c6d733ea8::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInit28ec809d5b0e2f07c00408e939bd1df2::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit28ec809d5b0e2f07c00408e939bd1df2::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit28ec809d5b0e2f07c00408e939bd1df2::$classMap;
}, null, ClassLoader::class);
}

View File

@ -9,8 +9,8 @@ $loader = require_once __DIR__.'/autoload.php';
if (!class_exists('AutoloadIncluder', false) && !interface_exists('AutoloadIncluder', false) && !trait_exists('AutoloadIncluder', false)) {
spl_autoload_call('RectorPrefix20211023\AutoloadIncluder');
}
if (!class_exists('ComposerAutoloaderInite3debac64aaa6a8fa330817c6d733ea8', false) && !interface_exists('ComposerAutoloaderInite3debac64aaa6a8fa330817c6d733ea8', false) && !trait_exists('ComposerAutoloaderInite3debac64aaa6a8fa330817c6d733ea8', false)) {
spl_autoload_call('RectorPrefix20211023\ComposerAutoloaderInite3debac64aaa6a8fa330817c6d733ea8');
if (!class_exists('ComposerAutoloaderInit28ec809d5b0e2f07c00408e939bd1df2', false) && !interface_exists('ComposerAutoloaderInit28ec809d5b0e2f07c00408e939bd1df2', false) && !trait_exists('ComposerAutoloaderInit28ec809d5b0e2f07c00408e939bd1df2', false)) {
spl_autoload_call('RectorPrefix20211023\ComposerAutoloaderInit28ec809d5b0e2f07c00408e939bd1df2');
}
if (!class_exists('Helmich\TypoScriptParser\Parser\AST\Statement', false) && !interface_exists('Helmich\TypoScriptParser\Parser\AST\Statement', false) && !trait_exists('Helmich\TypoScriptParser\Parser\AST\Statement', false)) {
spl_autoload_call('RectorPrefix20211023\Helmich\TypoScriptParser\Parser\AST\Statement');
@ -3306,9 +3306,9 @@ if (!function_exists('print_node')) {
return \RectorPrefix20211023\print_node(...func_get_args());
}
}
if (!function_exists('composerRequiree3debac64aaa6a8fa330817c6d733ea8')) {
function composerRequiree3debac64aaa6a8fa330817c6d733ea8() {
return \RectorPrefix20211023\composerRequiree3debac64aaa6a8fa330817c6d733ea8(...func_get_args());
if (!function_exists('composerRequire28ec809d5b0e2f07c00408e939bd1df2')) {
function composerRequire28ec809d5b0e2f07c00408e939bd1df2() {
return \RectorPrefix20211023\composerRequire28ec809d5b0e2f07c00408e939bd1df2(...func_get_args());
}
}
if (!function_exists('parseArgs')) {