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" />
|
<PossiblyInvalidArrayAccess errorLevel="info" />
|
||||||
<PossiblyInvalidArrayAssignment errorLevel="info" />
|
<PossiblyInvalidArrayAssignment errorLevel="info" />
|
||||||
<PossiblyInvalidArrayOffset errorLevel="info" />
|
<PossiblyInvalidArrayOffset errorLevel="info" />
|
||||||
|
<PossiblyInvalidCast errorLevel="info" />
|
||||||
<PossiblyInvalidFunctionCall errorLevel="info" />
|
<PossiblyInvalidFunctionCall errorLevel="info" />
|
||||||
<PossiblyInvalidIterator errorLevel="info" />
|
<PossiblyInvalidIterator errorLevel="info" />
|
||||||
<PossiblyInvalidMethodCall errorLevel="info" />
|
<PossiblyInvalidMethodCall errorLevel="info" />
|
||||||
|
@ -65,6 +65,7 @@
|
|||||||
<PossiblyInvalidArrayAccess errorLevel="info" />
|
<PossiblyInvalidArrayAccess errorLevel="info" />
|
||||||
<PossiblyInvalidArrayAssignment errorLevel="info" />
|
<PossiblyInvalidArrayAssignment errorLevel="info" />
|
||||||
<PossiblyInvalidArrayOffset errorLevel="info" />
|
<PossiblyInvalidArrayOffset errorLevel="info" />
|
||||||
|
<PossiblyInvalidCast errorLevel="info" />
|
||||||
<PossiblyInvalidFunctionCall errorLevel="info" />
|
<PossiblyInvalidFunctionCall errorLevel="info" />
|
||||||
<PossiblyInvalidIterator errorLevel="info" />
|
<PossiblyInvalidIterator errorLevel="info" />
|
||||||
<PossiblyInvalidMethodCall errorLevel="info" />
|
<PossiblyInvalidMethodCall errorLevel="info" />
|
||||||
|
@ -65,6 +65,7 @@
|
|||||||
<PossiblyInvalidArrayAccess errorLevel="info" />
|
<PossiblyInvalidArrayAccess errorLevel="info" />
|
||||||
<PossiblyInvalidArrayAssignment errorLevel="info" />
|
<PossiblyInvalidArrayAssignment errorLevel="info" />
|
||||||
<PossiblyInvalidArrayOffset errorLevel="info" />
|
<PossiblyInvalidArrayOffset errorLevel="info" />
|
||||||
|
<PossiblyInvalidCast errorLevel="info" />
|
||||||
<PossiblyInvalidFunctionCall errorLevel="info" />
|
<PossiblyInvalidFunctionCall errorLevel="info" />
|
||||||
<PossiblyInvalidIterator errorLevel="info" />
|
<PossiblyInvalidIterator errorLevel="info" />
|
||||||
<PossiblyInvalidMethodCall errorLevel="info" />
|
<PossiblyInvalidMethodCall errorLevel="info" />
|
||||||
|
@ -65,6 +65,7 @@
|
|||||||
<PossiblyInvalidArrayAccess errorLevel="info" />
|
<PossiblyInvalidArrayAccess errorLevel="info" />
|
||||||
<PossiblyInvalidArrayAssignment errorLevel="info" />
|
<PossiblyInvalidArrayAssignment errorLevel="info" />
|
||||||
<PossiblyInvalidArrayOffset errorLevel="info" />
|
<PossiblyInvalidArrayOffset errorLevel="info" />
|
||||||
|
<PossiblyInvalidCast errorLevel="info" />
|
||||||
<PossiblyInvalidFunctionCall errorLevel="info" />
|
<PossiblyInvalidFunctionCall errorLevel="info" />
|
||||||
<PossiblyInvalidIterator errorLevel="info" />
|
<PossiblyInvalidIterator errorLevel="info" />
|
||||||
<PossiblyInvalidMethodCall errorLevel="info" />
|
<PossiblyInvalidMethodCall errorLevel="info" />
|
||||||
|
@ -261,6 +261,7 @@
|
|||||||
<xs:element name="PossiblyInvalidArrayAccess" type="IssueHandlerType" minOccurs="0" />
|
<xs:element name="PossiblyInvalidArrayAccess" type="IssueHandlerType" minOccurs="0" />
|
||||||
<xs:element name="PossiblyInvalidArrayAssignment" type="IssueHandlerType" minOccurs="0" />
|
<xs:element name="PossiblyInvalidArrayAssignment" type="IssueHandlerType" minOccurs="0" />
|
||||||
<xs:element name="PossiblyInvalidArrayOffset" 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="PossiblyInvalidFunctionCall" type="IssueHandlerType" minOccurs="0" />
|
||||||
<xs:element name="PossiblyInvalidIterator" type="IssueHandlerType" minOccurs="0" />
|
<xs:element name="PossiblyInvalidIterator" type="IssueHandlerType" minOccurs="0" />
|
||||||
<xs:element name="PossiblyInvalidMethodCall" 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";
|
$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
|
### PossiblyInvalidArrayOffset
|
||||||
|
|
||||||
Emitted when it’s possible that the array offset is not applicable to the value you’re trying to access.
|
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);
|
$fq_class_name = reset($declared_classes);
|
||||||
|
|
||||||
if (!$codebase->classExtends(
|
if (!$codebase->classlikes->classExtends(
|
||||||
$fq_class_name,
|
$fq_class_name,
|
||||||
$must_extend
|
$must_extend
|
||||||
)
|
)
|
||||||
|
@ -35,6 +35,7 @@ use Psalm\Issue\ForbiddenCode;
|
|||||||
use Psalm\Issue\InvalidCast;
|
use Psalm\Issue\InvalidCast;
|
||||||
use Psalm\Issue\InvalidClone;
|
use Psalm\Issue\InvalidClone;
|
||||||
use Psalm\Issue\InvalidDocblock;
|
use Psalm\Issue\InvalidDocblock;
|
||||||
|
use Psalm\Issue\PossiblyInvalidCast;
|
||||||
use Psalm\Issue\PossiblyUndefinedVariable;
|
use Psalm\Issue\PossiblyUndefinedVariable;
|
||||||
use Psalm\Issue\UndefinedConstant;
|
use Psalm\Issue\UndefinedConstant;
|
||||||
use Psalm\Issue\UndefinedVariable;
|
use Psalm\Issue\UndefinedVariable;
|
||||||
@ -1473,6 +1474,9 @@ class ExpressionAnalyzer
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$has_valid_cast = false;
|
||||||
|
$invalid_casts = [];
|
||||||
|
|
||||||
foreach ($stmt->inferredType->getTypes() as $atomic_type) {
|
foreach ($stmt->inferredType->getTypes() as $atomic_type) {
|
||||||
if (!$atomic_type instanceof TMixed
|
if (!$atomic_type instanceof TMixed
|
||||||
&& !$atomic_type instanceof Type\Atomic\TResource
|
&& !$atomic_type instanceof Type\Atomic\TResource
|
||||||
@ -1487,9 +1491,27 @@ class ExpressionAnalyzer
|
|||||||
)
|
)
|
||||||
&& !$has_scalar_match
|
&& !$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(
|
if (IssueBuffer::accepts(
|
||||||
new InvalidCast(
|
new InvalidCast(
|
||||||
$atomic_type->getId() . ' cannot be cast to string',
|
$invalid_casts[0] . ' cannot be cast to string',
|
||||||
new CodeLocation($statements_analyzer->getSource(), $stmt)
|
new CodeLocation($statements_analyzer->getSource(), $stmt)
|
||||||
),
|
),
|
||||||
$statements_analyzer->getSuppressedIssues()
|
$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 = [];
|
$a = [];
|
||||||
}
|
}
|
||||||
$b = (string) $a;',
|
$b = (string) $a;',
|
||||||
'error_message' => 'InvalidCast',
|
'error_message' => 'PossiblyInvalidCast',
|
||||||
],
|
],
|
||||||
'cannotCastInsideString' => [
|
'cannotCastInsideString' => [
|
||||||
'<?php
|
'<?php
|
||||||
|
Loading…
Reference in New Issue
Block a user