Skip to content

Commit 677df31

Browse files
simPodclaude
authored andcommitted
Select versioned extension stubs
Detect the major version of extensions with versioned PhpStorm stub maps (ext-ds 1 vs 2) from the project's composer.json platform config, its require constraint, or the loaded extension, and pass it to PhpStormStubsSourceStubber. The ext-ds 1 stub overlay is only loaded for ds 1, and the detected versions are part of the internal stubs cache key. In the result cache, files using built-in symbols of such an extension record a dependency on its platform package (ext-<name>) next to their Composer package dependencies. A different selected version then re-analyses only those files and the files with errors instead of the whole project. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 7546cd6 commit 677df31

34 files changed

Lines changed: 587 additions & 38 deletions

‎.github/workflows/e2e-tests.yml‎

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,6 +1030,32 @@ jobs:
10301030
echo "$OUTPUT"
10311031
../bashunit -a contains 'Composer packages changed (psr/log); re-analysing the files depending on them and the files with errors.' "$OUTPUT"
10321032
../bashunit -a not_contains 'has invalid type Psr\Log\PluginProvidedLogger' "$OUTPUT"
1033+
- script: |
1034+
cd e2e/ext-ds-version
1035+
cp composer-json/v1-platform.json composer.json
1036+
composer install --ignore-platform-reqs
1037+
OUTPUT=$(../bashunit -a exit_code "1" "../../bin/phpstan analyse -vv --error-format raw")
1038+
echo "$OUTPUT"
1039+
../bashunit -a contains 'Foo.php:12:Instantiated class Ds\Seq not found.' "$OUTPUT"
1040+
# Only composer.json changes - composer.lock and installed.php stay as they are - and it now
1041+
# selects the ext-ds 2 stubs. src/Bar.php has no error with ext-ds 1, so only its dependency on
1042+
# ext-ds re-analyses it; src/Baz.php does not use ext-ds and stays cached.
1043+
cp composer-json/v2-platform.json composer.json
1044+
OUTPUT=$(../bashunit -a exit_code "1" "../../bin/phpstan analyse -vv --error-format raw")
1045+
echo "$OUTPUT"
1046+
../bashunit -a contains 'PHP extension versions changed (ext-ds); re-analysing the files depending on them and the files with errors.' "$OUTPUT"
1047+
../bashunit -a contains 'Result cache restored. 2 files will be reanalysed.' "$OUTPUT"
1048+
../bashunit -a contains 'Foo.php:11:Instantiated class Ds\Vector not found.' "$OUTPUT"
1049+
../bashunit -a contains 'Bar.php:15:Call to an undefined method Ds\Pair<string, int>::copy().' "$OUTPUT"
1050+
../bashunit -a not_contains 'Ds\Seq' "$OUTPUT"
1051+
cp composer-json/v1-platform.json composer.json
1052+
OUTPUT=$(../bashunit -a exit_code "1" "../../bin/phpstan analyse -vv --error-format raw")
1053+
echo "$OUTPUT"
1054+
../bashunit -a contains 'PHP extension versions changed (ext-ds); re-analysing the files depending on them and the files with errors.' "$OUTPUT"
1055+
../bashunit -a contains 'Result cache restored. 2 files will be reanalysed.' "$OUTPUT"
1056+
../bashunit -a contains 'Foo.php:12:Instantiated class Ds\Seq not found.' "$OUTPUT"
1057+
../bashunit -a not_contains 'Ds\Vector' "$OUTPUT"
1058+
../bashunit -a not_contains 'Bar.php' "$OUTPUT"
10331059
- script: |
10341060
cd e2e/result-cache-extension-path-package
10351061
composer install
@@ -1522,6 +1548,56 @@ jobs:
15221548
OUTPUT=$(../bashunit -a exit_code "1" "../../bin/phpstan analyse --no-progress")
15231549
echo "$OUTPUT"
15241550
../bashunit -a contains 'killed by signal 9 (SIGKILL)' "$OUTPUT"
1551+
- script: |
1552+
# config.platform selects the ext-ds 1 stubs: Ds\Vector exists, Ds\Seq does not.
1553+
cd e2e/ext-ds-version
1554+
cp composer-json/v1-platform.json composer.json
1555+
composer install --ignore-platform-reqs
1556+
OUTPUT=$(../bashunit -a exit_code "1" "../../bin/phpstan analyse --no-progress --error-format raw")
1557+
echo "$OUTPUT"
1558+
../bashunit -a contains 'Foo.php:12:Instantiated class Ds\Seq not found.' "$OUTPUT"
1559+
../bashunit -a not_contains 'Ds\Vector' "$OUTPUT"
1560+
../bashunit -a not_contains 'Bar.php' "$OUTPUT"
1561+
- script: |
1562+
# config.platform selects the ext-ds 2 stubs: Ds\Seq exists, Ds\Vector and Ds\Pair::copy() do not.
1563+
cd e2e/ext-ds-version
1564+
cp composer-json/v2-platform.json composer.json
1565+
composer install --ignore-platform-reqs
1566+
OUTPUT=$(../bashunit -a exit_code "1" "../../bin/phpstan analyse --no-progress --error-format raw")
1567+
echo "$OUTPUT"
1568+
../bashunit -a contains 'Foo.php:11:Instantiated class Ds\Vector not found.' "$OUTPUT"
1569+
../bashunit -a contains 'Bar.php:15:Call to an undefined method Ds\Pair<string, int>::copy().' "$OUTPUT"
1570+
../bashunit -a not_contains 'Ds\Seq' "$OUTPUT"
1571+
- script: |
1572+
# Without a config.platform entry, the major version of the required ext-ds is selected.
1573+
cd e2e/ext-ds-version
1574+
cp composer-json/v2-require.json composer.json
1575+
composer install --ignore-platform-reqs
1576+
OUTPUT=$(../bashunit -a exit_code "1" "../../bin/phpstan analyse --no-progress --error-format raw")
1577+
echo "$OUTPUT"
1578+
../bashunit -a contains 'Foo.php:11:Instantiated class Ds\Vector not found.' "$OUTPUT"
1579+
../bashunit -a contains 'Bar.php:15:Call to an undefined method Ds\Pair<string, int>::copy().' "$OUTPUT"
1580+
../bashunit -a not_contains 'Ds\Seq' "$OUTPUT"
1581+
- script: |
1582+
# A constraint whose alternatives all stay within one major version (^2.0 || ^2.1) selects that version.
1583+
cd e2e/ext-ds-version
1584+
cp composer-json/v2-same-major-or-require.json composer.json
1585+
composer install --ignore-platform-reqs
1586+
OUTPUT=$(../bashunit -a exit_code "1" "../../bin/phpstan analyse --no-progress --error-format raw")
1587+
echo "$OUTPUT"
1588+
../bashunit -a contains 'Foo.php:11:Instantiated class Ds\Vector not found.' "$OUTPUT"
1589+
../bashunit -a contains 'Bar.php:15:Call to an undefined method Ds\Pair<string, int>::copy().' "$OUTPUT"
1590+
../bashunit -a not_contains 'Ds\Seq' "$OUTPUT"
1591+
- script: |
1592+
# config.platform names ext-ds 3, which has no stubs, so the required ^2.0 decides instead.
1593+
cd e2e/ext-ds-version
1594+
cp composer-json/v2-unknown-platform.json composer.json
1595+
composer install --ignore-platform-reqs
1596+
OUTPUT=$(../bashunit -a exit_code "1" "../../bin/phpstan analyse --no-progress --error-format raw")
1597+
echo "$OUTPUT"
1598+
../bashunit -a contains 'Foo.php:11:Instantiated class Ds\Vector not found.' "$OUTPUT"
1599+
../bashunit -a contains 'Bar.php:15:Call to an undefined method Ds\Pair<string, int>::copy().' "$OUTPUT"
1600+
../bashunit -a not_contains 'Ds\Seq' "$OUTPUT"
15251601
15261602
steps:
15271603
- name: Harden the runner (Audit all outbound calls)

