Skip to content

Commit 4ff0a4c

Browse files
committed
Further optimize FileTypeMapper
1 parent 869f0c7 commit 4ff0a4c

2 files changed

Lines changed: 60 additions & 15 deletions

File tree

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\PhpDoc;
4+
5+
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocNode;
6+
use PHPStan\ShouldNotHappenException;
7+
use function array_key_exists;
8+
9+
class FileTypeMapperPhpDocNodeMap
10+
{
11+
12+
/** @var array<string, PhpDocNode> */
13+
private array $resolved = [];
14+
15+
/**
16+
* @param array<string, callable(): PhpDocNode> $map
17+
*/
18+
public function __construct(private array $map)
19+
{
20+
}
21+
22+
/**
23+
* @return array<string, callable(): PhpDocNode>
24+
*/
25+
public function getMap(): array
26+
{
27+
return $this->map;
28+
}
29+
30+
public function has(string $nameScopeKey): bool
31+
{
32+
return array_key_exists($nameScopeKey, $this->map);
33+
}
34+
35+
public function get(string $nameScopeKey): PhpDocNode
36+
{
37+
if (array_key_exists($nameScopeKey, $this->resolved)) {
38+
return $this->resolved[$nameScopeKey];
39+
}
40+
if (!$this->has($nameScopeKey)) {
41+
throw new ShouldNotHappenException();
42+
}
43+
return $this->resolved[$nameScopeKey] = $this->map[$nameScopeKey]();
44+
}
45+
46+
}

src/Type/FileTypeMapper.php

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use PHPStan\Broker\AnonymousClassNameHelper;
1010
use PHPStan\File\FileHelper;
1111
use PHPStan\Parser\Parser;
12+
use PHPStan\PhpDoc\FileTypeMapperPhpDocNodeMap;
1213
use PHPStan\PhpDoc\PhpDocNodeResolver;
1314
use PHPStan\PhpDoc\PhpDocStringResolver;
1415
use PHPStan\PhpDoc\ResolvedPhpDocBlock;
@@ -214,11 +215,10 @@ private function createResolvedPhpDocMap(string $fileName): array
214215

215216
/**
216217
* @param array<string, string> $traitMethodAliases
217-
* @return array<string, PhpDocNode>
218218
*/
219-
private function createPhpDocNodeMap(string $fileName, ?string $lookForTrait, ?string $traitUseClass, array $traitMethodAliases, string $originalClassFileName): array
219+
private function createPhpDocNodeMap(string $fileName, ?string $lookForTrait, ?string $traitUseClass, array $traitMethodAliases, string $originalClassFileName): FileTypeMapperPhpDocNodeMap
220220
{
221-
/** @var array<string, PhpDocNode> $phpDocNodeMap */
221+
/** @var array<string, callable(): PhpDocNode> $phpDocNodeMap */
222222
$phpDocNodeMap = [];
223223

224224
/** @var string[] $classStack */
@@ -285,7 +285,7 @@ function (Node $node) use ($fileName, $lookForTrait, &$traitFound, $traitMethodA
285285
$docComment = GetLastDocComment::forNode($node);
286286
if ($docComment !== null) {
287287
$nameScopeKey = $this->getNameScopeKey($originalClassFileName, $className, $lookForTrait, $functionName);
288-
$phpDocNodeMap[$nameScopeKey] = $this->phpDocStringResolver->resolve($docComment);
288+
$phpDocNodeMap[$nameScopeKey] = fn (): PhpDocNode => $this->phpDocStringResolver->resolve($docComment);
289289
}
290290

291291
return null;
@@ -347,7 +347,7 @@ function (Node $node) use ($fileName, $lookForTrait, &$traitFound, $traitMethodA
347347
$className,
348348
$traitMethodAliases[$traitName] ?? [],
349349
$originalClassFileName,
350-
));
350+
)->getMap());
351351
}
352352
}
353353

@@ -377,12 +377,11 @@ static function (Node $node) use (&$namespace, &$functionStack, &$classStack): v
377377
},
378378
);
379379

380-
return $phpDocNodeMap;
380+
return new FileTypeMapperPhpDocNodeMap($phpDocNodeMap);
381381
}
382382

