Skip to content

Commit ac9e1f0

Browse files
committed
fixed PHPStan errors
1 parent 59d28a8 commit ac9e1f0

File tree

11 files changed

+282
-79
lines changed

11 files changed

+282
-79
lines changed

phpstan-baseline.neon

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
parameters:
2+
ignoreErrors:
3+
-
4+
message: '#^Parameter \#1 \$key \(\(int\|string\)\) of method Nette\\Utils\\ArrayHash\:\:offsetSet\(\) should be contravariant with parameter \$offset \(int\|string\|null\) of method ArrayAccess\<\(int\|string\),T\>\:\:offsetSet\(\)$#'
5+
identifier: method.childParameterType
6+
count: 1
7+
path: src/Utils/ArrayHash.php
8+
9+
-
10+
message: '#^Call to static method Nette\\Utils\\Arrays\:\:isList\(\) with list\<T\> will always evaluate to true\.$#'
11+
identifier: staticMethod.alreadyNarrowedType
12+
count: 1
13+
path: src/Utils/ArrayList.php
14+
15+
-
16+
message: '#^Property Nette\\Utils\\ArrayList\<T\>\:\:\$list \(list\<T\>\) does not accept non\-empty\-array\<int\<0, max\>, T\>\.$#'
17+
identifier: assign.propertyType
18+
count: 1
19+
path: src/Utils/ArrayList.php
20+
21+
-
22+
message: '#^Cannot access offset string on array\<mixed\>\|object\.$#'
23+
identifier: offsetAccess.nonOffsetAccessible
24+
count: 3
25+
path: src/Utils/Arrays.php
26+
27+
-
28+
message: '#^Method Nette\\Utils\\Arrays\:\:invoke\(\) has parameter \$callbacks with no signature specified for callable\.$#'
29+
identifier: missingType.callable
30+
count: 1
31+
path: src/Utils/Arrays.php
32+
33+
-
34+
message: '#^Parameter \#1 \$objectOrMethod of class Nette\\Utils\\ReflectionMethod constructor expects class\-string\|object, string given\.$#'
35+
identifier: argument.type
36+
count: 1
37+
path: src/Utils/Callback.php
38+
39+
-
40+
message: '#^Left side of && is always true\.$#'
41+
identifier: booleanAnd.leftAlwaysTrue
42+
count: 2
43+
path: src/Utils/DateTime.php
44+
45+
-
46+
message: '#^Parameter \#1 \$pathNames of method Nette\\Utils\\Finder\:\:convertToFiles\(\) expects iterable\<string\>, FilesystemIterator given\.$#'
47+
identifier: argument.type
48+
count: 1
49+
path: src/Utils/Finder.php
50+
51+
-
52+
message: '#^Parameter \#2 \$operator of static method Nette\\Utils\\Helpers\:\:compare\(\) expects ''\!\=''\|''\!\=\=''\|''\<''\|''\<\=''\|''\<\>''\|''\=''\|''\=\=''\|''\=\=\=''\|''\>''\|''\>\='', non\-falsy\-string given\.$#'
53+
identifier: argument.type
54+
count: 2
55+
path: src/Utils/Finder.php
56+
57+
-
58+
message: '#^Trying to invoke non\-falsy\-string but it might not be a callable\.$#'
59+
identifier: callable.nonCallable
60+
count: 1
61+
path: src/Utils/Finder.php
62+
63+
-
64+
message: '#^Variable \$res on left side of \?\?\= always exists and is not nullable\.$#'
65+
identifier: nullCoalesce.variable
66+
count: 1
67+
path: src/Utils/Finder.php
68+
69+
-
70+
message: '#^Match arm comparison between ''\!\=\='' and ''\!\=\='' is always true\.$#'
71+
identifier: match.alwaysTrue
72+
count: 1
73+
path: src/Utils/Helpers.php
74+
75+
-
76+
message: '#^Comparison operation "\<" between int\<1, max\> and 1 is always false\.$#'
77+
identifier: smaller.alwaysFalse
78+
count: 2
79+
path: src/Utils/Image.php
80+
81+
-
82+
message: '#^Match arm comparison between 6 and 6 is always true\.$#'
83+
identifier: match.alwaysTrue
84+
count: 2
85+
path: src/Utils/Image.php
86+
87+
-
88+
message: '#^Offset 1\|2\|3\|6\|18\|19 on array\{2\: ''jpeg'', 3\: ''png'', 1\: ''gif'', 18\: ''webp'', 19\: ''avif'', 6\: ''bmp''\} in isset\(\) always exists and is not nullable\.$#'
89+
identifier: isset.offset
90+
count: 1
91+
path: src/Utils/Image.php
92+
93+
-
94+
message: '#^Result of \|\| is always false\.$#'
95+
identifier: booleanOr.alwaysFalse
96+
count: 1
97+
path: src/Utils/Image.php
98+
99+
-
100+
message: '#^Parameter \#1 \$class of class ReflectionClassConstant constructor expects class\-string\|object, string given\.$#'
101+
identifier: argument.type
102+
count: 1
103+
path: src/Utils/Reflection.php
104+
105+
-
106+
message: '#^Right side of && is always true\.$#'
107+
identifier: booleanAnd.rightAlwaysTrue
108+
count: 2
109+
path: src/Utils/Reflection.php
110+
111+
-
112+
message: '#^Parameter \#1 \$objectOrClass of class ReflectionClass constructor expects class\-string\<T of object\>\|T of object, object\|string given\.$#'
113+
identifier: argument.type
114+
count: 1
115+
path: src/Utils/ReflectionMethod.php
116+
117+
-
118+
message: '#^Parameter \#2 \$method of method ReflectionMethod\:\:__construct\(\) expects string, string\|null given\.$#'
119+
identifier: argument.type
120+
count: 1
121+
path: src/Utils/ReflectionMethod.php
122+
123+
-
124+
message: '#^Method Nette\\Utils\\Strings\:\:match\(\) should return array\<string\>\|null but returns array\<array\<int, int\|string\>\>\.$#'
125+
identifier: return.type
126+
count: 1
127+
path: src/Utils/Strings.php
128+
129+
-
130+
message: '#^Strict comparison using \!\=\= between string and false will always evaluate to true\.$#'
131+
identifier: notIdentical.alwaysTrue
132+
count: 1
133+
path: src/Utils/Strings.php
134+
135+
-
136+
message: '#^Parameter \#1 \$givenTypes of method Nette\\Utils\\Type\:\:allowsAny\(\) expects array\<string\>, list\<Nette\\Utils\\Type\|string\> given\.$#'
137+
identifier: argument.type
138+
count: 2
139+
path: src/Utils/Type.php
140+
141+
-
142+
message: '#^Parameter \#1 \$ourTypes of method Nette\\Utils\\Type\:\:allowsAll\(\) expects array\<string\>, list\<Nette\\Utils\\Type\|string\> given\.$#'
143+
identifier: argument.type
144+
count: 2
145+
path: src/Utils/Type.php
146+
147+
-
148+
message: '#^Parameter \#2 \$of of static method Nette\\Utils\\Type\:\:resolve\(\) expects ReflectionFunction\|ReflectionMethod\|ReflectionParameter\|ReflectionProperty, ReflectionFunctionAbstract\|ReflectionParameter\|ReflectionProperty given\.$#'
149+
identifier: argument.type
150+
count: 1
151+
path: src/Utils/Type.php

