Skip to content

Commit 514edfb

Browse files
authored
Add PHPStan (#274)
Add PHPStan level 6 checks in the CI and fixed the issues reported
2 parents 188ff49 + bdb04a8 commit 514edfb

19 files changed

+251
-49
lines changed

.travis.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,11 @@ install:
2727
script:
2828
- |
2929
if [ "$COVERAGE" == "true" ]; then
30-
make tc
31-
travis_wait 30 make e2e
30+
make tc
31+
travis_wait 30 make e2e
3232
else
33-
make tu
33+
make tu
34+
make phpstan
3435
fi
3536
3637
deploy:

Makefile

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ cs: $(CODE_SNIFFER) $(CODE_SNIFFER_FIX)
2525
$(PHPNOGC) $(CODE_SNIFFER_FIX) || true
2626
$(PHPNOGC) $(CODE_SNIFFER)
2727

28+
.PHONY: phpstan
29+
PHPSTAN=vendor-bin/phpstan/vendor/bin/phpstan
30+
phpstan: ## Runs PHPStan
31+
phpstan: $(PHPSTAN)
32+
$(PHPNOGC) $(PHPSTAN) analyze src -l6
33+
2834
.PHONY: build
2935
build: ## Build the PHAR
3036
BOX=bin/box
@@ -326,6 +332,10 @@ vendor-bin/code-sniffer/vendor: vendor-bin/code-sniffer/composer.lock vendor/bam
326332
composer bin code-sniffer install
327333
touch $@
328334

335+
vendor-bin/phpstan/vendor: vendor-bin/phpstan/composer.lock vendor/bamarni
336+
composer bin phpstan install
337+
touch $@
338+
329339
fixtures/set005/vendor: fixtures/set005/composer.lock
330340
composer --working-dir=fixtures/set005 install
331341
touch $@
@@ -392,6 +402,12 @@ composer.lock: composer.json
392402
vendor-bin/covers-validator/composer.lock: vendor-bin/covers-validator/composer.json
393403
@echo covers-validator composer.lock is not up to date
394404

405+
vendor-bin/code-sniffer/composer.lock: vendor-bin/code-sniffer/composer.json
406+
@echo code-sniffer composer.lock is not up to date
407+
408+
vendor-bin/phpstan/composer.lock: vendor-bin/phpstan/composer.json
409+
@echo phpstan composer.lock is not up to date
410+
395411
fixtures/set005/composer.lock: fixtures/set005/composer.json
396412
@echo fixtures/set005/composer.lock is not up to date.
397413

@@ -449,3 +465,7 @@ $(CODE_SNIFFER): vendor-bin/code-sniffer/vendor
449465
$(CODE_SNIFFER_FIX): vendor-bin/code-sniffer/vendor
450466
composer bin code-sniffer install
451467
touch $@
468+
469+
$(PHPSTAN): vendor-bin/phpstan/vendor
470+
composer bin phpstan install
471+
touch $@

composer.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,17 @@
4040
"bin": ["bin/php-scoper"],
4141
"autoload": {
4242
"files": [
43-
"src/functions.php"
43+
"src/functions.php",
44+
"src/json.php"
4445
],
4546
"psr-4": {
4647
"Humbug\\PhpScoper\\": "src/"
4748
}
4849
},
4950
"autoload-dev": {
5051
"files": [
51-
"tests/functions.php"
52+
"tests/functions.php",
53+
"src/json.php"
5254
],
5355
"psr-4": {
5456
"Humbug\\PhpScoper\\": "tests/"

phpstan.neon

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
parameters:
2+
excludes_analyse:
3+
- src/Console/Command/AddPrefixCommand.php

src/Configuration.php

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@
1414

1515
namespace Humbug\PhpScoper;
1616

17-
use Closure;
1817
use InvalidArgumentException;
1918
use Iterator;
2019
use RuntimeException;
2120
use SplFileInfo;
2221
use Symfony\Component\Filesystem\Filesystem;
2322
use Symfony\Component\Finder\Finder;
2423
use const DIRECTORY_SEPARATOR;
24+
use function array_key_exists;
2525
use function dirname;
2626
use function file_exists;
2727
use function gettype;
@@ -138,16 +138,15 @@ public static function load(string $path = null, array $paths = []): self
138138
}
139139

140140
/**
141-
* @param string|null $path Absolute path to the configuration file loaded.
142-
* @param string|null $prefix The prefix applied.
143-
* @param [string, string][] $filesWithContents Array of tuple with the first argument being the file path and the second its contents
144-
* @param callable[] $patchers List of closures which can alter the content of the files being
145-
* scoped.
146-
* @param Whitelist $whitelist List of classes that will not be scoped.
147-
* @param Closure $globalNamespaceWhitelisters Closure taking a class name from the global namespace as an argument and
148-
* returning a boolean which if `true` means the class should be scoped
149-
* (i.e. is ignored) or scoped otherwise.
150-
* @param string[] $whitelistedFiles List of absolute paths of files to completely ignore
141+
* @param string|null $path Absolute path to the configuration file loaded.
142+
* @param string|null $prefix The prefix applied.
143+
* @param string[][] $filesWithContents Array of tuple with the first argument being the file path and the second its contents
144+
* @param callable[] $patchers List of closures which can alter the content of the files being
145+
* scoped.
146+
* @param Whitelist $whitelist List of classes that will not be scoped.
147+
* returning a boolean which if `true` means the class should be scoped
148+
* (i.e. is ignored) or scoped otherwise.
149+
* @param string[] $whitelistedFiles List of absolute paths of files to completely ignore
151150
*/
152151
private function __construct(
153152
?string $path,
@@ -238,7 +237,7 @@ public function getWhitelistedFiles(): array
238237
private static function validateConfigKeys(array $config): void
239238
{
240239
array_map(
241-
['self', 'validateConfigKey'],
240+
self::class.'::validateConfigKey',
242241
array_keys($config)
243242
);
244243
}
@@ -263,7 +262,7 @@ private static function validateConfigKey(string $key): void
263262
*/
264263
private static function retrievePrefix(array $config): ?string
265264
{
266-
$prefix = array_key_exists(self::PREFIX_KEYWORD, $config) ? $config[self::PREFIX_KEYWORD] : null;
265+
$prefix = $config[self::PREFIX_KEYWORD] ?? null;
267266

268267
if (null === $prefix) {
269268
return null;
@@ -515,7 +514,7 @@ private static function retrieveFilesFromPaths(array $paths): iterable
515514
/**
516515
* @param Iterator $files
517516
*
518-
* @return [string, string][] Array of tuple with the first argument being the file path and the second its contents
517+
* @return string[][] Array of tuple with the first argument being the file path and the second its contents
519518
*/
520519
private static function retrieveFilesWithContents(Iterator $files): array
521520
{

src/Console/Command/BaseCommand.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ protected function configure(): void
4040

4141
final public function changeWorkingDirectory(InputInterface $input): void
4242
{
43+
/** @var string|null $workingDir */
4344
$workingDir = $input->getOption(self::WORKING_DIR_OPT);
4445

4546
if (null === $workingDir) {

src/Console/Command/InitCommand.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
104104

105105
private function retrieveConfig(InputInterface $input, OutputStyle $io): ?string
106106
{
107+
/** @var string|null $configFile */
107108
$configFile = $input->getOption(self::CONFIG_FILE_OPT);
108109

109110
$configFile = (null === $configFile)

src/PhpParser/NodeTraverser.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
use PhpParser\Node\Stmt\Use_;
2424
use PhpParser\Node\Stmt\UseUse;
2525
use PhpParser\NodeTraverser as PhpParserNodeTraverser;
26+
use function array_slice;
27+
use function array_values;
28+
use function count;
2629

2730
/**
2831
* @private
@@ -84,6 +87,13 @@ public function traverse(array $nodes): array
8487
*/
8588
private function wrapInNamespace(array $nodes): array
8689
{
90+
if ([] === $nodes) {
91+
return $nodes;
92+
}
93+
94+
$nodes = array_values($nodes);
95+
96+
$firstRealStatementIndex = 0;
8797
$realStatements = [];
8898

8999
foreach ($nodes as $i => $node) {

src/PhpParser/NodeVisitor/Collection/NamespaceStmtCollection.php

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ final class NamespaceStmtCollection implements IteratorAggregate, Countable
3737
private $nodes = [];
3838

3939
/**
40-
* @var Name|null[] Associative array with the potentially prefixed namespace names as keys and their original name
41-
* as value.
40+
* @var (Name|null)[] Associative array with the potentially prefixed namespace names as keys and their original name
41+
* as value.
4242
*/
4343
private $mapping = [];
4444

@@ -80,11 +80,9 @@ public function findNamespaceByName(string $name): ?Name
8080

8181
public function getCurrentNamespaceName(): ?Name
8282
{
83-
if (0 === count($this->nodes)) {
84-
return null;
85-
}
83+
$lastNode = end($this->nodes);
8684

87-
return end($this->nodes)->name;
85+
return false === $lastNode ? null : $lastNode->name;
8886
}
8987

9088
/**

src/PhpParser/NodeVisitor/Collection/UseStmtCollection.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public function findStatementForNode(?Name $namespaceName, Name $node): ?Name
8585

8686
foreach ($useStatements as $use_) {
8787
foreach ($use_->uses as $useStatement) {
88-
if (false === ($useStatement instanceof UseUse)) {
88+
if (!($useStatement instanceof UseUse)) {
8989
continue;
9090
}
9191

0 commit comments

Comments
 (0)