Skip to content
Merged
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
397 changes: 392 additions & 5 deletions .github/workflows/phar.yml

Large diffs are not rendered by default.

235 changes: 0 additions & 235 deletions .github/workflows/turbo-ext.yml

This file was deleted.

6 changes: 4 additions & 2 deletions compiler/build/box.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@
"files": [
"preload.php",
"vendor/composer/installed.php",
"vendor/attributes.php"
"vendor/attributes.php",
"turbo-ext/shadowed-classes.json"
],
"directories": [
"conf",
"src",
"resources",
"stubs"
"stubs",
"turbo-ext/stubs"
],
"force-autodiscovery": true,
"output": "tmp/phpstan.phar",
Expand Down
4 changes: 4 additions & 0 deletions compiler/build/scoper.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,10 @@ function (string $filePath, string $prefix, string $content): string {
],
'exclude-namespaces' => [
'PHPStan',
// the native turbo extension's classes — must match the loaded
// extension exactly, never prefixed (segment-aware matching means the
// PHPStan entry above does not cover this name)
'PHPStanTurbo',
'PHPUnit',
'PhpParser',
'Hoa',
Expand Down
25 changes: 25 additions & 0 deletions compiler/src/Console/PrepareCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,28 @@ private function buildPreloadScript(): void
if ($root === false) {
return;
}

// The turbo extension shadows these classes with stubs that
// TurboExtensionEnabler declares before the Composer autoloader
// registers; preloading the PHP twins by path would then fatal with a
// class redeclaration. Without the extension they load lazily through
// the autoloader.
$manifestContents = file_get_contents($root . '/turbo-ext/shadowed-classes.json');
if ($manifestContents === false) {
throw new ShouldNotHappenException('Could not read turbo-ext/shadowed-classes.json');
}

/** @var array<string, array{php: string, cpp: string, vendored?: bool}> $manifest */
$manifest = json_decode($manifestContents, true);
$shadowedFiles = [];
foreach ($manifest as $entry) {
$shadowedFile = realpath($root . '/' . $entry['php']);
if ($shadowedFile === false) {
throw new ShouldNotHappenException(sprintf('Shadowed file %s does not exist', $entry['php']));
}
$shadowedFiles[] = $shadowedFile;
}

$output = '';
foreach ($finder->files()->name('*.php')->in([
$this->buildDir . '/src',
Expand All @@ -185,6 +207,9 @@ private function buildPreloadScript(): void
if ($realPath === false) {
return;
}
if (in_array($realPath, $shadowedFiles, true)) {
continue;
}
if (in_array($realPath, [
$vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayItem.php',
$vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/ClosureUse.php',
Expand Down
8 changes: 8 additions & 0 deletions src/Process/ProcessHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace PHPStan\Process;

use PHPStan\Command\AnalyseCommand;
use PHPStan\Turbo\TurboExtensionSelector;
use Symfony\Component\Console\Input\InputInterface;
use function array_merge;
use function escapeshellarg;
Expand Down Expand Up @@ -43,6 +44,13 @@ public static function getWorkerCommand(
$processCommandArray[] = 'memory_limit=' . ini_get('memory_limit');
}

$turboExtension = TurboExtensionSelector::findExtensionForWorkers();
if ($turboExtension !== null) {
$processCommandArray[] = '-d';
// quote value so PHP will parse it as a string when the path contains a bitwise operator like ~
$processCommandArray[] = 'extension=' . escapeshellarg("'" . $turboExtension . "'");
}

foreach ([$mainScript, $commandName] as $arg) {
$processCommandArray[] = escapeshellarg($arg);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
use PHPStan\Reflection\BetterReflection\SourceLocator\RewriteClassAliasSourceLocator;
use PHPStan\Reflection\BetterReflection\SourceLocator\SkipClassAliasSourceLocator;
use PHPStan\Reflection\BetterReflection\SourceLocator\SkipPolyfillSourceLocator;
use PHPStan\Turbo\TurboExtensionEnabler;
use function array_merge;
use function array_unique;
use function count;
Expand Down Expand Up @@ -124,6 +125,17 @@ public function create(): SourceLocator
$fileLocators[] = $this->optimizedSingleFileSourceLocatorRepository->getOrCreate($analysedFile);
}

if (TurboExtensionEnabler::isActive()) {
// With the turbo extension active, the shadowed class names are
// declared by the stub shells extending the native classes;
// reflection has to keep seeing the real implementations, which
// the AutoloadSourceLocator below can no longer provide (it
// would resolve the class names to the stub files).
foreach (TurboExtensionEnabler::getShadowedClassSourceFiles() as $shadowedClassSourceFile) {
$fileLocators[] = $this->optimizedSingleFileSourceLocatorRepository->getOrCreate($shadowedClassSourceFile);
}
}

$directories = array_unique(array_merge($analysedDirectories, $this->scanDirectories));
foreach ($directories as $directory) {
$fileLocators[] = $this->optimizedDirectorySourceLocatorRepository->getOrCreate($directory);
Expand Down
Loading
Loading