‎build/composer-dependency-analyser.php‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,5 @@
4343
[ErrorType::UNUSED_DEPENDENCY],
4444
)
4545
->ignoreErrorsOnPackage('phpunit/phpunit', [ErrorType::DEV_DEPENDENCY_IN_PROD]) // prepared test tooling
46-
->ignoreErrorsOnPackage('jetbrains/phpstorm-stubs', [ErrorType::PROD_DEPENDENCY_ONLY_IN_DEV]) // there is no direct usage, but we need newer version then required by ondrejmirtes/BetterReflection
4746
->ignoreErrorsOnPath(__DIR__ . '/../tests', [ErrorType::UNKNOWN_CLASS, ErrorType::UNKNOWN_FUNCTION, ErrorType::SHADOW_DEPENDENCY]) // to be able to test invalid symbols
4847
->ignoreUnknownClasses($unknownClasses);

‎composer.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
"nette/utils": "^3.2.5",
3636
"nikic/php-parser": "^5.8.0",
3737
"ondram/ci-detector": "^4.0",
38-
"ondrejmirtes/better-reflection": "6.73.0.1",
38+
"ondrejmirtes/better-reflection": "6.73.0.2",
3939
"ondrejmirtes/composer-attribute-collector": "^1.2.0",
4040
"ondrejmirtes/php-merge": "^4.1",
4141
"phpstan/php-8-stubs": "0.4.39",

‎composer.lock‎

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎conf/config.neon‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,6 @@ parameters:
157157
- ../stubs/ArrayObject.stub
158158
- ../stubs/WeakReference.stub
159159
- ../stubs/SensitiveParameterValue.stub
160-
- ../stubs/ext-ds.stub
161160
- ../stubs/ImagickPixel.stub
162161
- ../stubs/PDOStatement.stub
163162
- ../stubs/date.stub

‎e2e/ext-ds-version/.gitignore‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/vendor
2+
/composer.json
3+
/composer.lock
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"config": {
3+
"platform": {
4+
"ext-ds": "1.0.0"
5+
}
6+
}
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"config": {
3+
"platform": {
4+
"ext-ds": "2.0.0"
5+
}
6+
}
7+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"require": {
3+
"ext-ds": "^2.0"
4+
}
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"require": {
3+
"ext-ds": "^2.0 || ^2.1"
4+
}
5+
}

0 commit comments

Comments
 (0)