Phan: parse only directly required composer dependencies

Indirect dependencies are typically needed only by the direct
dependencies, which are not analyzed.

Dev dependencies are needed to run Phan, but are not needed in the code
Phan is analyzing.

So it turns out to be fairly straightforward to eliminate unnecessary
dependencies from the Phan parse stage, reducing memory usage by about
40% and time usage by about 20%. This means I can run Phan on my laptop
without first closing PHPStorm, which is convenient.

As a matter of policy, you could argue that the list of allowed indirect
dependencies here should be explicitly declared by moving them to
composer.json.

Change-Id: I987c3b22bafd1b4332fdeaf40ec3e20d35a3d929
This commit is contained in:
Tim Starling 2022-11-09 16:32:23 +11:00
parent ebd13491b7
commit 3253cbf8d5

View file

@ -49,7 +49,12 @@ $cfg['exclude_file_list'] = array_merge(
// This file has invalid PHP syntax
'vendor/squizlabs/php_codesniffer/src/Standards/PSR2/Tests/Methods/MethodDeclarationUnitTest.inc',
// This file implements a polyfill for the JsonUnserializable class
'vendor/php-parallel-lint/php-parallel-lint/src/polyfill.php'
'vendor/php-parallel-lint/php-parallel-lint/src/polyfill.php',
// Avoid microsoft/tolerant-php-parser dependency
'maintenance/findDeprecated.php',
'maintenance/CodeCleanerGlobalsPass.php',
// Avoid nikic/php-parser dependency
'maintenance/shell.php',
]
);
@ -93,13 +98,48 @@ $cfg['directory_list'] = [
'maintenance/',
'mw-config/',
'resources/',
'vendor/',
'tests/common/',
'tests/parser/',
'tests/phpunit/mocks/',
// Do NOT add .phan/stubs/ here: stubs are conditionally loaded in file_list
];
// Include only direct production dependencies in vendor/
// Omit dev dependencies and most indirect dependencies
$composerJson = json_decode(
file_get_contents( __DIR__ . '/../composer.json' ),
true
);
$directDeps = [];
foreach ( $composerJson['require'] as $dep => $version ) {
$parts = explode( '/', $dep );
if ( count( $parts ) === 2 ) {
$directDeps[] = $dep;
}
}
// This is a list of all composer packages that are referenced by core but
// are not listed as requirements in composer.json.
$indirectDeps = [
'composer/spdx-licenses',
'doctrine/dbal',
'doctrine/sql-formatter',
'guzzlehttp/psr7',
'pear/net_url2',
'pear/pear-core-minimal',
'phpunit/phpunit',
'psr/http-message',
'seld/jsonlint',
'wikimedia/testing-access-wrapper',
'wikimedia/zest-css',
];
foreach ( [ ...$directDeps, ...$indirectDeps ] as $dep ) {
$cfg['directory_list'][] = "vendor/$dep";
}
$cfg['exclude_analysis_directory_list'] = [
'vendor/',
'.phan/',