1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-26 20:34:47 +01:00

Merge pull request #9314 from weirdan/flag-unused-docblock-params

Flag docblock parameters that have no counterparts in function signature
This commit is contained in:
Bruce Weirdan 2023-02-15 22:31:41 -04:00 committed by GitHub
commit f70f6517a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 53 additions and 10 deletions

View File

@ -484,6 +484,7 @@
<xs:element name="UnusedClass" type="ClassIssueHandlerType" minOccurs="0" />
<xs:element name="UnusedClosureParam" type="IssueHandlerType" minOccurs="0" />
<xs:element name="UnusedConstructor" type="MethodIssueHandlerType" minOccurs="0" />
<xs:element name="UnusedDocblockParam" type="IssueHandlerType" minOccurs="0" />
<xs:element name="UnusedForeachValue" type="IssueHandlerType" minOccurs="0" />
<xs:element name="UnusedFunctionCall" type="FunctionIssueHandlerType" minOccurs="0" />
<xs:element name="UnusedMethod" type="MethodIssueHandlerType" minOccurs="0" />

View File

@ -302,6 +302,7 @@ Level 5 and above allows a more non-verifiable code, and higher levels are even
- [UnusedClass](issues/UnusedClass.md)
- [UnusedClosureParam](issues/UnusedClosureParam.md)
- [UnusedConstructor](issues/UnusedConstructor.md)
- [UnusedDocblockParam](issues/UnusedDocblockParam.md)
- [UnusedForeachValue](issues/UnusedForeachValue.md)
- [UnusedMethod](issues/UnusedMethod.md)
- [UnusedParam](issues/UnusedParam.md)

View File

@ -288,6 +288,7 @@
- [UnusedClass](issues/UnusedClass.md)
- [UnusedClosureParam](issues/UnusedClosureParam.md)
- [UnusedConstructor](issues/UnusedConstructor.md)
- [UnusedDocblockParam](issues/UnusedDocblockParam.md)
- [UnusedForeachValue](issues/UnusedForeachValue.md)
- [UnusedFunctionCall](issues/UnusedFunctionCall.md)
- [UnusedMethod](issues/UnusedMethod.md)

View File

@ -0,0 +1,14 @@
# UnusedDocblockParam
Emitted when `--find-dead-code` is turned on and a parameter specified in docblock does not have a corresponding parameter in function / method signature.
```php
<?php
/**
* @param string $legacy_param was renamed to $newParam
*/
function f(string $newParam): string {
return strtolower($newParam);
}
```

View File

@ -42,6 +42,7 @@ use Psalm\Issue\ReferenceConstraintViolation;
use Psalm\Issue\ReservedWord;
use Psalm\Issue\UnresolvableConstant;
use Psalm\Issue\UnusedClosureParam;
use Psalm\Issue\UnusedDocblockParam;
use Psalm\Issue\UnusedParam;
use Psalm\IssueBuffer;
use Psalm\Plugin\EventHandler\Event\AfterFunctionLikeAnalysisEvent;
@ -361,14 +362,22 @@ abstract class FunctionLikeAnalyzer extends SourceAnalyzer
$context->external_mutation_free = true;
}
if ($storage->has_undertyped_native_parameters) {
foreach ($storage->unused_docblock_parameters as $param_name => $param_location) {
foreach ($storage->unused_docblock_parameters as $param_name => $param_location) {
if ($storage->has_undertyped_native_parameters) {
IssueBuffer::maybeAdd(
new InvalidDocblockParamName(
'Incorrect param name $' . $param_name . ' in docblock for ' . $cased_method_id,
$param_location,
),
);
} elseif ($codebase->find_unused_code) {
IssueBuffer::maybeAdd(
new UnusedDocblockParam(
'Docblock parameter $' . $param_name . ' in docblock for ' . $cased_method_id
. ' does not have a counterpart in signature parameter list',
$param_location,
),
);
}
}

View File

@ -104,7 +104,6 @@ class TypeParser
* Parses a string type representation
*
* @param list<array{0: string, 1: int, 2?: string}> $type_tokens
* @param array{int,int}|null $php_version
* @param array<string, array<string, Union>> $template_type_map
* @param array<string, TypeAlias> $type_aliases
*/
@ -716,7 +715,7 @@ class TypeParser
throw new TypeParseTreeException('Class string param should be a named object');
}
$types []= new TClassString($type->value, $type, false, false, false, $from_docblock);
$types[] = new TClassString($type->value, $type, false, false, false, $from_docblock);
}
return new Union($types);
@ -1452,7 +1451,7 @@ class TypeParser
|| ($had_optional && !$property_maybe_undefined)
|| $type === 'array'
|| $type === 'callable-array'
|| $previous_property_key != ($property_key-1)
|| $previous_property_key != ($property_key - 1)
)
) {
$is_list = false;

View File

@ -0,0 +1,9 @@
<?php
namespace Psalm\Issue;
final class UnusedDocblockParam extends CodeIssue
{
public const ERROR_LEVEL = -2;
public const SHORTCODE = 319;
}

View File

@ -70,7 +70,6 @@ abstract class Type
/**
* Parses a string type representation
*
* @param array{int,int}|null $php_version
* @param array<string, array<string, Union>> $template_type_map
*/
public static function parseString(
@ -905,8 +904,8 @@ abstract class Type
if ($intersection_atomic === null || $wider_type === null) {
throw new LogicException(
'$intersection_atomic and $wider_type should be both set or null.'
.' Check the preceding code for errors.'
.' Did you forget to assign one of the variables?',
. ' Check the preceding code for errors.'
. ' Did you forget to assign one of the variables?',
);
}
if (!self::mayHaveIntersection($intersection_atomic, $codebase)
@ -914,7 +913,7 @@ abstract class Type
) {
throw new LogicException(
'$intersection_atomic and $wider_type should be both support intersection.'
.' Check the preceding code for errors.',
. ' Check the preceding code for errors.',
);
}

View File

@ -1757,7 +1757,7 @@ class UnusedCodeTest extends TestCase
'exitInlineHtml' => [
'code' => '<?php
exit(0);
?'.'>foo
?' . '>foo
',
'error_message' => 'UnevaluatedCode',
],
@ -1836,6 +1836,16 @@ class UnusedCodeTest extends TestCase
PHP,
'error_message' => 'PossiblyUnusedParam',
],
'unused param tag' => [
'code' => <<<'PHP'
<?php
/**
* @param string $param
*/
function f(): void {}
PHP,
'error_message' => 'UnusedDocblockParam',
],
];
}
}