Skip to content

Commit 3bb03c6

Browse files
committed
Fix parsing php 7
1 parent 352dbf1 commit 3bb03c6

File tree

5 files changed

+39
-9
lines changed

5 files changed

+39
-9
lines changed

rules/Php74/Rector/ArrayDimFetch/CurlyToSquareBracketArrayStringRector.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,9 @@ private function isFollowedByCurlyBracket(File $file, ArrayDimFetch $arrayDimFet
7777
$oldTokens = $file->getOldTokens();
7878
$endTokenPost = $arrayDimFetch->getEndTokenPos();
7979

80-
if (isset($oldTokens[$endTokenPost]) && $oldTokens[$endTokenPost] === '}') {
81-
$startTokenPost = $arrayDimFetch->getStartTokenPos();
82-
return ! (isset($oldTokens[$startTokenPost][1]) && $oldTokens[$startTokenPost][1] === '${');
80+
if (isset($oldTokens[$endTokenPost]) && (string) $oldTokens[$endTokenPost] === '}') {
81+
$startTokenPos = $arrayDimFetch->getStartTokenPos();
82+
return ! (isset($oldTokens[$startTokenPos]) && (string) $oldTokens[$startTokenPos] === '${');
8383
}
8484

8585
return false;

src/Application/FileProcessor.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ private function parseFileAndDecorateNodes(File $file): ?SystemError
112112
{
113113
try {
114114
$this->parseFileNodes($file);
115+
} catch (ParserErrorsException) {
116+
$this->parseFileNodes($file, false);
115117
} catch (ShouldNotHappenException $shouldNotHappenException) {
116118
throw $shouldNotHappenException;
117119
} catch (AnalysedCodeException $analysedCodeException) {
@@ -187,10 +189,13 @@ private function printFile(File $file, Configuration $configuration, string $fil
187189
FileSystem::write($filePath, $newContent, null);
188190
}
189191

190-
private function parseFileNodes(File $file): void
192+
private function parseFileNodes(File $file, bool $forNewestSupportedVersion = true): void
191193
{
192194
// store tokens by original file content, so we don't have to print them right now
193-
$stmtsAndTokens = $this->rectorParser->parseFileContentToStmtsAndTokens($file->getOriginalFileContent());
195+
$stmtsAndTokens = $this->rectorParser->parseFileContentToStmtsAndTokens(
196+
$file->getOriginalFileContent(),
197+
$forNewestSupportedVersion
198+
);
194199

195200
$oldStmts = $stmtsAndTokens->getStmts();
196201
$oldTokens = $stmtsAndTokens->getTokens();

src/NodeAnalyzer/ScopeAnalyzer.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use PhpParser\Node;
88
use PhpParser\Node\Arg;
9+
use PhpParser\Node\Expr\ArrayDimFetch;
910
use PhpParser\Node\Expr\Variable;
1011
use PhpParser\Node\Identifier;
1112
use PhpParser\Node\Name;
@@ -16,7 +17,7 @@ final class ScopeAnalyzer
1617
/**
1718
* @var array<class-string<Node>>
1819
*/
19-
private const NON_REFRESHABLE_NODES = [Name::class, Identifier::class, Param::class, Arg::class, Variable::class];
20+
private const NON_REFRESHABLE_NODES = [Name::class, Identifier::class, Param::class, Arg::class, Variable::class, ArrayDimFetch::class];
2021

2122
public function isRefreshable(Node $node): bool
2223
{

src/NodeTypeResolver/PHPStan/Scope/PHPStanNodeScopeResolver.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Rector\NodeTypeResolver\PHPStan\Scope;
66

7+
use PHPStan\Parser\ParserErrorsException;
78
use PhpParser\Node;
89
use PhpParser\Node\Arg;
910
use PhpParser\Node\Expr;
@@ -329,7 +330,11 @@ private function nodeScopeResolverProcessNodes(
329330
): void {
330331
try {
331332
$this->nodeScopeResolver->processNodes($stmts, $mutatingScope, $nodeCallback);
333+
} catch (ParserErrorsException) {
334+
// nothing we can do as error parsing from deep internal PHPStan service with service injection we cannot reset
335+
// in the middle of process
332336
} catch (ShouldNotHappenException) {
337+
// internal PHPStan error
333338
}
334339
}
335340

src/PhpParser/Parser/RectorParser.php

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
namespace Rector\PhpParser\Parser;
66

77
use PhpParser\Node\Stmt;
8+
use PhpParser\ParserFactory;
9+
use PhpParser\PhpVersion;
810
use PHPStan\Parser\Parser;
911
use Rector\PhpParser\ValueObject\StmtsAndTokens;
1012
use Rector\Util\Reflection\PrivatesAccessor;
@@ -35,11 +37,28 @@ public function parseString(string $fileContent): array
3537
return $this->parser->parseString($fileContent);
3638
}
3739

38-
public function parseFileContentToStmtsAndTokens(string $fileContent): StmtsAndTokens
40+
public function parseFileContentToStmtsAndTokens(string $fileContent, bool $forNewestSupportedVersion = true): StmtsAndTokens
3941
{
40-
$stmts = $this->parser->parseString($fileContent);
42+
if (! $forNewestSupportedVersion) {
43+
// don't directly change PHPStan Parser service
44+
// to avoid reuse on next file
45+
$phpstanParser = clone $this->parser;
4146

42-
$innerParser = $this->privatesAccessor->getPrivateProperty($this->parser, 'parser');
47+
$parserFactory = new ParserFactory();
48+
$parser = $parserFactory->createForVersion(PhpVersion::fromString('7.0'));
49+
$this->privatesAccessor->setPrivateProperty($phpstanParser, 'parser', $parser);
50+
51+
return $this->resolveStmtsAndTokens($phpstanParser, $fileContent);
52+
}
53+
54+
return $this->resolveStmtsAndTokens($this->parser, $fileContent);
55+
}
56+
57+
private function resolveStmtsAndTokens(Parser $parser, string $fileContent): StmtsAndTokens
58+
{
59+
$stmts = $parser->parseString($fileContent);
60+
61+
$innerParser = $this->privatesAccessor->getPrivateProperty($parser, 'parser');
4362
$tokens = $innerParser->getTokens();
4463

4564
return new StmtsAndTokens($stmts, $tokens);

0 commit comments

Comments
 (0)