1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-30 04:39:00 +01:00

Report unused baseline entries

This commit is contained in:
Jack Worman 2023-01-17 19:30:43 -05:00
parent b6bdc94070
commit 56f6dfecc8
13 changed files with 90 additions and 6 deletions

View File

@ -44,6 +44,8 @@
<xs:attribute name="findUnusedCode" type="xs:boolean" default="false" /> <xs:attribute name="findUnusedCode" type="xs:boolean" default="false" />
<xs:attribute name="findUnusedVariablesAndParams" type="xs:boolean" default="false" /> <xs:attribute name="findUnusedVariablesAndParams" type="xs:boolean" default="false" />
<xs:attribute name="findUnusedPsalmSuppress" type="xs:boolean" default="false" /> <xs:attribute name="findUnusedPsalmSuppress" type="xs:boolean" default="false" />
<!-- TODO: Update default to true in Psalm 6 -->
<xs:attribute name="findUnusedBaselineEntry" type="xs:boolean" default="false" />
<xs:attribute name="hideExternalErrors" type="xs:boolean" default="false" /> <xs:attribute name="hideExternalErrors" type="xs:boolean" default="false" />
<xs:attribute name="hoistConstants" type="xs:boolean" default="false" /> <xs:attribute name="hoistConstants" type="xs:boolean" default="false" />
<xs:attribute name="ignoreInternalFunctionFalseReturn" type="xs:boolean" default="true" /> <xs:attribute name="ignoreInternalFunctionFalseReturn" type="xs:boolean" default="true" />
@ -476,6 +478,7 @@
<xs:element name="UnsafeGenericInstantiation" type="IssueHandlerType" minOccurs="0" /> <xs:element name="UnsafeGenericInstantiation" type="IssueHandlerType" minOccurs="0" />
<xs:element name="UnsafeInstantiation" type="IssueHandlerType" minOccurs="0" /> <xs:element name="UnsafeInstantiation" type="IssueHandlerType" minOccurs="0" />
<xs:element name="UnsupportedReferenceUsage" type="IssueHandlerType" minOccurs="0" /> <xs:element name="UnsupportedReferenceUsage" type="IssueHandlerType" minOccurs="0" />
<xs:element name="UnusedBaselineEntry" type="IssueHandlerType" minOccurs="0" />
<xs:element name="UnusedClass" type="ClassIssueHandlerType" minOccurs="0" /> <xs:element name="UnusedClass" type="ClassIssueHandlerType" minOccurs="0" />
<xs:element name="UnusedClosureParam" type="IssueHandlerType" minOccurs="0" /> <xs:element name="UnusedClosureParam" type="IssueHandlerType" minOccurs="0" />
<xs:element name="UnusedConstructor" type="MethodIssueHandlerType" minOccurs="0" /> <xs:element name="UnusedConstructor" type="MethodIssueHandlerType" minOccurs="0" />

View File

