Skip to content

Commit 9a0359f

Browse files
authored
Merge pull request #17 from adriansuter/feature-phpstan
Add phpstan
2 parents 8fc17d8 + 972fc94 commit 9a0359f

File tree

10 files changed

+137
-41
lines changed

10 files changed

+137
-41
lines changed

.editorconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ trim_trailing_whitespace = true
1111
[*.md]
1212
trim_trailing_whitespace = false
1313

14-
[*.{yml,yaml}]
14+
[*.{yml,yaml,json}]
1515
indent_size = 2

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@
1111
/.gitignore export-ignore
1212
/.travis.yml export-ignore
1313
/phpcs.xml.dist export-ignore
14+
/phpstan.neon.dist export-ignore
1415
/phpunit.xml.dist export-ignore

composer.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,21 @@
3838
"nikic/php-parser": "^4.4"
3939
},
4040
"require-dev": {
41+
"phpstan/phpstan": "^0.12.25",
4142
"phpunit/phpunit": "^7.5",
4243
"squizlabs/php_codesniffer": "^3.5"
4344
},
4445
"scripts": {
4546
"test": [
4647
"@phpunit",
47-
"@phpcs"
48+
"@phpcs",
49+
"@phpstan"
4850
],
4951
"phpunit": "phpunit",
50-
"phpcs": "phpcs"
52+
"phpcs": "phpcs",
53+
"phpstan": "phpstan analyse src --memory-limit=-1"
54+
},
55+
"config": {
56+
"sort-packages": true
5157
}
5258
}

phpstan.neon.dist

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
parameters:
2+
level: max
3+
ignoreErrors:
4+
- message: '/Parameter \#3 \$microseconds of function stream_set_timeout expects int, int\|null given./'
5+
path: src/FileStreamWrapper.php
6+
count: 1

src/AutoloadCollection.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,10 @@ public function addDirectory(string $directory): void
5959
}
6060

6161
$files = glob($directory . '/*.php');
62-
foreach ($files as $file) {
63-
$this->addFile($file);
62+
if (is_array($files)) {
63+
foreach ($files as $file) {
64+
$this->addFile($file);
65+
}
6466
}
6567
}
6668

src/ClosureHandler.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public function addClosure(string $name, Closure $closure): void
6464
* Magic call.
6565
*
6666
* @param string $name The method name.
67-
* @param array $arguments The method arguments.
67+
* @param array<mixed> $arguments The method arguments.
6868
*
6969
* @return mixed
7070
*/

src/CodeConverter.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use PhpParser\Parser;
2222
use PhpParser\Parser\Php7;
2323
use PhpParser\PrettyPrinter\Standard;
24+
use RuntimeException;
2425

