Skip to content

Commit 4f80a48

Browse files
SanderMullerclaude
authored andcommitted
Cover the loader shapes the reverted autoloader attempts broke
#6292 reverted five commits because the attempts fixed one use case and broke another, and only some of those breakages had an e2e project. These two do not test PHPStan's current behaviour so much as pin the shapes a future attempt at phpstan/phpstan#14976 and phpstan/phpstan#14988 must not regress. class-alias-loader uses the real typo3/class-alias-loader: it replaces Composer's loader with its own wrapper, resolves a legacy name through a class alias map, and an IDE-only stub in the analysed paths declares that name as a plain class. The alias has to win. 2.2.9 returns the stub and reports a missing method. robot-loader registers a Nette RobotLoader over a directory Composer does not map, so only that loader can find the class. RobotLoader locks and writes a cache file while resolving, which fails inside the file-read trap: on 598faaa the analysis dies in RobotLoader::acquireLock() with "Unable to create file '<tmp>/....php.lock'". Both pass on this commit. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent f72ad66 commit 4f80a48

14 files changed

Lines changed: 123 additions & 0 deletions

File tree

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,14 @@ jobs:
141141
cd e2e/bug-12972c
142142
composer install
143143
../../bin/phpstan analyze
144+
- script: |
145+
cd e2e/class-alias-loader
146+
composer install
147+
../../bin/phpstan analyze
148+
- script: |
149+
cd e2e/robot-loader
150+
composer install
151+
../../bin/phpstan analyze
144152
- script: |
145153
cd e2e/bug-15102b
146154
../../bin/phpstan analyze

‎e2e/class-alias-loader/.gitignore‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/vendor/
2+
composer.lock
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php declare(strict_types = 1);
2+
3+
// typo3/class-alias-loader replaces Composer's class loader with its own wrapper and
4+
// resolves these names through class_alias() at runtime.
5+
return [
6+
'AliasLoaderE2e\\LegacyName' => 'AliasLoaderE2e\\ModernName',
7+
];
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"require": {
3+
"typo3/class-alias-loader": "^1.2"
4+
},
5+
"autoload": {
6+
"psr-4": {
7+
"AliasLoaderE2e\\": "src/"
8+
}
9+
},
10+
"extra": {
11+
"typo3/class-alias-loader": {
12+
"class-alias-maps": [
13+
"alias-map.php"
14+
],
15+
"always-add-alias-loader": true
16+
}
17+
},
18+
"config": {
19+
"allow-plugins": {
20+
"typo3/class-alias-loader": true
21+
}
22+
}
23+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
parameters:
2+
level: 8
3+
bootstrapFiles:
4+
- vendor/autoload.php
5+
paths:
6+
- test.php
7+
- stub
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace AliasLoaderE2e;
4+
5+
class ModernName
6+
{
7+
8+
public function doFoo(): int
9+
{
10+
return 1;
11+
}
12+
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace AliasLoaderE2e;
4+
5+
// An IDE-only stub, never loaded at runtime: it declares the legacy name as a plain class so
6+
// editors resolve it. At runtime typo3/class-alias-loader makes the name a class_alias to
7+
// ModernName, which is the declaration PHPStan has to use - it has doFoo(), this does not.
8+
die('never loaded at runtime');
9+
10+
class LegacyName
11+
{
12+
13+
}

‎e2e/class-alias-loader/test.php‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php declare(strict_types = 1);
2+
3+
use AliasLoaderE2e\LegacyName;
4+
5+
function (LegacyName $legacy): int {
6+
return $legacy->doFoo();
7+
};

‎e2e/robot-loader/.gitignore‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/vendor/
2+
composer.lock

‎e2e/robot-loader/bootstrap.php‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php declare(strict_types = 1);
2+
3+
require __DIR__ . '/vendor/autoload.php';
4+
5+
$loader = new Nette\Loaders\RobotLoader();
6+
$loader->addDirectory(__DIR__ . '/classes');
7+
$loader->setTempDirectory(sys_get_temp_dir() . '/phpstan-e2e-robot-loader');
8+
$loader->register();

0 commit comments

Comments
 (0)