@ -491,6 +491,10 @@ class PremiumCar extends StandardCar {
``` ```
`ImplementedReturnTypeMismatch - The inherited return type 'list{'motor', 'brakes', 'wheels'}' for StandardCar::getSystems is different to the implemented return type for PremiumCar::getsystems 'list{'motor', 'brakes', 'wheels', 'rear parking sensor'}'` `ImplementedReturnTypeMismatch - The inherited return type 'list{'motor', 'brakes', 'wheels'}' for StandardCar::getSystems is different to the implemented return type for PremiumCar::getsystems 'list{'motor', 'brakes', 'wheels', 'rear parking sensor'}'`
#### findUnusedBaselineEntry
Emits [UnusedBaselineEntry](issues/UnusedBaselineEntry.md) when a baseline entry
is not being used to suppress an issue.
## Project settings ## Project settings

View File

@ -282,6 +282,7 @@
- [UnsafeGenericInstantiation](issues/UnsafeGenericInstantiation.md) - [UnsafeGenericInstantiation](issues/UnsafeGenericInstantiation.md)
- [UnsafeInstantiation](issues/UnsafeInstantiation.md) - [UnsafeInstantiation](issues/UnsafeInstantiation.md)
- [UnsupportedReferenceUsage](issues/UnsupportedReferenceUsage.md) - [UnsupportedReferenceUsage](issues/UnsupportedReferenceUsage.md)
- [UnusedBaselineEntry](issues/UnusedBaselineEntry.md)
- [UnusedClass](issues/UnusedClass.md) - [UnusedClass](issues/UnusedClass.md)
- [UnusedClosureParam](issues/UnusedClosureParam.md) - [UnusedClosureParam](issues/UnusedClosureParam.md)
- [UnusedConstructor](issues/UnusedConstructor.md) - [UnusedConstructor](issues/UnusedConstructor.md)

View File

@ -0,0 +1,22 @@
# UnusedBaselineEntry
Emitted when a baseline entry is not being used to suppress an issue.
Enabled by [findUnusedBaselineEntry](../configuration.md#findunusedbaselineentry)
```php
<?php
$a = 'Hello, World!';
echo $a;
```
```xml
<?xml version="1.0" encoding="UTF-8"?>
<files>
<file src="example.php">
<UnusedVariable>
<!-- The following entry is unused and should be removed. -->
<code>$a</code>
</UnusedVariable>
</file>
</files>
```

View File

@ -701,11 +701,6 @@
<code>hasLowercaseString</code> <code>hasLowercaseString</code>
</PossiblyUnusedMethod> </PossiblyUnusedMethod>
</file> </file>
<file src="tests/Internal/Codebase/InternalCallMapHandlerTest.php">
<UnusedPsalmSuppress>
<code>UndefinedMethod</code>
</UnusedPsalmSuppress>
</file>
<file src="vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ArrowFunction.php"> <file src="vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ArrowFunction.php">
<PossiblyUndefinedStringArrayOffset> <PossiblyUndefinedStringArrayOffset>
<code>$subNodes['expr']</code> <code>$subNodes['expr']</code>

View File

@ -12,6 +12,7 @@
limitMethodComplexity="true" limitMethodComplexity="true"
errorBaseline="psalm-baseline.xml" errorBaseline="psalm-baseline.xml"
findUnusedPsalmSuppress="true" findUnusedPsalmSuppress="true"
findUnusedBaselineEntry="true"
> >
<stubs> <stubs>
<file name="stubs/phpparser.phpstub"/> <file name="stubs/phpparser.phpstub"/>

View File

@ -460,6 +460,11 @@ class Config
*/ */
public $find_unused_psalm_suppress = false; public $find_unused_psalm_suppress = false;
/**
* TODO: Psalm 6: Update default to be true and remove warning.
*/
public bool $find_unused_baseline_entry = false;
/** /**
* @var bool * @var bool
*/ */
@ -1061,6 +1066,7 @@ class Config
'allowInternalNamedArgumentsCalls' => 'allow_internal_named_arg_calls', 'allowInternalNamedArgumentsCalls' => 'allow_internal_named_arg_calls',
'allowNamedArgumentCalls' => 'allow_named_arg_calls', 'allowNamedArgumentCalls' => 'allow_named_arg_calls',
'findUnusedPsalmSuppress' => 'find_unused_psalm_suppress', 'findUnusedPsalmSuppress' => 'find_unused_psalm_suppress',
'findUnusedBaselineEntry' => 'find_unused_baseline_entry',
'reportInfo' => 'report_info', 'reportInfo' => 'report_info',
'restrictReturnTypes' => 'restrict_return_types', 'restrictReturnTypes' => 'restrict_return_types',
'limitMethodComplexity' => 'limit_method_complexity', 'limitMethodComplexity' => 'limit_method_complexity',
@ -1164,6 +1170,10 @@ class Config
$config->use_igbinary = version_compare($igbinary_version, '2.0.5') >= 0; $config->use_igbinary = version_compare($igbinary_version, '2.0.5') >= 0;
} }
if (!isset($config_xml['findUnusedBaselineEntry']) && !defined('__IS_TEST_ENV__')) {
fwrite(STDERR, 'Warning: "findUnusedBaselineEntry" will be defaulted to "true" in Psalm 6. You should'
. ' explicitly enable or disable this setting.' . PHP_EOL);
}
if (isset($config_xml['findUnusedCode'])) { if (isset($config_xml['findUnusedCode'])) {
$attribute_text = (string) $config_xml['findUnusedCode']; $attribute_text = (string) $config_xml['findUnusedCode'];

View File

@ -45,6 +45,7 @@ final class Creator
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config" xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
findUnusedBaselineEntry="true"
> >
<projectFiles> <projectFiles>
<directory name="src" /> <directory name="src" />

View File

@ -0,0 +1,11 @@
<?php
declare(strict_types=1);
namespace Psalm\Issue;
class UnusedBaselineEntry extends ClassIssue
{
public const ERROR_LEVEL = -1;
public const SHORTCODE = 316;
}

View File

@ -14,6 +14,7 @@ use Psalm\Issue\CodeIssue;
use Psalm\Issue\ConfigIssue; use Psalm\Issue\ConfigIssue;
use Psalm\Issue\MixedIssue; use Psalm\Issue\MixedIssue;
use Psalm\Issue\TaintedInput; use Psalm\Issue\TaintedInput;
use Psalm\Issue\UnusedBaselineEntry;
use Psalm\Issue\UnusedPsalmSuppress; use Psalm\Issue\UnusedPsalmSuppress;
use Psalm\Plugin\EventHandler\Event\AfterAnalysisEvent; use Psalm\Plugin\EventHandler\Event\AfterAnalysisEvent;
use Psalm\Plugin\EventHandler\Event\BeforeAddIssueEvent; use Psalm\Plugin\EventHandler\Event\BeforeAddIssueEvent;
@ -611,6 +612,39 @@ final class IssueBuffer
$issues_data[$file_path][$key] = $issue_data; $issues_data[$file_path][$key] = $issue_data;
} }
} }
if ($codebase->config->find_unused_baseline_entry) {
foreach ($issue_baseline as $file_path => $issues) {
foreach ($issues as $issue_name => $issue) {
if ($issue['o'] !== 0) {
$issues_data[$file_path][] = new IssueData(
Config::REPORT_ERROR,
0,
0,
UnusedBaselineEntry::getIssueType(),
sprintf(
'Baseline for issue "%s" has %d extra %s.',
$issue_name,
$issue['o'],
$issue['o'] === 1 ? 'entry' : 'entries',
),
$file_path,
'',
'',
'',
0,
0,
0,
0,
0,
0,
UnusedBaselineEntry::SHORTCODE,
UnusedBaselineEntry::ERROR_LEVEL,
);
}
}
}
}
} }
} }

