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

Fix #2 - suppress errors for single lines

This commit is contained in:
Matt Brown 2017-10-26 18:19:19 -04:00
parent d06e844748
commit 8b7d82ddf6
8 changed files with 237 additions and 1 deletions

View File

@ -33,7 +33,7 @@ class FileChecker extends SourceChecker implements StatementsSource
protected $actual_file_path;
/**
* @var array<string, string>
* @var array<int, string>
*/
protected $suppressed_issues = [];
@ -497,6 +497,26 @@ class FileChecker extends SourceChecker implements StatementsSource
return $this->suppressed_issues;
}
/**
* @param array<int, string> $new_issues
*
* @return void
*/
public function addSuppressedIssues(array $new_issues)
{
$this->suppressed_issues = array_merge($new_issues, $this->suppressed_issues);
}
/**
* @param array<int, string> $new_issues
*
* @return void
*/
public function removeSuppressedIssues(array $new_issues)
{
$this->suppressed_issues = array_diff($this->suppressed_issues, $new_issues);
}
public function getFQCLN()
{
return null;

View File

@ -1321,6 +1321,26 @@ abstract class FunctionLikeChecker extends SourceChecker implements StatementsSo
return $this->suppressed_issues;
}
/**
* @param array<int, string> $new_issues
*
* @return void
*/
public function addSuppressedIssues(array $new_issues)
{
$this->suppressed_issues = array_merge($new_issues, $this->suppressed_issues);
}
/**
* @param array<int, string> $new_issues
*
* @return void
*/
public function removeSuppressedIssues(array $new_issues)
{
$this->suppressed_issues = array_diff($this->suppressed_issues, $new_issues);
}
/**
* Adds a suppressed issue, useful when creating a method checker from scratch
*

View File

@ -161,6 +161,34 @@ abstract class SourceChecker implements StatementsSource
return $this->source->getSuppressedIssues();
}
/**
* @param array<int, string> $new_issues
*
* @return void
*/
public function addSuppressedIssues(array $new_issues)
{
if ($this->source === null) {
throw new \UnexpectedValueException('$source cannot be null');
}
return $this->source->addSuppressedIssues($new_issues);
}
/**
* @param array<int, string> $new_issues
*
* @return void
*/
public function removeSuppressedIssues(array $new_issues)
{
if ($this->source === null) {
throw new \UnexpectedValueException('$source cannot be null');
}
return $this->source->removeSuppressedIssues($new_issues);
}
/**
* @return string
*/

View File

@ -129,6 +129,33 @@ class StatementsChecker extends SourceChecker implements StatementsSource
}
*/
$new_issues = null;
if ($docblock = $stmt->getDocComment()) {
$comments = CommentChecker::parseDocComment((string)$docblock);
if (isset($comments['specials']['psalm-suppress'])) {
$suppressed = array_filter(
array_map(
/**
* @param string $line
*
* @return string
*/
function ($line) {
return explode(' ', trim($line))[0];
},
$comments['specials']['psalm-suppress']
)
);
if ($suppressed) {
$new_issues = array_diff($suppressed, $this->source->getSuppressedIssues());
/** @psalm-suppress TypeCoercion */
$this->addSuppressedIssues($new_issues);
}
}
}
if ($stmt instanceof PhpParser\Node\Stmt\If_) {
IfChecker::analyze($this, $stmt, $context, $loop_context);
} elseif ($stmt instanceof PhpParser\Node\Stmt\TryCatch) {
@ -348,6 +375,11 @@ class StatementsChecker extends SourceChecker implements StatementsSource
return false;
}
}
if ($new_issues) {
/** @psalm-suppress TypeCoercion */
$this->removeSuppressedIssues($new_issues);
}
}
return null;

View File

@ -82,4 +82,18 @@ interface StatementsSource
* @return array<int, string>
*/
public function getSuppressedIssues();
/**
* @param array<int, string> $new_issues
*
* @return void
*/
public function addSuppressedIssues(array $new_issues);
/**
* @param array<int, string> $new_issues
*
* @return void
*/
public function removeSuppressedIssues(array $new_issues);
}

View File

@ -140,4 +140,22 @@ class TraitSource implements StatementsSource
{
return [];
}
/**
* @param array<int, string> $new_issues
*
* @return void
*/
public function addSuppressedIssues(array $new_issues)
{
}
/**
* @param array<int, string> $new_issues
*
* @return void
*/
public function removeSuppressedIssues(array $new_issues)
{
}
}

54
tests/AssertTest.php Normal file
View File

@ -0,0 +1,54 @@
<?php
namespace Psalm\Tests;
class AssertTest extends TestCase
{
use Traits\FileCheckerInvalidCodeParseTestTrait;
use Traits\FileCheckerValidCodeParseTestTrait;
/**
* @return array
*/
public function providerFileCheckerValidCodeParse()
{
return [
'assertInstanceOfB' => [
'<?php
class A {}
class B extends A {
public function foo() : void {}
}
function assertInstanceOfB(A $var) : void {
if (!$var instanceof B) {
throw new \Exception();
}
}
function assertInstanceOfClass(A $var, string $class) : void {
if (!$var instanceof $class) {
throw new \Exception();
}
}
function takesA(A $a) : void {
assertInstanceOfB($a);
$a->foo();
}
function takesA(A $a) : void {
assertInstanceOfB($a);
$a->foo();
}',
],
];
}
/**
* @return array
*/
public function providerFileCheckerInvalidCodeParse()
{
return [];
}
}

View File

@ -4,6 +4,7 @@ namespace Psalm\Tests;
class IssueSuppressionTest extends TestCase
{
use Traits\FileCheckerValidCodeParseTestTrait;
use Traits\FileCheckerInvalidCodeParseTestTrait;
/**
* @return array
@ -24,6 +25,24 @@ class IssueSuppressionTest extends TestCase
}
}',
],
'undefinedClassOneLine' => [
'<?php
class A {
public function b() : void {
/**
* @psalm-suppress UndefinedClass
*/
new B();
}
}',
],
'undefinedClassOneLineInFile' => [
'<?php
/**
* @psalm-suppress UndefinedClass
*/
new B();',
],
'excludeIssue' => [
'<?php
fooFoo();',
@ -32,4 +51,35 @@ class IssueSuppressionTest extends TestCase
],
];
}
/**
* @return array
*/
public function providerFileCheckerInvalidCodeParse()
{
return [
'undefinedClassOneLineWithLineAfter' => [
'<?php
class A {
public function b() {
/**
* @psalm-suppress UndefinedClass
*/
new B();
new C();
}
}',
'error_message' => 'UndefinedClass - src/somefile.php:8 - Class or interface C',
],
'undefinedClassOneLineInFileAfter' => [
'<?php
/**
* @psalm-suppress UndefinedClass
*/
new B();
new C();',
'error_message' => 'UndefinedClass - src/somefile.php:6 - Class or interface C',
],
];
}
}