Skip to content

Commit 1741462

Browse files
committed
Fix deprecated string interpolation syntax
1 parent 8337a4f commit 1741462

17 files changed

+294
-6
lines changed

UPGRADING.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,3 +336,5 @@ Remove `Type::isSuperTypeOfWithReason()`, `Type:isSuperTypeOf()` return type cha
336336
* `ClassPropertyNode::getNativeType()` return type changed from AST node to `Type|null`
337337
* Class `PHPStan\Node\ClassMethod` (accessible from `ClassMethodsNode`) is no longer an AST node
338338
* Call `PHPStan\Node\ClassMethod::getNode()` to access the original AST node
339+
* Interface `PHPStan\Analyser\Scope` introduces a new `getTokens()` method which returns the tokens for the current file.
340+
* Interface `PHPStan\Parser\Parser` introduces a new `getTokens()` method which returns the tokens for the parsed file.

src/Analyser/FileAnalyser.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ public function analyseFile(
9999
try {
100100
$this->collectErrors($analysedFiles);
101101
$parserNodes = $this->parser->parseFile($file);
102+
$parserTokens = $this->parser->getTokens();
102103
$processedFiles[] = $file;
103104

104105
$nodeCallback = new FileAnalyserCallback(
@@ -114,7 +115,7 @@ public function analyseFile(
114115
$this->ruleErrorTransformer,
115116
$processedFiles,
116117
);
117-
$scope = $this->scopeFactory->create(ScopeContext::create($file), $nodeCallback);
118+
$scope = $this->scopeFactory->create(ScopeContext::create($file, $parserTokens), $nodeCallback);
118119
$nodeCallback(new FileNode($parserNodes), $scope);
119120
$this->nodeScopeResolver->processNodes(
120121
$parserNodes,

src/Analyser/MutatingScope.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,12 @@ public function getFile(): string
300300
return $this->context->getFile();
301301
}
302302

303+
/** @api */
304+
public function getTokens(): array
305+
{
306+
return $this->context->getTokens();
307+
}
308+
303309
/** @api */
304310
public function getFileDescription(): string
305311
{

src/Analyser/Scope.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use PhpParser\Node\Expr;
77
use PhpParser\Node\Name;
88
use PhpParser\Node\Param;
9+
use PhpParser\Token;
910
use PHPStan\Php\PhpVersions;
1011
use PHPStan\Reflection\ClassConstantReflection;
1112
use PHPStan\Reflection\ClassMemberAccessAnswerer;
@@ -65,6 +66,11 @@ interface Scope extends ClassMemberAccessAnswerer, NamespaceAnswerer
6566
*/
6667
public function getFile(): string;
6768

69+
/**
70+
* @return Token[]
71+
*/
72+
public function getTokens(): array;
73+
6874
/**
6975
* For traits, returns the trait file path with the using class context,
7076
* e.g. "TraitFile.php (in context of class MyClass)".

src/Analyser/ScopeContext.php

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace PHPStan\Analyser;
44

5+
use PhpParser\Token;
56
use PHPStan\Reflection\ClassReflection;
67
use PHPStan\ShouldNotHappenException;
78

@@ -12,19 +13,20 @@ private function __construct(
1213
private string $file,
1314
private ?ClassReflection $classReflection,
1415
private ?ClassReflection $traitReflection,
16+
private array $tokens,
1517
)
1618
{
1719
}
1820

1921
/** @api */
20-
public static function create(string $file): self
22+
public static function create(string $file, array $tokens = []): self
2123
{
22-
return new self($file, classReflection: null, traitReflection: null);
24+
return new self($file, classReflection: null, traitReflection: null, tokens: $tokens);
2325
}
2426

2527
public function beginFile(): self
2628
{
27-
return new self($this->file, classReflection: null, traitReflection: null);
29+
return new self($this->file, classReflection: null, traitReflection: null, tokens: $this->tokens);
2830
}
2931

3032
public function enterClass(ClassReflection $classReflection): self
@@ -35,7 +37,7 @@ public function enterClass(ClassReflection $classReflection): self
3537
if ($classReflection->isTrait()) {
3638
throw new ShouldNotHappenException();
3739
}
38-
return new self($this->file, $classReflection, traitReflection: null);
40+
return new self($this->file, $classReflection, traitReflection: null, tokens: $this->tokens);
3941
}
4042

4143
public function enterTrait(ClassReflection $traitReflection): self
@@ -47,7 +49,7 @@ public function enterTrait(ClassReflection $traitReflection): self
4749
throw new ShouldNotHappenException();
4850
}
4951

50-
return new self($this->file, $this->classReflection, $traitReflection);
52+
return new self($this->file, $this->classReflection, $traitReflection, $this->tokens);
5153
}
5254

5355
public function equals(self $otherContext): bool
@@ -90,4 +92,12 @@ public function getTraitReflection(): ?ClassReflection
9092
return $this->traitReflection;
9193
}
9294