phpstan.neon

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,50 @@
11
parameters:
2-
level: 5
2+
level: 8
33

44
paths:
55
- src
66

7+
excludePaths:
8+
- src/compatibility.php
9+
- src/Iterators/Mapper.php
10+
- src/Utils/ObjectHelpers.php
11+
712
bootstrapFiles:
813
- tests/phpstan-bootstrap.php
914

1015
ignoreErrors:
11-
# PHPStan does not support dynamic by reference return used by Nette\Utils\Strings::pcre()
12-
- '#Undefined variable: \$m#'
16+
# Intentional design pattern: new static() for inheritance support in fluent interfaces
17+
-
18+
identifier: new.static
19+
paths:
20+
- src/Utils/ArrayHash.php
21+
- src/Utils/ArrayList.php
22+
- src/Utils/DateTime.php
23+
- src/Utils/Finder.php
24+
- src/Utils/Html.php
25+
- src/Utils/Image.php
26+
27+
# Runtime validation: type narrowing checks that are necessary at runtime
28+
-
29+
identifier: function.alreadyNarrowedType
30+
paths:
31+
- src/Utils/ArrayHash.php
32+
- src/Utils/ArrayList.php
33+
- src/Utils/Strings.php
34+
35+
# Array destructuring from getimagesize() which returns false (converted to null by falseToNull)
36+
-
37+
identifier: offsetAccess.nonArray
38+
paths:
39+
- src/Utils/Image.php
1340

