Skip to content

Commit 672e80b

Browse files
authored
Fix static analysis warnings in mixin generator (#328)
1 parent a5bcb48 commit 672e80b

File tree

1 file changed

+33
-38
lines changed

1 file changed

+33
-38
lines changed

bin/src/MixinGenerator.php

Lines changed: 33 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,20 @@
1010
use ReflectionException;
1111
use ReflectionIntersectionType;
1212
use ReflectionMethod;
13+
use ReflectionNamedType;
1314
use ReflectionType;
1415
use ReflectionUnionType;
1516
use RuntimeException;
1617
use Webmozart\Assert\Assert;
1718

18-
use function array_map;
19-
use function implode;
20-
use function rtrim;
21-
2219
final class MixinGenerator
2320
{
2421
/**
2522
* @psalm-var list<string>
2623
*
2724
* @var string[]
2825
*/
29-
private $unsupportedMethods = [
26+
private array $unsupportedMethods = [
3027
'nullOrNotInstanceOf', // not supported by psalm (https://github.com/vimeo/psalm/issues/3443)
3128
'allNotInstanceOf', // not supported by psalm (https://github.com/vimeo/psalm/issues/3443)
3229
'nullOrNotEmpty', // not supported by psalm (https://github.com/vimeo/psalm/issues/3443)
@@ -51,7 +48,7 @@ final class MixinGenerator
5148
*
5249
* @var string[]
5350
*/
54-
private $skipMethods = [
51+
private array $skipMethods = [
5552
'nullOrNull', // meaningless
5653
'nullOrNotNull', // meaningless
5754
'allNullOrNull', // meaningless
@@ -123,7 +120,7 @@ trait Mixin
123120

124121
PHP
125122
,
126-
implode("\n\n", $declaredMethods)
123+
\implode("\n\n", $declaredMethods)
127124
);
128125
}
129126

@@ -224,9 +221,8 @@ private function assertion(ReflectionMethod $method, string $methodNameTemplate,
224221
$parameters[] = $parameterReflection->name;
225222

226223
if ($parameterReflection->isDefaultValueAvailable()) {
227-
/** @var mixed $defaultValue */
228224
$defaultValue = $parameterReflection->getDefaultValue();
229-
Assert::nullOrScalar($defaultValue);
225+
$defaultValue = Assert::nullOrScalar($defaultValue);
230226

231227
$parametersDefaults[$parameterReflection->name] = $defaultValue;
232228
}
@@ -250,7 +246,7 @@ private function assertion(ReflectionMethod $method, string $methodNameTemplate,
250246

251247
$paramsAdded = false;
252248

253-
$nativeReturnType = reset($parameterTypes) ?? 'mixed';
249+
$nativeReturnType = $parameterTypes ? $parameterTypes[\array_key_first($parameterTypes)] : 'mixed';
254250
$phpdocReturnType = 'mixed';
255251

256252
$phpdocLines = [];
@@ -275,10 +271,10 @@ private function assertion(ReflectionMethod $method, string $methodNameTemplate,
275271

276272
foreach ($values as $i => $value) {
277273
$parts = $this->splitDocLine($value);
278-
if (('param' === $key || 'psalm-param' === $key) && isset($parts[1]) && $parts[1] === '$'.$parameters[0] && 'mixed' !== $parts[0]) {
274+
if (('param' === $key || 'psalm-param' === $key) && isset($parts[1]) && isset($parameters[0]) && $parts[1] === '$'.$parameters[0] && 'mixed' !== $parts[0]) {
279275
$parts[0] = $this->applyTypeTemplate($parts[0], $typeTemplate);
280276

281-
$values[$i] = implode(' ', $parts);
277+
$values[$i] = \implode(' ', $parts);
282278
}
283279
}
284280

@@ -301,7 +297,7 @@ private function assertion(ReflectionMethod $method, string $methodNameTemplate,
301297
}
302298

303299
if ('param' === $key) {
304-
if (!array_key_exists(1, $parts)) {
300+
if (!isset($parts[1])) {
305301
throw new RuntimeException(sprintf('param key must come with type and variable name in method: %s', $method->name));
306302
}
307303

@@ -311,7 +307,7 @@ private function assertion(ReflectionMethod $method, string $methodNameTemplate,
311307

312308
$comment = sprintf('@%s %s', $key, $type);
313309
if (count($parts) >= 2) {
314-
$comment .= sprintf(' %s', implode(' ', array_slice($parts, 1)));
310+
$comment .= sprintf(' %s', \implode(' ', array_slice($parts, 1)));
315311
}
316312

317313
$phpdocLines[] = trim($comment);
@@ -344,13 +340,15 @@ private function assertion(ReflectionMethod $method, string $methodNameTemplate,
344340
private function reduceParameterType(ReflectionType $type): string
345341
{
346342
if ($type instanceof ReflectionIntersectionType) {
347-
return implode('&', array_map([$this, 'reduceParameterType'], $type->getTypes()));
343+
return \implode('&', \array_map([$this, 'reduceParameterType'], $type->getTypes()));
348344
}
349345

350346
if ($type instanceof ReflectionUnionType) {
351-
return implode('|', array_map([$this, 'reduceParameterType'], $type->getTypes()));
347+
return \implode('|', \array_map([$this, 'reduceParameterType'], $type->getTypes()));
352348
}
353349

350+
$type = Assert::isInstanceOf($type, ReflectionNamedType::class);
351+
354352
if ($type->getName() === 'mixed') {
355353
return $type->getName();
356354
}
@@ -398,7 +396,7 @@ private function findLongestTypeAndName(array $values): array
398396
$longestType = strlen($type);
399397
}
400398

401-
if (!array_key_exists(1, $parts)) {
399+
if (!isset($parts[1])) {
402400
continue;
403401
}
404402

@@ -415,34 +413,36 @@ private function findLongestTypeAndName(array $values): array
415413
* @psalm-param list<string> $parameters
416414
* @psalm-param array<string, scalar|null> $defaults
417415
* @psalm-param list<string> $phpdocLines
418-
* @psalm-param callable(string,string):string $body
419416
*
420417
* @param string $name
421418
* @param string[] $parameters
422419
* @param array<string, string> $types
423420
* @param string[] $defaults
424421
* @param array $phpdocLines
425422
* @param int $indent
426-
* @param callable $body
423+
* @param callable(string,string): string $body
427424
* @param string $returnType
428425
*
429426
* @return string
430427
*/
431428
private function staticMethod(string $name, array $parameters, array $types, array $defaults, array $phpdocLines, int $indent, callable $body, string $returnType): string
432429
{
430+
Assert::notEmpty($parameters);
431+
433432
$indentation = str_repeat(' ', $indent);
434433

434+
$parameterList = \array_map(static fn (string $parameter): string => '$'.$parameter, $parameters);
435+
$firstParameter = \array_shift($parameterList);
436+
$parameterList = \implode(', ', $parameterList);
437+
438+
$methodBody = \preg_replace('/(?<=^|\n)(?!\n)/', $indentation.$indentation, $body($firstParameter, $parameterList));
439+
440+
Assert::stringNotEmpty($methodBody);
441+
435442
$staticFunction = $this->phpdoc($phpdocLines, $indent)."\n";
436443
$staticFunction .= $indentation.'public static function '.$name.$this->functionParameters($parameters, $types, $defaults).": {$returnType}\n"
437444
.$indentation."{\n";
438-
439-
$firstParameter = '$'.array_shift($parameters);
440-
$parameters = implode(', ', \array_map(static function (string $parameter): string {
441-
return '$'.$parameter;
442-
}, $parameters));
443-
444-
$staticFunction .= preg_replace('/(?<=^|\n)(?!\n)/', $indentation.$indentation, $body($firstParameter, $parameters))."\n";
445-
$staticFunction .= $indentation.'}';
445+
$staticFunction .= $methodBody."\n".$indentation."}";
446446

447447
return $staticFunction;
448448
}
@@ -496,10 +496,10 @@ private function phpdoc(array $lines, int $indent): string
496496
$throws = '';
497497

498498
foreach ($lines as $line) {
499-
if (strpos($line, '@throws') === 0) {
500-
$throws .= "\n".$indentation.rtrim(' * '.$line);
499+
if (\str_starts_with($line, '@throws')) {
500+
$throws .= "\n".$indentation.\rtrim(' * '.$line);
501501
} else {
502-
$phpdoc .= "\n".$indentation.rtrim(' * '.$line);
502+
$phpdoc .= "\n".$indentation.\rtrim(' * '.$line);
503503
}
504504
}
505505

@@ -538,7 +538,7 @@ private function parseDocComment(string $comment): array
538538
}
539539

540540
/**
541-
* @psalm-return array{0: string, 1?: string, 2?: string}
541+
* @psalm-return list{string, string|null, string|null}
542542
*
543543
* @param string $line
544544
*
@@ -547,15 +547,10 @@ private function parseDocComment(string $comment): array
547547
private function splitDocLine(string $line): array
548548
{
549549
if (!preg_match('~^(.*)\s+(\$\S+)(?:\s+(.*))?$~', $line, $matches)) {
550-
return [$line];
551-
}
552-
553-
$parts = [trim($matches[1]), $matches[2]];
554-
if (count($matches) > 3) {
555-
$parts[2] = $matches[3];
550+
return [$line, null, null];
556551
}
557552

558-
return $parts;
553+
return [trim($matches[1]), $matches[2], $matches[3] ?? null];
559554
}
560555

561556
/**

0 commit comments

Comments
 (0)