Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/Internal/ComposerHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ final class ComposerHelper

private static ?string $betterReflectionVersion = null;

private static ?string $phpstomStubsVersion = null;

private static ?string $phpDocParserVersion = null;

/** @var array<string, mixed[]> */
Expand Down Expand Up @@ -124,6 +126,21 @@ public static function getBetterReflectionVersion(): string
return self::$betterReflectionVersion = self::processPackageVersion($rootPackage);
}

public static function getPhpStormStubsVersion(): string
{
if (self::$phpstomStubsVersion !== null) {
return self::$phpstomStubsVersion;
}

$installed = self::getInstalled();
$rootPackage = $installed['versions']['jetbrains/phpstorm-stubs'] ?? null;
if ($rootPackage === null) {
return self::$phpstomStubsVersion = self::UNKNOWN_VERSION;
}

return self::$phpstomStubsVersion = self::processPackageVersion($rootPackage);
}

public static function getPhpDocParserVersion(): string
{
if (self::$phpDocParserVersion !== null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use PHPStan\BetterReflection\SourceLocator\Type\MemoizingSourceLocator;
use PHPStan\BetterReflection\SourceLocator\Type\PhpInternalSourceLocator;
use PHPStan\BetterReflection\SourceLocator\Type\SourceLocator;
use PHPStan\Cache\Cache;
use PHPStan\DependencyInjection\AutowiredParameter;
use PHPStan\DependencyInjection\AutowiredService;
use PHPStan\Php\PhpVersion;
Expand All @@ -28,6 +29,7 @@
use PHPStan\Reflection\BetterReflection\SourceLocator\RewriteClassAliasSourceLocator;
use PHPStan\Reflection\BetterReflection\SourceLocator\SkipClassAliasSourceLocator;
use PHPStan\Reflection\BetterReflection\SourceLocator\SkipPolyfillSourceLocator;
use PHPStan\Reflection\BetterReflection\SourceStubber\CachedPhpStormStubsSourceStubber;
use function array_merge;
use function array_unique;
use function count;
Expand Down Expand Up @@ -74,6 +76,7 @@ public function __construct(
private bool $playgroundMode, // makes all PHPStan classes in the PHAR discoverable with PSR-4
#[AutowiredParameter]
private ?string $singleReflectionFile,
private Cache $cache,
)
{
}
Expand Down Expand Up @@ -160,13 +163,18 @@ public function create(): SourceLocator
);
}
}
$cachedPhpstormSourceStubber = new CachedPhpStormStubsSourceStubber(
$this->phpstormStubsSourceStubber,
$this->cache,
$this->phpVersion,
);

$locators[] = new RewriteClassAliasSourceLocator(new AggregateSourceLocator($fileLocators));
$locators[] = new SkipClassAliasSourceLocator(new PhpInternalSourceLocator($astPhp8Locator, $this->phpstormStubsSourceStubber));
$locators[] = new SkipClassAliasSourceLocator(new PhpInternalSourceLocator($astPhp8Locator, $cachedPhpstormSourceStubber));

$locators[] = new AutoloadSourceLocator($this->fileNodesFetcher, true);
$locators[] = new PhpVersionBlacklistSourceLocator(new PhpInternalSourceLocator($astLocator, $this->reflectionSourceStubber), $this->phpstormStubsSourceStubber);
$locators[] = new PhpVersionBlacklistSourceLocator(new EvaledCodeSourceLocator($astLocator, $this->reflectionSourceStubber), $this->phpstormStubsSourceStubber);
$locators[] = new PhpVersionBlacklistSourceLocator(new PhpInternalSourceLocator($astLocator, $this->reflectionSourceStubber), $cachedPhpstormSourceStubber);
$locators[] = new PhpVersionBlacklistSourceLocator(new EvaledCodeSourceLocator($astLocator, $this->reflectionSourceStubber), $cachedPhpstormSourceStubber);

return new MemoizingSourceLocator(new AggregateSourceLocator($locators));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@
use PHPStan\BetterReflection\Reflector\Reflector;
use PHPStan\BetterReflection\SourceLocator\SourceStubber\PhpStormStubsSourceStubber;
use PHPStan\BetterReflection\SourceLocator\Type\SourceLocator;
use PHPStan\Reflection\BetterReflection\SourceStubber\CachedPhpStormStubsSourceStubber;