14-
# PHPStan does not support RecursiveIteratorIterator proxying unknown method calls to inner iterator
15-
- '#RecursiveIteratorIterator::getSubPathName\(\)#'
41+
# Works with arbitrary PHP callbacks, precise callable types not practical
42+
-
43+
identifier: missingType.callable
44+
paths:
45+
- src/Utils/Callback.php
46+
- src/Utils/Image.php
47+
- src/Utils/Strings.php
1648

17-
# static cannot be changed to maintain backward compatibility
18-
- '#Unsafe usage of new static\(\)#'
49+
includes:
50+
- phpstan-baseline.neon

src/Utils/Arrays.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,8 @@ public static function associate(array $array, string|array $path): array|\stdCl
328328
$x = $row[$parts[$i]];
329329
$row = null;
330330
}
331+
break; // '=' is always the final operation
332+
331333
} elseif ($part === '->') {
332334
if (isset($parts[++$i])) {
333335
if ($x === null) {

src/Utils/Callback.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,18 @@ final class Callback
2828
*/
2929
public static function invokeSafe(string $function, array $args, callable $onError): mixed
3030
{
31-
$prev = set_error_handler(function (int $severity, string $message, string $file, int $line) use ($onError, &$prev, $function): ?bool {
31+
$prev = set_error_handler(function (int $severity, string $message, string $file, int $line) use ($onError, &$prev, $function): bool {
3232
if ($file === __FILE__) {
3333
$msg = ini_get('html_errors')
3434
? Html::htmlToText($message)
3535
: $message;
36-
$msg = preg_replace("#^$function\\(.*?\\): #", '', $msg);
36+
$msg = (string) preg_replace("#^$function\\(.*?\\): #", '', $msg);
3737
if ($onError($msg, $severity) !== false) {
38-
return null;
38+
return true;
3939
}
4040
}
4141

42-
return $prev ? $prev(...func_get_args()) : false;
42+
return $prev ? $prev(...func_get_args()) !== false : false;
4343
});
4444

4545
try {
@@ -103,6 +103,7 @@ public static function toReflection(mixed $callable): \ReflectionMethod|\Reflect
103103
} elseif (is_object($callable) && !$callable instanceof \Closure) {
104104
return new ReflectionMethod($callable, '__invoke');
105105
} else {
106+
assert($callable instanceof \Closure || is_string($callable));
106107
return new \ReflectionFunction($callable);
107108
}
108109
}
@@ -121,7 +122,7 @@ public static function isStatic(callable $callable): bool
121122
* Unwraps closure created by Closure::fromCallable().
122123
* @return callable|array{object|class-string, string}|string
123124
*/
124-
public static function unwrap(\Closure $closure): callable|array
125+
public static function unwrap(\Closure $closure): callable|array|string
125126
{
126127
$r = new \ReflectionFunction($closure);
127128
$class = $r->getClosureScopeClass()?->name;

src/Utils/FileSystem.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ public static function copy(string $origin, string $target, bool $overwrite = tr
5252
} elseif (is_dir($origin)) {
5353
static::createDir($target);
5454
foreach (new \FilesystemIterator($target) as $item) {
55+
\assert($item instanceof \SplFileInfo);
5556
static::delete($item->getPathname());
5657
}
5758

@@ -112,6 +113,7 @@ public static function delete(string $path): void
112113
}
113114
} elseif (is_dir($path)) {
114115
foreach (new \FilesystemIterator($path) as $item) {
116+
\assert($item instanceof \SplFileInfo);
115117
static::delete($item->getPathname());
116118
}
117119

@@ -251,6 +253,7 @@ public static function makeWritable(string $path, int $dirMode = 0o777, int $fil
251253
}
252254
} elseif (is_dir($path)) {
253255
foreach (new \FilesystemIterator($path) as $item) {
256+
\assert($item instanceof \SplFileInfo);
254257
static::makeWritable($item->getPathname(), $dirMode, $fileMode);
255258
}
256259

src/Utils/Finder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ public function size(string $operator, ?int $size = null): static
289289

290290
[, $operator, $size, $unit] = $matches;
291291
$units = ['' => 1, 'k' => 1e3, 'm' => 1e6, 'g' => 1e9];
292-
$size *= $units[strtolower($unit)];
292+
$size = (float) $size * $units[strtolower($unit)];
293293
$operator = $operator ?: '=';
294294
}
295295

0 commit comments

Comments
 (0)