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

Add PossiblyInvalidCast for more refined checks

This commit is contained in:
Matthew Brown 2019-03-17 17:10:51 -04:00
parent e3d8ebf612
commit 472ab29d74
10 changed files with 50 additions and 3 deletions

View File

@ -65,6 +65,7 @@
<PossiblyInvalidArrayAccess errorLevel="info" />
<PossiblyInvalidArrayAssignment errorLevel="info" />
<PossiblyInvalidArrayOffset errorLevel="info" />
<PossiblyInvalidCast errorLevel="info" />
<PossiblyInvalidFunctionCall errorLevel="info" />
<PossiblyInvalidIterator errorLevel="info" />
<PossiblyInvalidMethodCall errorLevel="info" />

View File

@ -65,6 +65,7 @@
<PossiblyInvalidArrayAccess errorLevel="info" />
<PossiblyInvalidArrayAssignment errorLevel="info" />
<PossiblyInvalidArrayOffset errorLevel="info" />
<PossiblyInvalidCast errorLevel="info" />
<PossiblyInvalidFunctionCall errorLevel="info" />
<PossiblyInvalidIterator errorLevel="info" />
<PossiblyInvalidMethodCall errorLevel="info" />

View File

@ -65,6 +65,7 @@
<PossiblyInvalidArrayAccess errorLevel="info" />
<PossiblyInvalidArrayAssignment errorLevel="info" />
<PossiblyInvalidArrayOffset errorLevel="info" />
<PossiblyInvalidCast errorLevel="info" />
<PossiblyInvalidFunctionCall errorLevel="info" />
<PossiblyInvalidIterator errorLevel="info" />
<PossiblyInvalidMethodCall errorLevel="info" />

View File

@ -65,6 +65,7 @@
<PossiblyInvalidArrayAccess errorLevel="info" />
<PossiblyInvalidArrayAssignment errorLevel="info" />
<PossiblyInvalidArrayOffset errorLevel="info" />
<PossiblyInvalidCast errorLevel="info" />
<PossiblyInvalidFunctionCall errorLevel="info" />
<PossiblyInvalidIterator errorLevel="info" />
<PossiblyInvalidMethodCall errorLevel="info" />

View File

@ -261,6 +261,7 @@
<xs:element name="PossiblyInvalidArrayAccess" type="IssueHandlerType" minOccurs="0" />
<xs:element name="PossiblyInvalidArrayAssignment" type="IssueHandlerType" minOccurs="0" />
<xs:element name="PossiblyInvalidArrayOffset" type="IssueHandlerType" minOccurs="0" />
<xs:element name="PossiblyInvalidCast" type="IssueHandlerType" minOccurs="0" />
<xs:element name="PossiblyInvalidFunctionCall" type="IssueHandlerType" minOccurs="0" />
<xs:element name="PossiblyInvalidIterator" type="IssueHandlerType" minOccurs="0" />
<xs:element name="PossiblyInvalidMethodCall" type="IssueHandlerType" minOccurs="0" />

View File

@ -1464,6 +1464,20 @@ $arr = rand(0, 1) ? 5 : [4, 3, 2, 1];
$arr[0] = "hello";
```
### PossiblyInvalidCast
Emitted when attempting to cast a value that may not be castable
```php
class A {}
class B {
public function __toString() {
return 'hello';
}
}
$c = (string) (rand(0, 1) ? new A() : new B());
```
### PossiblyInvalidArrayOffset
Emitted when its possible that the array offset is not applicable to the value youre trying to access.

View File

@ -990,7 +990,7 @@ class Config
$fq_class_name = reset($declared_classes);
if (!$codebase->classExtends(
if (!$codebase->classlikes->classExtends(
$fq_class_name,
$must_extend
)

View File

@ -35,6 +35,7 @@ use Psalm\Issue\ForbiddenCode;
use Psalm\Issue\InvalidCast;
use Psalm\Issue\InvalidClone;
use Psalm\Issue\InvalidDocblock;
use Psalm\Issue\PossiblyInvalidCast;
use Psalm\Issue\PossiblyUndefinedVariable;
use Psalm\Issue\UndefinedConstant;
use Psalm\Issue\UndefinedVariable;
@ -1473,6 +1474,9 @@ class ExpressionAnalyzer
return;
}
$has_valid_cast = false;
$invalid_casts = [];
foreach ($stmt->inferredType->getTypes() as $atomic_type) {
if (!$atomic_type instanceof TMixed
&& !$atomic_type instanceof Type\Atomic\TResource
@ -1487,9 +1491,27 @@ class ExpressionAnalyzer
)
&& !$has_scalar_match
) {
$invalid_casts[] = $atomic_type->getId();
} else {
$has_valid_cast = true;
}
}
if ($invalid_casts) {
if ($has_valid_cast) {
if (IssueBuffer::accepts(
new PossiblyInvalidCast(
$invalid_casts[0] . ' cannot be cast to string',
new CodeLocation($statements_analyzer->getSource(), $stmt)
),
$statements_analyzer->getSuppressedIssues()
)) {
// fall through
}
} else {
if (IssueBuffer::accepts(
new InvalidCast(
$atomic_type->getId() . ' cannot be cast to string',
$invalid_casts[0] . ' cannot be cast to string',
new CodeLocation($statements_analyzer->getSource(), $stmt)
),
$statements_analyzer->getSuppressedIssues()

View File

@ -0,0 +1,6 @@
<?php
namespace Psalm\Issue;
class PossiblyInvalidCast extends CodeIssue
{
}

View File

@ -193,7 +193,7 @@ class ToStringTest extends TestCase
$a = [];
}
$b = (string) $a;',
'error_message' => 'InvalidCast',
'error_message' => 'PossiblyInvalidCast',
],
'cannotCastInsideString' => [
'<?php