95+
/**
96+
* @return Token[]
97+
*/
98+
public function getTokens(): array
99+
{
100+
return $this->tokens;
101+
}
102+
93103
}

src/Parser/CachedParser.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace PHPStan\Parser;
44

55
use PhpParser\Node;
6+
use PhpParser\Token;
67
use PHPStan\File\FileReader;
78
use function array_slice;
89

@@ -12,6 +13,11 @@ final class CachedParser implements Parser
1213
/** @var array<string, Node\Stmt[]>*/
1314
private array $cachedNodesByString = [];
1415

16+
/** @var array<string, Token[]>*/
17+
private array $cachedTokensByString = [];
18+
19+
private ?string $lastParsedSourceCode;
20+
1521
private int $cachedNodesByStringCount = 0;
1622

1723
/** @var array<string, true> */
@@ -36,17 +42,24 @@ public function parseFile(string $file): array
3642
1,
3743
preserve_keys: true,
3844
);
45+
$this->cachedTokensByString = array_slice(
46+
$this->cachedTokensByString,
47+
1,
48+
preserve_keys: true,
49+
);
3950

4051
--$this->cachedNodesByStringCount;
4152
}
4253

4354
$sourceCode = FileReader::read($file);
4455
if (!isset($this->cachedNodesByString[$sourceCode]) || isset($this->parsedByString[$sourceCode])) {
4556
$this->cachedNodesByString[$sourceCode] = $this->originalParser->parseFile($file);
57+
$this->cachedTokensByString[$sourceCode] = $this->originalParser->getTokens();
4658
$this->cachedNodesByStringCount++;
4759
unset($this->parsedByString[$sourceCode]);
4860
}
4961

62+
$this->lastParsedSourceCode = $sourceCode;
5063
return $this->cachedNodesByString[$sourceCode];
5164
}
5265

@@ -61,19 +74,34 @@ public function parseString(string $sourceCode): array
6174
1,
6275
preserve_keys: true,
6376
);
77+
$this->cachedTokensByString = array_slice(
78+
$this->cachedTokensByString,
79+
1,
80+
preserve_keys: true,
81+
);
6482

6583
--$this->cachedNodesByStringCount;
6684
}
6785

6886
if (!isset($this->cachedNodesByString[$sourceCode])) {
6987
$this->cachedNodesByString[$sourceCode] = $this->originalParser->parseString($sourceCode);
88+
$this->cachedTokensByString[$sourceCode] = $this->originalParser->getTokens();
7089
$this->cachedNodesByStringCount++;
7190
$this->parsedByString[$sourceCode] = true;
7291
}
7392

93+
$this->lastParsedSourceCode = $sourceCode;
7494
return $this->cachedNodesByString[$sourceCode];
7595
}
7696

