Skip to content

Commit 87db146

Browse files
authored
chore(deps): Upgrade to PHPStan2 (#1118)
1 parent 0a2556c commit 87db146

38 files changed

+335
-164
lines changed

Makefile

+13-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ PHP_SCOPER_PHAR = $(PHP_SCOPER_PHAR_BIN)
1010
COMPOSER_BIN_PLUGIN_VENDOR = vendor/bamarni/composer-bin-plugin
1111

1212
PHPSTAN_BIN = vendor-bin/phpstan/vendor/bin/phpstan
13-
PHPSTAN = $(PHPSTAN_BIN) analyze src tests --level max --memory-limit=-1
13+
PHPSTAN = $(PHPSTAN_BIN)
1414

1515
BOX_BIN = bin/box
1616
BOX = $(BOX_BIN)
@@ -92,7 +92,18 @@ gitignore_sort:
9292

9393
.PHONY: phpstan
9494
phpstan: $(PHPSTAN_BIN)
95-
$(PHPSTAN)
95+
$(MAKE) _phpstan
96+
97+
.PHONY: _phpstan
98+
_phpstan: _phpstan_src _phpstan_tests
99+
100+
.PHONY: _phpstan_src
101+
_phpstan_src:
102+
$(PHPSTAN) analyze src --memory-limit=-1 --configuration=phpstan-src.neon
103+
104+
.PHONY: _phpstan_tests
105+
_phpstan_tests:
106+
$(PHPSTAN) analyze tests --memory-limit=-1 --configuration=phpstan-tests.neon
96107

97108
.PHONY: autoreview
98109
autoreview: ## Runs the AutoReview checks

phpstan-src.neon

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
parameters:
2+
level: 9
3+
4+
ignoreErrors:
5+
- identifier: missingType.iterableValue
6+
path: 'src/Scoper/Composer/AutoloadPrefixer.php'
7+
- identifier: missingType.iterableValue
8+
message: '#\$config#'
9+
path: 'src/Configuration/ConfigurationFactory.php'
10+
- message: '#Cannot cast array\<string\>\|string to string\.#'
11+
path: 'src/Patcher/SymfonyPatcher.php'
12+
- message: '#Parameter \#1 \$nodes of method PhpParser\\NodeTraverserInterface::traverse\(\) expects array\<PhpParser\\Node\>, array\<PhpParser\\Node\\Stmt\>\|null given\.#'
13+
path: 'src/Scoper/PhpScoper.php'
14+
- message: '#UseStmtManipulator::getOriginalName\(\) should return#'
15+
path: 'src/PhpParser/NodeVisitor/UseStmt/UseStmtManipulator.php'
16+
- message: '#IdentifierResolver::resolveIdentifier\(\) should return#'
17+
path: 'src/PhpParser/NodeVisitor/Resolver/IdentifierResolver.php'
18+
- message: '#ParentNodeAppender::getParent\(\) should return#'
19+
path: 'src/PhpParser/NodeVisitor/AttributeAppender/ParentNodeAppender.php'
20+
- message: '#ParentNodeAppender::findParent\(\) should return#'
21+
path: 'src/PhpParser/NodeVisitor/AttributeAppender/ParentNodeAppender.php'
22+
- message: '#OriginalNameResolver::getOriginalName\(\) should return#'
23+
path: 'src/PhpParser/NodeVisitor/Resolver/OriginalNameResolver.php'
24+
- message: '#NamespaceManipulator::getOriginalName\(\) should return#'
25+
path: 'src/PhpParser/NodeVisitor/NamespaceStmt/NamespaceManipulator.php'
26+
- message: '#::concat\(\) should return .+Name but returns .+\|null#'
27+
path: 'src/PhpParser/Node/NameFactory.php'
28+
- message: '#concat\(\) should return .+FullyQualified but returns .+\|null#'
29+
path: 'src/PhpParser/Node/FullyQualifiedFactory.php'
30+
- message: '#Scoper::scope\(\) expects string\, mixed given\.#'
31+
path: 'src/Scoper/PatchScoper.php'
32+
- message: '#Scoper::scope\(\) expects string\, mixed given\.#'
33+
path: 'src/Scoper/PhpScoper.php'
34+
- message: '#Scoper::scope\(\) expects string\, mixed given\.#'
35+
path: 'src/Scoper/Symfony/XmlScoper.php'
36+
- message: '#Scoper::scope\(\) expects string\, mixed given\.#'
37+
path: 'src/Scoper/Symfony/YamlScoper.php'
38+
- message: '#Scoper::scope\(\) expects string\, mixed given\.#'
39+
path: 'src/Scoper/SymfonyScoper.php'
40+
- message: '#unserialize#'
41+
path: 'src/Symbol/SymbolsRegistry.php'
42+
- message: '#Stmt\:\:\$stmts#'
43+
path: 'src/PhpParser/NodeVisitor/ClassAliasStmtAppender.php'
44+
# Fixed in https://github.com/nikic/PHP-Parser/pull/1003
45+
- message: '#Standard constructor expects array#'
46+
path: 'src/Container.php'

phpstan.neon.dist phpstan-tests.neon

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
parameters:
2-
checkMissingIterableValueType: false
3-
checkGenericClassInNonGenericObjectType: false
2+
level: 9
43

54
excludePaths:
65
- tests/Autoload/AutoloadDumperTest.php
76

87
ignoreErrors:
8+
- identifier: missingType.iterableValue
9+
- identifier: assign.propertyType
910
- message: '#Cannot cast array\<string\>\|string to string\.#'
1011
path: 'src/Patcher/SymfonyPatcher.php'
1112
- message: '#Parameter \#1 \$nodes of method PhpParser\\NodeTraverserInterface::traverse\(\) expects array\<PhpParser\\Node\>, array\<PhpParser\\Node\\Stmt\>\|null given\.#'
@@ -26,8 +27,6 @@ parameters:
2627
path: 'tests/Console/Command/AddPrefixCommandIntegrationTest.php'
2728
- message: '#AddPrefixCommandIntegrationTest\:\:getNormalizeDisplay\(\) should return string but returns array#'
2829
path: 'tests/Console/Command/AddPrefixCommandIntegrationTest.php'
29-
- message: '#ConfigurationKeysTest\:\:retrieveConfigurationKeys\(\) should return array#'
30-
path: 'tests/Configuration/ConfigurationKeysTest.php'
3130
- message: '#Property .* does not accept#'
3231
path: 'src/PhpParser/NodeVisitor/UseStmt/UseStmtCollection.php'
3332
- message: '#::concat\(\) should return .+Name but returns .+\|null#'

src/Autoload/ComposerFileHasher.php

+6
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
private const ROOT_PACKAGE_NAME = '__root__';
2626
private const PACKAGE_PATH_REGEX = '~^%s/(?<vendor>[^/]+?/[^/]+?)/(?<path>.+?)$~';
2727

28+
/**
29+
* @param string[] $filePaths
30+
*/
2831
public static function create(
2932
string $vendorDir,
3033
string $rootDir,
@@ -44,6 +47,9 @@ public static function create(
4447
);
4548
}
4649

50+
/**
51+
* @param string[] $filePaths
52+
*/
4753
public function __construct(
4854
private string $rootDir,
4955
private array $filePaths,

src/Autoload/ScoperAutoloadGenerator.php

+3
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ function humbug_phpscoper_expose_class($exposed, $prefixed) {
5454
/** @var non-empty-string */
5555
private static string $eol;
5656

57+
/**
58+
* @param string[] $excludedComposerAutoloadFileHashes
59+
*/
5760
public function __construct(
5861
private readonly SymbolsRegistry $registry,
5962
private readonly array $excludedComposerAutoloadFileHashes,

src/Configuration/ConfigurationFactory.php

+22-4
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@
5151
use function trim;
5252
use const DIRECTORY_SEPARATOR;
5353

54+
/**
55+
* @phpstan-import-type PatcherCallable from Patcher
56+
*/
5457
final readonly class ConfigurationFactory
5558
{
5659
public const DEFAULT_FILE_NAME = 'scoper.inc.php';
@@ -135,6 +138,8 @@ public function createWithPrefix(Configuration $config, string $prefix): Configu
135138

136139
/**
137140
* @throws InvalidConfigurationValue
141+
*
142+
* @phpstan-ignore missingType.iterableValue
138143
*/
139144
private function loadConfigFile(string $path): array
140145
{
@@ -216,7 +221,7 @@ private static function retrieveOutputDir(array $config): ?string
216221
/**
217222
* @throws InvalidConfigurationValue
218223
*
219-
* @return array<(callable(string,string,string): string)|Patcher>
224+
* @return array<PatcherCallable|Patcher>
220225
*/
221226
private static function retrievePatchers(array $config): array
222227
{
@@ -231,14 +236,26 @@ private static function retrievePatchers(array $config): array
231236
}
232237

233238
foreach ($patchers as $index => $patcher) {
234-
if (!is_callable($patcher)) {
235-
throw InvalidConfigurationValue::forInvalidPatcherType($index, $patcher);
236-
}
239+
self::assertIsPatcher($patcher, $index);
237240
}
238241

242+
/** @phpstan-ignore return.type */
239243
return $patchers;
240244
}
241245

246+
/**
247+
* @phpstan-assert PatcherCallable|Patcher $patcher
248+
*
249+
* @throws InvalidConfigurationValue
250+
*/
251+
private static function assertIsPatcher(mixed $patcher, int|string $index): void
252+
{
253+
/** @phpstan-ignore instanceof.alwaysFalse */
254+
if (!is_callable($patcher) && !($patcher instanceof Patcher)) {
255+
throw InvalidConfigurationValue::forInvalidPatcherType($index, $patcher);
256+
}
257+
}
258+
242259
/**
243260
* @throws InvalidConfigurationValue
244261
*
@@ -298,6 +315,7 @@ private static function retrieveFinders(array $config): array
298315
throw InvalidConfigurationValue::forInvalidFinderType($index, $finder);
299316
}
300317

318+
/** @phpstan-ignore return.type */
301319
return $finders;
302320
}
303321

src/Configuration/SymbolsConfigurationFactory.php

+9-2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ public function __construct(private RegexChecker $regexChecker)
3535
{
3636
}
3737

38+
/**
39+
* @param array<array-key, mixed> $config
40+
*/
3841
public function createSymbolsConfiguration(array $config): SymbolsConfiguration
3942
{
4043
[
@@ -132,6 +135,9 @@ public function createSymbolsConfiguration(array $config): SymbolsConfiguration
132135
);
133136
}
134137

138+
/**
139+
* @param array<array-key, mixed> $config
140+
*/
135141
private static function retrieveExposeGlobalSymbol(array $config, string $key): bool
136142
{
137143
if (!array_key_exists($key, $config)) {
@@ -154,6 +160,7 @@ private static function retrieveExposeGlobalSymbol(array $config, string $key):
154160
}
155161

156162
/**
163+
* @param array<array-key, mixed> $config
157164
* @return array{list<string>, list<string>}
158165
*/
159166
private function retrieveElements(array $config, string $key): array
@@ -164,7 +171,7 @@ private function retrieveElements(array $config, string $key): array
164171

165172
$symbolNamesAndRegexes = $config[$key];
166173

167-
self::assertIsArrayOfStrings($config[$key], $key);
174+
self::assertIsArrayOfStrings($symbolNamesAndRegexes, $key);
168175

169176
// Store the strings in the keys for avoiding a unique check later on
170177
$names = [];
@@ -232,7 +239,7 @@ private static function getRegexFlags(string $regex): string
232239
}
233240

234241
/**
235-
* @psalm-assert string[] $value
242+
* @phpstan-assert string[] $value
236243
*/
237244
private static function assertIsArrayOfStrings(mixed $value, string $key): void
238245
{

src/Console/Command/InspectSymbolCommand.php

+3
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,9 @@ private static function printTypedSymbol(
291291
]);
292292
}
293293

294+
/**
295+
* @return array{bool, bool}
296+
*/
294297
private static function determineSymbolStatus(
295298
string $symbol,
296299
SymbolType $type,

src/Console/ConsoleScoper.php

+3
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,9 @@ private static function getCommonDirectoryPath(Configuration $config): string
299299
return $commonPath;
300300
}
301301

302+
/**
303+
* @param string[] $outputFilePaths
304+
*/
302305
private static function findVendorDir(array $outputFilePaths): ?string
303306
{
304307
$vendorDirsAsKeys = [];

src/Patcher/Patcher.php

+3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414

1515
namespace Humbug\PhpScoper\Patcher;
1616

17+
/**
18+
* @phpstan-type PatcherCallable callable(string $filePath, string $prefix, string $contents): string
19+
*/
1720
interface Patcher
1821
{
1922
public function __invoke(string $filePath, string $prefix, string $contents): string;

src/Patcher/PatcherChain.php

+5-2
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,13 @@
1616

1717
use function array_reduce;
1818

19+
/**
20+
* @phpstan-import-type PatcherCallable from Patcher
21+
*/
1922
final readonly class PatcherChain implements Patcher
2023
{
2124
/**
22-
* @param array<(callable(string, string, string): string)|Patcher> $patchers
25+
* @param array<PatcherCallable|Patcher> $patchers
2326
*/
2427
public function __construct(private array $patchers = [])
2528
{
@@ -35,7 +38,7 @@ public function __invoke(string $filePath, string $prefix, string $contents): st
3538
}
3639

3740
/**
38-
* @return array<(callable(string, string, string): string)|Patcher>
41+
* @return array<PatcherCallable|Patcher>
3942
*/
4043
public function getPatchers(): array
4144
{

src/Patcher/SymfonyParentTraitPatcher.php

+6
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ private static function isSupportedFile(string $filePath): bool
6060
return false;
6161
}
6262

63+
/**
64+
* @return list<string>
65+
*/
6366
private function getReplacement(string $prefix): array
6467
{
6568
if (!array_key_exists($prefix, $this->replacement)) {
@@ -69,6 +72,9 @@ private function getReplacement(string $prefix): array
6972
return $this->replacement[$prefix];
7073
}
7174

75+
/**
76+
* @return list<string>
77+
*/
7278
private static function generateReplacement(string $prefix): array
7379
{
7480
$prefixLength = strlen($prefix);

src/PhpParser/Node/FullyQualifiedFactory.php

+4
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,17 @@
1919
use PhpParser\Node\Name;
2020
use PhpParser\Node\Name\FullyQualified;
2121

22+
/**
23+
* @phpstan-import-type Attributes from NameFactory
24+
*/
2225
final class FullyQualifiedFactory
2326
{
2427
use NotInstantiable;
2528

2629
/**
2730
* @param string|Name|string[]|null $name1
2831
* @param string|Name|string[]|null $name2
32+
* @param Attributes|null $attributes
2933
*/
3034
public static function concat(
3135
array|Name|string|null $name1,

src/PhpParser/Node/NameFactory.php

+7
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,17 @@
1818
use InvalidArgumentException;
1919
use PhpParser\Node\Name;
2020

21+
/**
22+
* @phpstan-type Attributes array<string, mixed>
23+
*/
2124
final class NameFactory
2225
{
2326
use NotInstantiable;
2427

2528
/**
2629
* @param string|Name|string[]|null $name1
2730
* @param string|Name|string[]|null $name2
31+
* @param Attributes|null $attributes
2832
*/
2933
public static function concat(
3034
array|Name|string|null $name1,
@@ -43,6 +47,9 @@ public static function concat(
4347
/**
4448
* @param string|string[]|Name|null $name1
4549
* @param string|string[]|Name|null $name2
50+
* @param Attributes|null $attributes
51+
*
52+
* @return Attributes
4653
*/
4754
public static function getConcatenatedNamesAttributes(
4855
string|array|Name|null $name1,

src/PhpParser/NodeVisitor/AttributeAppender/ParentNodeAppender.php

+6-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,12 @@ public static function findParent(Node $node): ?Node
5656
: null;
5757
}
5858

59-
public function beforeTraverse(array $nodes): ?array
59+
/**
60+
* @param Node[] $nodes
61+
*
62+
* @return Node[]
63+
*/
64+
public function beforeTraverse(array $nodes): array
6065
{
6166
$this->stack = [];
6267

src/PhpParser/NodeVisitor/ClassAliasStmtAppender.php

+6
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ public function __construct(
6565
) {
6666
}
6767

68+
/**
69+
* @param Node[] $nodes
70+
*
71+
* @return Node[]
72+
*/
6873
public function afterTraverse(array $nodes): array
6974
{
7075
$this->traverseNodes($nodes);
@@ -125,6 +130,7 @@ private function appendClassAliasStmtIfApplicable(array $stmts, Stmt $stmt): arr
125130
return $this->appendClassAliasStmtIfNecessary($stmts, $stmt);
126131
}
127132

133+
/** @phpstan-ignore staticMethod.alreadyNarrowedType */
128134
if (self::isNodeAStatementWithStatements($stmt)) {
129135
$this->updateStatements($stmt);
130136
}

0 commit comments

Comments
 (0)