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

Detect erroneous abstract static method calls

This commit is contained in:
Matthew Brown 2020-03-11 10:18:40 -04:00
parent d2950af636
commit 0d62fbdf98
5 changed files with 48 additions and 0 deletions

View File

@ -157,6 +157,7 @@
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="PluginIssue" type="PluginIssueHandlerType" minOccurs="0" />
<xs:element name="AbstractInstantiation" type="IssueHandlerType" minOccurs="0" />
<xs:element name="AbstractMethodCall" type="IssueHandlerType" minOccurs="0" />
<xs:element name="ArgumentTypeCoercion" type="ArgumentIssueHandlerType" minOccurs="0" />
<xs:element name="AssignmentToVoid" type="IssueHandlerType" minOccurs="0" />
<xs:element name="CircularReference" type="IssueHandlerType" minOccurs="0" />

View File

@ -9,6 +9,18 @@ abstract class A {}
new A();
```
### AbstractMethodCall
Emitted when an attempt is made to call an abstract method
```php
abstract class Base {
abstract static function bar() : void;
}
Base::bar();
```
### ArgumentTypeCoercion
Emitted when calling a function with an argument which has a less specific type than the function expects

View File

@ -10,6 +10,7 @@ use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\FileManipulation\FileManipulationBuffer;
use Psalm\Issue\AbstractMethodCall;
use Psalm\Issue\DeprecatedClass;
use Psalm\Issue\ImpureMethodCall;
use Psalm\Issue\InvalidStringClass;
@ -952,6 +953,20 @@ class StaticCallAnalyzer extends \Psalm\Internal\Analyzer\Statements\Expression\
$method_storage = $codebase->methods->getUserMethodStorage($method_id);
if ($method_storage) {
if ($method_storage->abstract) {
if (IssueBuffer::accepts(
new AbstractMethodCall(
'Cannot call an abstract method ' . $method_id,
new CodeLocation($statements_analyzer->getSource(), $stmt)
),
$statements_analyzer->getSuppressedIssues()
)) {
// fall through
}
return;
}
if ($context->pure && !$method_storage->pure) {
if (IssueBuffer::accepts(
new ImpureMethodCall(

View File

@ -0,0 +1,7 @@
<?php
namespace Psalm\Issue;
class AbstractMethodCall extends CodeIssue
{
const ERROR_LEVEL = -1;
}

View File

@ -871,6 +871,19 @@ class MethodCallTest extends TestCase
}',
'error_message' => 'InvalidStringClass',
],
'preventAbstractMethodCall' => [
'<?php
abstract class Base {
public static function callAbstract() : void {
static::bar();
}
abstract static function bar() : void;
}
Base::bar();',
'error_message' => 'AbstractMethodCall',
],
];
}
}