97+
public function getTokens(): array
98+
{
99+
if (isset($this->cachedTokensByString[$this->lastParsedSourceCode])) {
100+
return $this->cachedTokensByString[$this->lastParsedSourceCode];
101+
}
102+
return [];
103+
}
104+
77105
public function getCachedNodesByStringCount(): int
78106
{
79107
return $this->cachedNodesByStringCount;

src/Parser/CleaningParser.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ public function parseString(string $sourceCode): array
2828
return $this->clean($this->wrappedParser->parseString($sourceCode));
2929
}
3030

31+
public function getTokens(): array
32+
{
33+
return $this->wrappedParser->getTokens();
34+
}
35+
3136
/**
3237
* @param Stmt[] $ast
3338
* @return Stmt[]

src/Parser/Parser.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace PHPStan\Parser;
44

55
use PhpParser\Node;
6+
use PhpParser\Token;
67

78
/** @api */
89
interface Parser
@@ -21,4 +22,11 @@ public function parseFile(string $file): array;
2122
*/
2223
public function parseString(string $sourceCode): array;
2324

25+
/**
26+
* Return tokens for the last parse.
27+
*
28+
* @return Token[]
29+
*/
30+
public function getTokens(): array;
31+
2432
}

src/Parser/PathRoutingParser.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ final class PathRoutingParser implements Parser
1818

1919
private ?string $singleReflectionFile;
2020

21+
private ?Parser $usedParser;
22+
2123
/** @var array<string, true> filePath(string) => bool(true) */
2224
private array $analysedFiles = [];
2325

@@ -44,9 +46,11 @@ public function parseFile(string $file): array
4446
{
4547
$normalizedPath = $this->fileHelper->normalizePath($file, '/');
4648
if (str_contains($normalizedPath, 'vendor/jetbrains/phpstorm-stubs')) {
49+
$this->usedParser = $this->php8Parser;
4750
return $this->php8Parser->parseFile($file);
4851
}
4952
if (str_contains($normalizedPath, 'vendor/phpstan/php-8-stubs/stubs')) {
53+
$this->usedParser = $this->php8Parser;
5054
return $this->php8Parser->parseFile($file);
5155
}
5256

@@ -64,21 +68,36 @@ public function parseFile(string $file): array
6468
if ($realFilePath !== false) {
6569
$normalizedRealFilePath = $this->fileHelper->normalizePath($realFilePath);
6670
if (isset($this->analysedFiles[$normalizedRealFilePath])) {
71+
$this->usedParser = $this->currentPhpVersionRichParser;
6772
return $this->currentPhpVersionRichParser->parseFile($file);
6873
}
6974
}
7075
break;
7176
}
7277

78+
$this->usedParser = $this->currentPhpVersionSimpleParser;
7379
return $this->currentPhpVersionSimpleParser->parseFile($file);
7480
}
7581

82+
$this->usedParser = $this->currentPhpVersionRichParser;
7683
return $this->currentPhpVersionRichParser->parseFile($file);
7784
}
7885

7986
public function parseString(string $sourceCode): array
8087
{
88+
$this->usedParser = $this->currentPhpVersionSimpleParser;
8189
return $this->currentPhpVersionSimpleParser->parseString($sourceCode);
8290
}
8391

92+
/**
93+
* {@inheritdoc}
94+
*/
95+
public function getTokens(): array
96+
{
97+
if ($this->usedParser) {
98+
return $this->usedParser->getTokens();
99+
}
100+
return [];
101+
}
102+
84103
}

src/Parser/RichParser.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,14 @@ public function parseString(string $sourceCode): array
123123
return $nodes;
124124
}
125125

126+
/**
127+
* {@inheritdoc}
128+
*/
129+
public function getTokens(): array
130+
{
131+
return $this->parser->getTokens();
132+
}
133+
126134
/**
127135
* @param Token[] $tokens
128136
* @return array{lines: array<int, non-empty-list<Identifier>|null>, errors: array<int, non-empty-list<string>>}

0 commit comments

Comments
 (0)