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:
parent
e3d8ebf612
commit
472ab29d74
@ -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" />
|
||||
|
@ -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" />
|
||||
|
@ -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" />
|
||||
|
@ -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" />
|
||||
|
@ -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" />
|
||||
|
@ -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 it’s possible that the array offset is not applicable to the value you’re trying to access.
|
||||
|
@ -990,7 +990,7 @@ class Config
|
||||
|
||||
$fq_class_name = reset($declared_classes);
|
||||
|
||||
if (!$codebase->classExtends(
|
||||
if (!$codebase->classlikes->classExtends(
|
||||
$fq_class_name,
|
||||
$must_extend
|
||||
)
|
||||
|
@ -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()
|
||||
|
6
src/Psalm/Issue/PossiblyInvalidCast.php
Normal file
6
src/Psalm/Issue/PossiblyInvalidCast.php
Normal file
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
namespace Psalm\Issue;
|
||||
|
||||
class PossiblyInvalidCast extends CodeIssue
|
||||
{
|
||||
}
|
@ -193,7 +193,7 @@ class ToStringTest extends TestCase
|
||||
$a = [];
|
||||
}
|
||||
$b = (string) $a;',
|
||||
'error_message' => 'InvalidCast',
|
||||
'error_message' => 'PossiblyInvalidCast',
|
||||
],
|
||||
'cannotCastInsideString' => [
|
||||
'<?php
|
||||
|
Loading…
Reference in New Issue
Block a user