mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-01 17:00:51 +00:00
[Core] Avoid hang on file has template-extends (#1034)
* [Core] Avoid hang on file has template-extends * check with regex * phpstan * [ci-review] Rector Rectify * add comment to PHPStan issue * add comment for why oldTokens only that filled when newStmts equal to oldStmts * add comment for why oldTokens only that filled when newStmts equal to oldStmts * final touch: linking issue * final touch: typo fix * [ci-review] Rector Rectify Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
parent
c5426f60d6
commit
06994b8ff3
|
@ -27,6 +27,7 @@ use PhpParser\Node\Scalar\LNumber;
|
|||
use PhpParser\Node\Scalar\String_;
|
||||
use PhpParser\Node\Stmt;
|
||||
use PhpParser\Node\Stmt\Expression;
|
||||
use PhpParser\Node\Stmt\Foreach_;
|
||||
use PhpParser\Node\Stmt\Return_;
|
||||
use PhpParser\Node\UnionType;
|
||||
use PhpParser\Parser;
|
||||
|
@ -206,7 +207,7 @@ final class AnonymousFunctionFactory
|
|||
$parentNode = $variableNode->getAttribute(AttributeKey::PARENT_NODE);
|
||||
if (
|
||||
$parentNode instanceof Assign
|
||||
|| $parentNode instanceof Stmt\Foreach_
|
||||
|| $parentNode instanceof Foreach_
|
||||
|| $parentNode instanceof Param
|
||||
) {
|
||||
$alreadyAssignedVariables[] = $variableName;
|
||||
|
|
|
@ -4,21 +4,31 @@ declare(strict_types=1);
|
|||
|
||||
namespace Rector\Core\Application;
|
||||
|
||||
use Nette\Utils\Strings;
|
||||
use PhpParser\Lexer;
|
||||
use PhpParser\Node;
|
||||
use Rector\ChangesReporting\Collector\AffectedFilesCollector;
|
||||
use Rector\Core\PhpParser\NodeTraverser\RectorNodeTraverser;
|
||||
use Rector\Core\PhpParser\Parser\Parser;
|
||||
use Rector\Core\PhpParser\Printer\BetterStandardPrinter;
|
||||
use Rector\Core\ValueObject\Application\File;
|
||||
use Rector\NodeTypeResolver\NodeScopeAndMetadataDecorator;
|
||||
|
||||
final class FileProcessor
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
* @see https://regex101.com/r/ozPuC9/1
|
||||
*/
|
||||
private const TEMPLATE_EXTENDS_REGEX = '#(\*|\/\/)\s+\@template-extends\s+\\\\?\w+#';
|
||||
|
||||
public function __construct(
|
||||
private AffectedFilesCollector $affectedFilesCollector,
|
||||
private Lexer $lexer,
|
||||
private NodeScopeAndMetadataDecorator $nodeScopeAndMetadataDecorator,
|
||||
private Parser $parser,
|
||||
private RectorNodeTraverser $rectorNodeTraverser
|
||||
private RectorNodeTraverser $rectorNodeTraverser,
|
||||
private BetterStandardPrinter $betterStandardPrinter
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -29,6 +39,17 @@ final class FileProcessor
|
|||
$oldStmts = $this->parser->parseFileInfo($smartFileInfo);
|
||||
$oldTokens = $this->lexer->getTokens();
|
||||
|
||||
/**
|
||||
* Tweak PHPStan internal issue for has @template-extends that cause endless loop in the process
|
||||
*
|
||||
* @see https://github.com/phpstan/phpstan/issues/3865
|
||||
* @see https://github.com/rectorphp/rector/issues/6758
|
||||
*/
|
||||
if ($this->isTemplateExtendsInSource($oldStmts)) {
|
||||
$file->hydrateStmtsAndTokens($oldStmts, $oldStmts, $oldTokens);
|
||||
return;
|
||||
}
|
||||
|
||||
// @todo may need tweak to refresh PHPStan types to avoid issue like in https://github.com/rectorphp/rector/issues/6561
|
||||
$newStmts = $this->nodeScopeAndMetadataDecorator->decorateNodesFromFile($file, $oldStmts);
|
||||
$file->hydrateStmtsAndTokens($newStmts, $oldStmts, $oldTokens);
|
||||
|
@ -44,4 +65,13 @@ final class FileProcessor
|
|||
$this->refactor($otherTouchedFile);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Node[] $nodes
|
||||
*/
|
||||
private function isTemplateExtendsInSource(array $nodes): bool
|
||||
{
|
||||
$print = $this->betterStandardPrinter->print($nodes);
|
||||
return (bool) Strings::match($print, self::TEMPLATE_EXTENDS_REGEX);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -114,6 +114,15 @@ final class File
|
|||
throw new ShouldNotHappenException('Double stmts override');
|
||||
}
|
||||
|
||||
/*
|
||||
* If newStmts is equal to $oldStmts,
|
||||
* it is necessary to fill oldTokens only to avoid content of the file removed or spacing changed
|
||||
*/
|
||||
if ($newStmts === $oldStmts) {
|
||||
$this->oldTokens = $oldTokens;
|
||||
return;
|
||||
}
|
||||
|
||||
$this->oldStmts = $oldStmts;
|
||||
$this->newStmts = $newStmts;
|
||||
$this->oldTokens = $oldTokens;
|
||||
|
|
Loading…
Reference in New Issue
Block a user