mirror of
https://github.com/danog/psalm.git
synced 2024-11-27 04:45:20 +01:00
Merge pull request #7133 from AndrolGenhald/remove-unused-suppressed
Allow suppressing UnusedPsalmSuppress, remove unused suppressions.
This commit is contained in:
commit
f79f857ded
@ -16,6 +16,7 @@
|
||||
xsi:schemaLocation="https://getpsalm.org/schema/config config.xsd"
|
||||
limitMethodComplexity="true"
|
||||
errorBaseline="psalm-baseline.xml"
|
||||
findUnusedPsalmSuppress="true"
|
||||
>
|
||||
<stubs>
|
||||
<file name="stubs/phpparser.phpstub"/>
|
||||
|
@ -137,9 +137,6 @@ class CodeLocation
|
||||
$this->docblock_line_number = $line;
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-suppress MixedArrayAccess
|
||||
*/
|
||||
private function calculateRealLocation(): void
|
||||
{
|
||||
if ($this->have_recalculated) {
|
||||
|
@ -850,7 +850,6 @@ class Config
|
||||
/**
|
||||
* @psalm-suppress MixedMethodCall
|
||||
* @psalm-suppress MixedAssignment
|
||||
* @psalm-suppress MixedOperand
|
||||
* @psalm-suppress MixedArgument
|
||||
* @psalm-suppress MixedPropertyFetch
|
||||
*
|
||||
@ -1294,8 +1293,6 @@ class Config
|
||||
|
||||
/**
|
||||
* Initialises all the plugins (done once the config is fully loaded)
|
||||
*
|
||||
* @psalm-suppress MixedAssignment
|
||||
*/
|
||||
public function initializePlugins(ProjectAnalyzer $project_analyzer): void
|
||||
{
|
||||
@ -2065,10 +2062,6 @@ class Config
|
||||
$this->include_collector = $include_collector;
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-suppress MixedAssignment
|
||||
* @psalm-suppress MixedArrayAccess
|
||||
*/
|
||||
public function visitComposerAutoloadFiles(ProjectAnalyzer $project_analyzer, ?Progress $progress = null): void
|
||||
{
|
||||
if ($progress === null) {
|
||||
|
@ -208,7 +208,6 @@ class Creator
|
||||
* @return list<string>
|
||||
* @psalm-suppress MixedAssignment
|
||||
* @psalm-suppress MixedArgument
|
||||
* @psalm-suppress PossiblyUndefinedArrayOffset
|
||||
*/
|
||||
private static function getPsr4Or0Paths(string $current_dir, array $composer_json): array
|
||||
{
|
||||
|
@ -36,9 +36,6 @@ class FileBasedPluginAdapter implements Plugin\PluginEntryPointInterface
|
||||
$this->codebase = $codebase;
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-suppress PossiblyUnusedParam
|
||||
*/
|
||||
public function __invoke(RegistrationInterface $registration, ?SimpleXMLElement $config = null): void
|
||||
{
|
||||
$fq_class_name = $this->getPluginClassForPath($this->path);
|
||||
|
@ -67,7 +67,6 @@ class ReturnTypeAnalyzer
|
||||
* @return false|null
|
||||
*
|
||||
* @psalm-suppress PossiblyUnusedReturnValue unused but seems important
|
||||
* @psalm-suppress ComplexMethod to be refactored
|
||||
*/
|
||||
public static function verifyReturnType(
|
||||
FunctionLike $function,
|
||||
|
@ -55,6 +55,7 @@ use function array_merge;
|
||||
use function array_search;
|
||||
use function count;
|
||||
use function end;
|
||||
use function in_array;
|
||||
use function is_string;
|
||||
use function md5;
|
||||
use function microtime;
|
||||
@ -185,8 +186,12 @@ abstract class FunctionLikeAnalyzer extends SourceAnalyzer
|
||||
$project_analyzer = $this->getProjectAnalyzer();
|
||||
|
||||
if ($codebase->track_unused_suppressions && !isset($storage->suppressed_issues[0])) {
|
||||
foreach ($storage->suppressed_issues as $offset => $issue_name) {
|
||||
IssueBuffer::addUnusedSuppression($this->getFilePath(), $offset, $issue_name);
|
||||
if (count($storage->suppressed_issues) === 1 // UnusedPsalmSuppress by itself should be marked as unused
|
||||
|| !in_array("UnusedPsalmSuppress", $storage->suppressed_issues)
|
||||
) {
|
||||
foreach ($storage->suppressed_issues as $offset => $issue_name) {
|
||||
IssueBuffer::addUnusedSuppression($this->getFilePath(), $offset, $issue_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -683,7 +683,6 @@ class SimpleTypeInferer
|
||||
$array_creation_info->property_types[$new_offset] = $property_value;
|
||||
}
|
||||
} elseif ($unpacked_atomic_type instanceof Type\Atomic\TArray) {
|
||||
/** @psalm-suppress PossiblyUndefinedArrayOffset provably true, but Psalm can’t see it */
|
||||
if ($unpacked_atomic_type->type_params[1]->isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
@ -57,8 +57,10 @@ use function array_combine;
|
||||
use function array_keys;
|
||||
use function array_merge;
|
||||
use function array_search;
|
||||
use function count;
|
||||
use function fwrite;
|
||||
use function get_class;
|
||||
use function in_array;
|
||||
use function is_string;
|
||||
use function preg_split;
|
||||
use function reset;
|
||||
@ -420,18 +422,25 @@ class StatementsAnalyzer extends SourceAnalyzer
|
||||
foreach ($suppressed as $offset => $suppress_entry) {
|
||||
foreach (DocComment::parseSuppressList($suppress_entry) as $issue_offset => $issue_type) {
|
||||
$new_issues[$issue_offset + $offset] = $issue_type;
|
||||
}
|
||||
}
|
||||
|
||||
if ($codebase->track_unused_suppressions
|
||||
&& (
|
||||
(count($new_issues) === 1) // UnusedPsalmSuppress by itself should be marked as unused
|
||||
|| !in_array("UnusedPsalmSuppress", $new_issues)
|
||||
)
|
||||
) {
|
||||
foreach ($new_issues as $offset => $issue_type) {
|
||||
if ($issue_type === 'InaccessibleMethod') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($codebase->track_unused_suppressions) {
|
||||
IssueBuffer::addUnusedSuppression(
|
||||
$statements_analyzer->getFilePath(),
|
||||
$issue_offset + $offset,
|
||||
$issue_type
|
||||
);
|
||||
}
|
||||
IssueBuffer::addUnusedSuppression(
|
||||
$statements_analyzer->getFilePath(),
|
||||
$offset,
|
||||
$issue_type
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,6 @@ final class CliUtils
|
||||
|
||||
$psalm_dir = dirname(__DIR__, 3);
|
||||
|
||||
/** @psalm-suppress UndefinedConstant */
|
||||
$in_phar = Phar::running() || strpos(__NAMESPACE__, 'HumbugBox');
|
||||
|
||||
if ($in_phar) {
|
||||
@ -154,9 +153,7 @@ final class CliUtils
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-suppress MixedArrayAccess
|
||||
* @psalm-suppress MixedAssignment
|
||||
* @psalm-suppress PossiblyUndefinedStringArrayOffset
|
||||
*/
|
||||
public static function getVendorDir(string $current_dir): string
|
||||
{
|
||||
|
@ -338,9 +338,6 @@ class InternalCallMapHandler
|
||||
* Gets the method/function call map
|
||||
*
|
||||
* @return array<string, array<int|string, string>>
|
||||
* @psalm-suppress MixedInferredReturnType as the use of require buggers things up
|
||||
* @psalm-suppress MixedReturnStatement
|
||||
* @psalm-suppress MixedReturnTypeCoercion
|
||||
*/
|
||||
public static function getCallMap(): array
|
||||
{
|
||||
@ -397,7 +394,6 @@ class InternalCallMapHandler
|
||||
* }>,
|
||||
* removed: array<string, array<int|string, string>>
|
||||
* }
|
||||
* @psalm-suppress UnresolvableInclude
|
||||
*/
|
||||
$diff_call_map = require($delta_file);
|
||||
|
||||
|
@ -422,9 +422,6 @@ class Reflection
|
||||
return Type::getMixed();
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-suppress UndefinedClass,TypeDoesNotContainType
|
||||
*/
|
||||
if ($reflection_type instanceof ReflectionNamedType) {
|
||||
$type = $reflection_type->getName();
|
||||
} elseif ($reflection_type instanceof ReflectionUnionType) {
|
||||
|
@ -368,7 +368,9 @@ class Pool
|
||||
// Kill all children
|
||||
foreach ($this->child_pid_list as $child_pid) {
|
||||
/**
|
||||
* @psalm-suppress UndefinedConstant - does not exist on windows
|
||||
* SIGTERM does not exist on windows
|
||||
* @psalm-suppress UnusedPsalmSuppress
|
||||
* @psalm-suppress UndefinedConstant
|
||||
* @psalm-suppress MixedArgument
|
||||
*/
|
||||
posix_kill($child_pid, SIGTERM);
|
||||
@ -422,7 +424,9 @@ class Pool
|
||||
|
||||
if ($process_lookup) {
|
||||
/**
|
||||
* @psalm-suppress UndefinedConstant - does not exist on windows
|
||||
* SIGALRM does not exist on windows
|
||||
* @psalm-suppress UnusedPsalmSuppress
|
||||
* @psalm-suppress UndefinedConstant
|
||||
* @psalm-suppress MixedArgument
|
||||
*/
|
||||
posix_kill($child_pid, SIGALRM);
|
||||
@ -438,7 +442,9 @@ class Pool
|
||||
$term_sig = pcntl_wtermsig($status);
|
||||
|
||||
/**
|
||||
* @psalm-suppress UndefinedConstant - does not exist on windows
|
||||
* SIGALRM does not exist on windows
|
||||
* @psalm-suppress UnusedPsalmSuppress
|
||||
* @psalm-suppress UndefinedConstant
|
||||
*/
|
||||
if ($term_sig !== SIGALRM) {
|
||||
$this->did_have_error = true;
|
||||
|
@ -140,7 +140,6 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher
|
||||
// Invoke the method handler to get a result
|
||||
/**
|
||||
* @var Promise
|
||||
* @psalm-suppress UndefinedDocblockClass
|
||||
*/
|
||||
$dispatched = $this->dispatch($msg->body);
|
||||
/** @psalm-suppress MixedAssignment */
|
||||
|
@ -51,9 +51,6 @@ class ProtocolStreamReader implements ProtocolReader
|
||||
asyncCall(
|
||||
/**
|
||||
* @return Generator<int, Promise<?string>, ?string, void>
|
||||
* @psalm-suppress MixedReturnTypeCoercion
|
||||
* @psalm-suppress MixedArgument in old Amp versions
|
||||
* @psalm-suppress MixedAssignment in old Amp versions
|
||||
*/
|
||||
function () use ($input): Generator {
|
||||
while ($this->is_accepting_new_requests) {
|
||||
@ -119,7 +116,6 @@ class ProtocolStreamReader implements ProtocolReader
|
||||
$this->emit('message', [$msg]);
|
||||
/**
|
||||
* @psalm-suppress DocblockTypeContradiction
|
||||
* @psalm-suppress RedundantConditionGivenDocblockType
|
||||
*/
|
||||
if (!$this->is_accepting_new_requests) {
|
||||
// If we fork, don't read any bytes in the input buffer from the worker process.
|
||||
|
@ -15,10 +15,6 @@ class CheckTrivialExprVisitor extends PhpParser\NodeVisitorAbstract
|
||||
|
||||
private function checkNonTrivialExpr(PhpParser\Node\Expr $node): bool
|
||||
{
|
||||
/**
|
||||
* @psalm-suppress UndefinedClass
|
||||
* @psalm-suppress TypeDoesNotContainType
|
||||
*/
|
||||
if ($node instanceof PhpParser\Node\Expr\ArrayDimFetch
|
||||
|| $node instanceof PhpParser\Node\Expr\Closure
|
||||
|| $node instanceof PhpParser\Node\Expr\ClosureUse
|
||||
|
@ -54,9 +54,6 @@ class OffsetShifterVisitor extends PhpParser\NodeVisitorAbstract
|
||||
$node->setAttribute('comments', $new_comments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-suppress MixedOperand
|
||||
*/
|
||||
$node->setAttribute(
|
||||
'startFilePos',
|
||||
$attrs['startFilePos'] + $this->file_offset + ($this->extra_offsets[$attrs['startFilePos']] ?? 0)
|
||||
|
@ -46,8 +46,6 @@ class ClassLikeDocblockParser
|
||||
{
|
||||
/**
|
||||
* @throws DocblockParseException if there was a problem parsing the docblock
|
||||
*
|
||||
* @psalm-suppress MixedArrayAccess
|
||||
*/
|
||||
public static function parse(
|
||||
Node $node,
|
||||
|
@ -49,9 +49,6 @@ class FakeFileProvider extends FileProvider
|
||||
return $this->fake_file_times[$file_path] ?? parent::getModifiedTime($file_path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-suppress InvalidPropertyAssignmentValue because microtime is needed for cache busting
|
||||
*/
|
||||
public function registerFile(string $file_path, string $file_contents): void
|
||||
{
|
||||
$this->fake_files[$file_path] = $file_contents;
|
||||
|
@ -71,8 +71,6 @@ class ParserCacheProvider
|
||||
|
||||
/**
|
||||
* @return list<PhpParser\Node\Stmt>|null
|
||||
*
|
||||
* @psalm-suppress UndefinedFunction
|
||||
*/
|
||||
public function loadStatementsFromCache(
|
||||
string $file_path,
|
||||
@ -116,8 +114,6 @@ class ParserCacheProvider
|
||||
|
||||
/**
|
||||
* @return list<PhpParser\Node\Stmt>|null
|
||||
*
|
||||
* @psalm-suppress UndefinedFunction
|
||||
*/
|
||||
public function loadExistingStatementsFromCache(string $file_path): ?array
|
||||
{
|
||||
@ -217,9 +213,6 @@ class ParserCacheProvider
|
||||
|
||||
/**
|
||||
* @param list<PhpParser\Node\Stmt> $stmts
|
||||
*
|
||||
*
|
||||
* @psalm-suppress UndefinedFunction
|
||||
*/
|
||||
public function saveStatementsToCache(
|
||||
string $file_path,
|
||||
|
@ -150,7 +150,6 @@ class StatementsProvider
|
||||
|
||||
$existing_statements = $this->parser_cache_provider->loadExistingStatementsFromCache($file_path);
|
||||
|
||||
/** @psalm-suppress DocblockTypeContradiction */
|
||||
if ($existing_statements && !$existing_statements[0] instanceof PhpParser\Node\Stmt) {
|
||||
$existing_statements = null;
|
||||
}
|
||||
|
@ -97,7 +97,6 @@ class TypeTokenizer
|
||||
*
|
||||
* @return list<array{string, int}>
|
||||
*
|
||||
* @psalm-suppress ComplexMethod
|
||||
* @psalm-suppress PossiblyUndefinedIntArrayOffset
|
||||
*/
|
||||
public static function tokenize(string $string_type, bool $ignore_space = true): array
|
||||
|
@ -371,6 +371,24 @@ class IssueSuppressionTest extends TestCase
|
||||
}
|
||||
',
|
||||
],
|
||||
'suppressUnusedSuppression' => [
|
||||
'<?php
|
||||
class Foo {
|
||||
/**
|
||||
* @psalm-suppress UnusedPsalmSuppress, MissingPropertyType
|
||||
*/
|
||||
public string $bar = "baz";
|
||||
|
||||
/**
|
||||
* @psalm-suppress UnusedPsalmSuppress, MissingReturnType
|
||||
*/
|
||||
public function foobar(): string
|
||||
{
|
||||
return "foobar";
|
||||
}
|
||||
}
|
||||
',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
@ -408,6 +426,17 @@ class IssueSuppressionTest extends TestCase
|
||||
function foo($s = Foo::BAR) : void {}',
|
||||
'error_message' => 'UndefinedClass',
|
||||
],
|
||||
'suppressUnusedSuppressionByItselfIsNotSuppressed' => [
|
||||
'<?php
|
||||
class Foo {
|
||||
/**
|
||||
* @psalm-suppress UnusedPsalmSuppress
|
||||
*/
|
||||
public string $bar = "baz";
|
||||
}
|
||||
',
|
||||
'error_message' => 'UnusedPsalmSuppress',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -15,9 +15,6 @@ class TestConfig extends Config
|
||||
/** @var ProjectFileFilter|null */
|
||||
private static $cached_project_files = null;
|
||||
|
||||
/**
|
||||
* @psalm-suppress PossiblyNullPropertyAssignmentValue because cache_directory isn't strictly nullable
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
Loading…
Reference in New Issue
Block a user