383383
/**
384384
* @param array<string, string> $traitMethodAliases
385-
* @param array<string, PhpDocNode> $phpDocNodeMap
386385
* @return (callable(): NameScope)[]
387386
*/
388387
private function createNameScopeMap(
@@ -391,7 +390,7 @@ private function createNameScopeMap(
391390
?string $traitUseClass,
392391
array $traitMethodAliases,
393392
string $originalClassFileName,
394-
array $phpDocNodeMap,
393+
FileTypeMapperPhpDocNodeMap $phpDocNodeMap,
395394
): array
396395
{
397396
/** @var (callable(): NameScope)[] $nameScopeMap */
@@ -435,8 +434,8 @@ function (Node $node) use ($fileName, $lookForTrait, $phpDocNodeMap, &$traitFoun
435434

436435
$traitFound = true;
437436
$traitNameScopeKey = $this->getNameScopeKey($originalClassFileName, $classStack[count($classStack) - 1] ?? null, $lookForTrait, null);
438-
if (array_key_exists($traitNameScopeKey, $phpDocNodeMap)) {
439-
$typeAliasStack[] = $this->getTypeAliasesMap($phpDocNodeMap[$traitNameScopeKey]);
437+
if ($phpDocNodeMap->has($traitNameScopeKey)) {
438+
$typeAliasStack[] = $this->getTypeAliasesMap($phpDocNodeMap->get($traitNameScopeKey));
440439
} else {
441440
$typeAliasStack[] = [];
442441
}
@@ -458,8 +457,8 @@ function (Node $node) use ($fileName, $lookForTrait, $phpDocNodeMap, &$traitFoun
458457
}
459458
$classStack[] = $className;
460459
$classNameScopeKey = $this->getNameScopeKey($originalClassFileName, $className, $lookForTrait, null);
461-
if (array_key_exists($classNameScopeKey, $phpDocNodeMap)) {
462-
$typeAliasStack[] = $this->getTypeAliasesMap($phpDocNodeMap[$classNameScopeKey]);
460+
if ($phpDocNodeMap->has($classNameScopeKey)) {
461+
$typeAliasStack[] = $this->getTypeAliasesMap($phpDocNodeMap->get($classNameScopeKey));
463462
} else {
464463
$typeAliasStack[] = [];
465464
}
@@ -480,8 +479,8 @@ function (Node $node) use ($fileName, $lookForTrait, $phpDocNodeMap, &$traitFoun
480479
$nameScopeKey = $this->getNameScopeKey($originalClassFileName, $className, $lookForTrait, $functionName);
481480

482481
if ($node instanceof Node\Stmt\ClassLike || $node instanceof Node\Stmt\ClassMethod || $node instanceof Node\Stmt\Function_) {
483-
if (array_key_exists($nameScopeKey, $phpDocNodeMap)) {
484-
$phpDocNode = $phpDocNodeMap[$nameScopeKey];
482+
if ($phpDocNodeMap->has($nameScopeKey)) {
483+
$phpDocNode = $phpDocNodeMap->get($nameScopeKey);
485484
$typeMapStack[] = function () use ($namespace, $uses, $className, $lookForTrait, $functionName, $phpDocNode, $typeMapStack, $typeAliasStack, $constUses): TemplateTypeMap {
486485
$typeMapCb = $typeMapStack[count($typeMapStack) - 1] ?? null;
487486
$currentTypeMap = $typeMapCb !== null ? $typeMapCb() : null;
@@ -536,7 +535,7 @@ function (Node $node) use ($fileName, $lookForTrait, $phpDocNodeMap, &$traitFoun
536535
}
537536

538537
if ($node instanceof Node\Stmt\ClassLike || $node instanceof Node\Stmt\ClassMethod || $node instanceof Node\Stmt\Function_) {
539-
if (array_key_exists($nameScopeKey, $phpDocNodeMap)) {
538+
if ($phpDocNodeMap->has($nameScopeKey)) {
540539
return self::POP_TYPE_MAP_STACK;
541540
}
542541

0 commit comments

Comments
 (0)