2526
use function array_keys;
2627
use function array_values;
@@ -107,20 +108,23 @@ private function defaultLexer(): Lexer
107108
* Convert the given source code.
108109
*
109110
* @param string $code The source code.
110-
* @param array $functionCallMap The function call map.
111+
* @param array<string, string> $functionCallMap The function call map.
111112
*
112113
* @return string
113114
*/
114115
public function convert(string $code, array $functionCallMap): string
115116
{
116117
$oldStmts = $this->parser->parse($code);
117-
$oldTokens = $this->lexer->getTokens();
118+
if (is_null($oldStmts)) {
119+
throw new RuntimeException('Code could not be parsed.');
120+
}
118121

119-
$overridePlaceholders = [];
122+
$oldTokens = $this->lexer->getTokens();
120123

121124
$newStmts = $this->traverser->traverse($oldStmts);
122125

123126
// Find function calls.
127+
$overridePlaceholders = [];
124128
$funcCalls = $this->nodeFinder->findInstanceOf($newStmts, FuncCall::class);
125129
foreach ($funcCalls as $funcCall) {
126130
/** @var FuncCall $funcCall */

src/FileStreamWrapper.php

Lines changed: 74 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
namespace AdrianSuter\Autoload\Override;
1212

13+
use RuntimeException;
14+
1315
use function chgrp;
1416
use function chmod;
1517
use function chown;
@@ -47,12 +49,12 @@
4749
class FileStreamWrapper
4850
{
4951
/**
50-
* @var resource
52+
* @var resource|null
5153
*/
5254
public $context;
5355

5456
/**
55-
* @var resource|null
57+
* @var resource|null|false
5658
*/
5759
private $resource;
5860

@@ -65,7 +67,9 @@ public function dir_closedir(): bool
6567
{
6668
stream_wrapper_restore('file');
6769

68-
closedir($this->resource);
70+
if (is_resource($this->resource)) {
71+
closedir($this->resource);
72+
}
6973

7074
stream_wrapper_unregister('file');
7175
stream_wrapper_register('file', self::class);
@@ -108,7 +112,10 @@ public function dir_readdir()
108112
{
109113
stream_wrapper_restore('file');
110114

111-
$r = readdir($this->resource);
115+
$r = false;
116+
if (is_resource($this->resource)) {
117+
$r = readdir($this->resource);
118+
}
112119

113120
stream_wrapper_unregister('file');
114121
stream_wrapper_register('file', self::class);
@@ -126,7 +133,9 @@ public function dir_rewinddir(): bool
126133
{
127134
stream_wrapper_restore('file');
128135

129-
rewinddir($this->resource);
136+
if (is_resource($this->resource)) {
137+
rewinddir($this->resource);
138+
}
130139

131140
stream_wrapper_unregister('file');
132141
stream_wrapper_register('file', self::class);
@@ -234,7 +243,9 @@ public function stream_close(): void
234243
{
235244
stream_wrapper_restore('file');
236245

237-
fclose($this->resource);
246+
if (is_resource($this->resource)) {
247+
fclose($this->resource);
248+
}
238249

239250
stream_wrapper_unregister('file');
240251
stream_wrapper_register('file', self::class);
@@ -250,7 +261,10 @@ public function stream_eof(): bool
250261
{
251262
stream_wrapper_restore('file');
252263

253-
$r = feof($this->resource);
264+
$r = false;
265+
if (is_resource($this->resource)) {
266+
$r = feof($this->resource);
267+
}
254268

255269
stream_wrapper_unregister('file');
256270
stream_wrapper_register('file', self::class);
@@ -268,7 +282,10 @@ public function stream_flush(): bool
268282
{
269283
stream_wrapper_restore('file');
270284

271-
$r = fflush($this->resource);
285+
$r = false;
286+
if (is_resource($this->resource)) {
287+
$r = fflush($this->resource);
288+
}
272289

273290
stream_wrapper_unregister('file');
274291
stream_wrapper_register('file', self::class);
@@ -307,7 +324,7 @@ public function stream_metadata(string $path, int $option, $value): bool
307324
$r = false;
308325
switch ($option) {
309326
case STREAM_META_TOUCH:
310-
if (!isset($value[0]) || $value[0] === null) {
327+
if (!isset($value[0]) || is_null($value[0])) {
311328
$r = touch($path);
312329
} else {
313330
$r = touch($path, $value[0], $value[1]);
@@ -361,11 +378,16 @@ public function stream_open(string $path, string $mode, int $options, ?string &$
361378
// Replace the global function calls into local function calls.
362379
if (!empty($functionCallMap)) {
363380
$source = file_get_contents($path, $usePath);
381+
if (!is_string($source)) {
382+
throw new RuntimeException(sprintf("File `%s` could not be loaded.", $path));
383+
}
364384
$source = Override::convert($source, $functionCallMap);
365385

366386
$this->resource = fopen('php://temp', 'w+');
367-
fwrite($this->resource, $source);
368-
fseek($this->resource, 0);
387+
if (is_resource($this->resource)) {
388+
fwrite($this->resource, $source);
389+
fseek($this->resource, 0);
390+
}
369391
} elseif (is_resource($this->context)) {
370392
$this->resource = fopen($path, $mode, $usePath, $this->context);
371393
} else {
@@ -390,7 +412,10 @@ public function stream_read(int $count): string
390412
{
391413
stream_wrapper_restore('file');
392414

393-
$r = fgets($this->resource, $count);
415+
$r = false;
416+
if (is_resource($this->resource)) {
417+
$r = fgets($this->resource, $count);
418+
}
394419

395420
stream_wrapper_unregister('file');
396421
stream_wrapper_register('file', self::class);
@@ -415,7 +440,10 @@ public function stream_seek(int $offset, int $whence = SEEK_SET): bool
415440
{
416441
stream_wrapper_restore('file');
417442

418-
$r = fseek($this->resource, $offset, $whence);
443+
$r = -1;
444+
if (is_resource($this->resource)) {
445+
$r = fseek($this->resource, $offset, $whence);
446+
}
419447

420448
stream_wrapper_unregister('file');
421449
stream_wrapper_register('file', self::class);
@@ -440,21 +468,29 @@ public function stream_set_option(int $option, int $arg1, ?int $arg2)
440468
$r = false;
441469
switch ($option) {
442470
case STREAM_OPTION_BLOCKING:
443-
$r = stream_set_blocking($this->resource, $arg1 ? true : false);
471+
if (is_resource($this->resource)) {
472+
$r = stream_set_blocking($this->resource, $arg1 ? true : false);
473+
}
444474
break;
445475

446476
case STREAM_OPTION_READ_TIMEOUT:
447-
$r = stream_set_timeout($this->resource, $arg1, $arg2);
477+
if (is_resource($this->resource)) {
478+
$r = stream_set_timeout($this->resource, $arg1, $arg2);
479+
}
448480
break;
449481

450482
case STREAM_OPTION_WRITE_BUFFER:
451483
switch ($arg1) {
452484
case STREAM_BUFFER_NONE:
453-
$r = stream_set_write_buffer($this->resource, 0);
485+
if (is_resource($this->resource)) {
486+
$r = stream_set_write_buffer($this->resource, 0);
487+
}
454488
break;
455489

456490
case STREAM_BUFFER_FULL:
457-
$r = stream_set_write_buffer($this->resource, $arg2);
491+
if (is_resource($this->resource) && is_int($arg2)) {
492+
$r = stream_set_write_buffer($this->resource, $arg2);
493+
}
458494
break;
459495
}
460496
break;
@@ -469,14 +505,20 @@ public function stream_set_option(int $option, int $arg1, ?int $arg2)
469505
/**
470506
* Retrieve information about a file resource.
471507
*
472-
* @return array
508+
* @return array<int|string, int>
473509
* @noinspection PhpUnused
474510
*/
475511
public function stream_stat(): array
476512
{
477513
stream_wrapper_restore('file');
478514

479-
$r = fstat($this->resource);
515+
$r = [];
516+
if (is_resource($this->resource)) {
517+
$r = fstat($this->resource);
518+
if (!is_array($r)) {
519+
$r = [];
520+
}
521+
}
480522

481523
stream_wrapper_unregister('file');
482524
stream_wrapper_register('file', self::class);
@@ -494,7 +536,10 @@ public function stream_tell(): int
494536
{
495537
stream_wrapper_restore('file');
496538

497-
$r = fseek($this->resource, 0, SEEK_CUR);
539+
$r = -1;
540+
if (is_resource($this->resource)) {
541+
$r = fseek($this->resource, 0, SEEK_CUR);
542+
}
498543

499544
stream_wrapper_unregister('file');
500545
stream_wrapper_register('file', self::class);
@@ -514,7 +559,10 @@ public function stream_truncate(int $new_size): bool
514559
{
515560
stream_wrapper_restore('file');
516561

517-
$r = ftruncate($this->resource, $new_size);
562+
$r = false;
563+
if (is_resource($this->resource)) {
564+
$r = ftruncate($this->resource, $new_size);
565+
}
518566

519567
stream_wrapper_unregister('file');
520568
stream_wrapper_register('file', self::class);
@@ -534,7 +582,10 @@ public function stream_write(string $data)
534582
{
535583
stream_wrapper_restore('file');
536584

537-
$r = fwrite($this->resource, $data);
585+
$r = false;
586+
if (is_resource($this->resource)) {
587+
$r = fwrite($this->resource, $data);
588+
}
538589

539590
stream_wrapper_unregister('file');
540591
stream_wrapper_register('file', self::class);
@@ -567,7 +618,7 @@ public function unlink(string $path): bool
567618
* @param string $path
568619
* @param int $flags
569620
*
570-
* @return array|false
621+
* @return array<int|string, int>|false
571622
* @noinspection PhpUnused
572623
*/
573624
public function url_stat(string $path, int $flags)

0 commit comments

Comments
 (0)