final class PhpVersionBlacklistSourceLocator implements SourceLocator
{

public function __construct(
private SourceLocator $sourceLocator,
private PhpStormStubsSourceStubber $phpStormStubsSourceStubber,
private PhpStormStubsSourceStubber|CachedPhpStormStubsSourceStubber $phpStormStubsSourceStubber,
)
{
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?php declare(strict_types = 1);

namespace PHPStan\Reflection\BetterReflection\SourceStubber;

use PHPStan\BetterReflection\SourceLocator\SourceStubber\PhpStormStubsSourceStubber;
use PHPStan\BetterReflection\SourceLocator\SourceStubber\SourceStubber;
use PHPStan\BetterReflection\SourceLocator\SourceStubber\StubData;
use PHPStan\Cache\Cache;
use PHPStan\Internal\ComposerHelper;
use PHPStan\Php\PhpVersion;
use function array_key_exists;
use function sprintf;

final class CachedPhpStormStubsSourceStubber implements SourceStubber
{

/** @var array<string, mixed> */
private array $cached;

public function __construct(
private PhpStormStubsSourceStubber $sourceStubber,
private Cache $cache,
private PhpVersion $phpVersion,
)
{
[$cacheKey, $variableCacheKey] = $this->getCacheKeys();
$this->cached = $this->cache->load($cacheKey, $variableCacheKey) ?? [];
}

/**
* @return array{non-empty-string, string}
*/
private function getCacheKeys(): array
{
$stubsVersion = ComposerHelper::getPhpStormStubsVersion();
$cacheKey = sprintf('phpstorm-stubs-%s', $stubsVersion);
$variableCacheKey = sprintf('v1-%s-%s', ComposerHelper::getBetterReflectionVersion(), $this->phpVersion->getVersionString());
Comment on lines +35 to +37
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure whether this keys are correct this way.
whats the difference between $cacheKey and $variableCacheKey?


return [$cacheKey, $variableCacheKey];
}

#[\Override]
public function generateClassStub(string $className): ?StubData
{
$this->cached['classes'] ??= [];
if (!array_key_exists($className, $this->cached['classes'])) {
$this->cached['classes'][$className] = $this->sourceStubber->generateClassStub($className);
$this->storeCache();
}
return $this->cached['classes'][$className];
}

#[\Override]
public function generateFunctionStub(string $functionName): ?StubData
{
$this->cached['functions'] ??= [];
if (!array_key_exists($functionName, $this->cached['functions'])) {
$this->cached['functions'][$functionName] = $this->sourceStubber->generateFunctionStub($functionName);
$this->storeCache();
}
return $this->cached['functions'][$functionName];
}

#[\Override]
public function generateConstantStub(string $constantName): ?StubData
{
$this->cached['constants'] ??= [];
if (!array_key_exists($constantName, $this->cached['constants'])) {
$this->cached['constants'][$constantName] = $this->sourceStubber->generateConstantStub($constantName);
$this->storeCache();
}
return $this->cached['constants'][$constantName];
}

public function isPresentClass(string $className): ?bool
{
$this->cached['isPresentClass'] ??= [];
if (!array_key_exists($className, $this->cached['isPresentClass'])) {
$this->cached['isPresentClass'][$className] = $this->sourceStubber->isPresentClass($className);
$this->storeCache();
}
return $this->cached['isPresentClass'][$className];
}

public function isPresentFunction(string $functionName): ?bool
{
$this->cached['isPresentFunction'] ??= [];
if (!array_key_exists($functionName, $this->cached['isPresentFunction'])) {
$this->cached['isPresentFunction'][$functionName] = $this->sourceStubber->isPresentFunction($functionName);
$this->storeCache();
}
return $this->cached['isPresentFunction'][$functionName];
}

private function storeCache(): void
{
[$cacheKey, $variableCacheKey] = $this->getCacheKeys();
$this->cache->save($cacheKey, $variableCacheKey, $this->cached);
}

}
Loading