View File

@ -38,6 +38,7 @@ class CreatorTest extends TestCase
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config" xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
findUnusedBaselineEntry="true"
> >
<projectFiles> <projectFiles>
<directory name="lib" /> <directory name="lib" />

View File

@ -15,6 +15,7 @@ use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Internal\Provider\FakeFileProvider; use Psalm\Internal\Provider\FakeFileProvider;
use Psalm\Internal\Provider\Providers; use Psalm\Internal\Provider\Providers;
use Psalm\Internal\RuntimeCaches; use Psalm\Internal\RuntimeCaches;
use Psalm\Issue\UnusedBaselineEntry;
use Psalm\Tests\Internal\Provider\FakeParserCacheProvider; use Psalm\Tests\Internal\Provider\FakeParserCacheProvider;
use UnexpectedValueException; use UnexpectedValueException;
@ -262,6 +263,7 @@ class DocumentationTest extends TestCase
case 'RedundantIdentityWithTrue': case 'RedundantIdentityWithTrue':
case 'TraitMethodSignatureMismatch': case 'TraitMethodSignatureMismatch':
case 'UncaughtThrowInGlobalScope': case 'UncaughtThrowInGlobalScope':
case UnusedBaselineEntry::getIssueType():
continue 2; continue 2;
/** @todo reinstate this test when the issue is restored */ /** @todo reinstate this test when the issue is restored */

View File

@ -1395,7 +1395,6 @@ class InternalCallMapHandlerTest extends TestCase
} }
} }
/** @psalm-suppress UndefinedMethod */
public function assertEntryReturnType(ReflectionFunctionAbstract $function, string $entryReturnType): void public function assertEntryReturnType(ReflectionFunctionAbstract $function, string $entryReturnType): void
{ {
if (version_compare(PHP_VERSION, '8.1.0', '>=')) { if (version_compare(PHP_VERSION, '8.1.0', '>=')) {