mirror of
https://github.com/danog/psalm.git
synced 2024-11-26 20:34:47 +01:00
Fix #300 - add PossiblyInvalidPropertyFetch
This commit is contained in:
parent
c5faa2d06a
commit
a99135c4d0
@ -160,6 +160,7 @@
|
||||
<xs:element name="PossiblyInvalidArrayAccess" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="PossiblyInvalidMethodCall" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="PossiblyInvalidPropertyAssignment" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="PossiblyInvalidPropertyFetch" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="PossiblyNullArgument" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="PossiblyNullArrayAccess" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="PossiblyNullFunctionCall" type="IssueHandlerType" minOccurs="0" />
|
||||
|
@ -27,6 +27,7 @@ use Psalm\Issue\NullPropertyFetch;
|
||||
use Psalm\Issue\NullReference;
|
||||
use Psalm\Issue\ParentNotFound;
|
||||
use Psalm\Issue\PossiblyInvalidArrayAccess;
|
||||
use Psalm\Issue\PossiblyInvalidPropertyFetch;
|
||||
use Psalm\Issue\PossiblyNullArrayAccess;
|
||||
use Psalm\Issue\PossiblyNullPropertyFetch;
|
||||
use Psalm\Issue\PossiblyNullReference;
|
||||
@ -167,25 +168,22 @@ class FetchChecker
|
||||
return null;
|
||||
}
|
||||
|
||||
$invalid_fetch_types = [];
|
||||
$has_valid_fetch_type = false;
|
||||
|
||||
foreach ($stmt_var_type->types as $lhs_type_part) {
|
||||
if ($lhs_type_part instanceof TNull) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$lhs_type_part instanceof TNamedObject && !$lhs_type_part instanceof TObject) {
|
||||
if (IssueBuffer::accepts(
|
||||
new InvalidPropertyFetch(
|
||||
'Cannot fetch property on non-object ' . $stmt_var_id . ' of type ' . $lhs_type_part,
|
||||
new CodeLocation($statements_checker->getSource(), $stmt)
|
||||
),
|
||||
$statements_checker->getSuppressedIssues()
|
||||
)) {
|
||||
// fall through
|
||||
}
|
||||
$invalid_fetch_types[] = (string)$lhs_type_part;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$has_valid_fetch_type = true;
|
||||
|
||||
// stdClass and SimpleXMLElement are special cases where we cannot infer the return types
|
||||
// but we don't want to throw an error
|
||||
// Hack has a similar issue: https://github.com/facebook/hhvm/issues/5164
|
||||
@ -365,6 +363,32 @@ class FetchChecker
|
||||
}
|
||||
}
|
||||
|
||||
if ($invalid_fetch_types) {
|
||||
$lhs_type_part = $invalid_fetch_types[0];
|
||||
|
||||
if ($has_valid_fetch_type) {
|
||||
if (IssueBuffer::accepts(
|
||||
new PossiblyInvalidPropertyFetch(
|
||||
'Cannot fetch property on possible non-object ' . $stmt_var_id . ' of type ' . $lhs_type_part,
|
||||
new CodeLocation($statements_checker->getSource(), $stmt)
|
||||
),
|
||||
$statements_checker->getSuppressedIssues()
|
||||
)) {
|
||||
// fall through
|
||||
}
|
||||
} else {
|
||||
if (IssueBuffer::accepts(
|
||||
new InvalidPropertyFetch(
|
||||
'Cannot fetch property on non-object ' . $stmt_var_id . ' of type ' . $lhs_type_part,
|
||||
new CodeLocation($statements_checker->getSource(), $stmt)
|
||||
),
|
||||
$statements_checker->getSuppressedIssues()
|
||||
)) {
|
||||
// fall through
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($var_id) {
|
||||
$context->vars_in_scope[$var_id] = isset($stmt->inferredType) ? $stmt->inferredType : Type::getMixed();
|
||||
}
|
||||
|
6
src/Psalm/Issue/PossiblyInvalidPropertyFetch.php
Normal file
6
src/Psalm/Issue/PossiblyInvalidPropertyFetch.php
Normal file
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
namespace Psalm\Issue;
|
||||
|
||||
class PossiblyInvalidPropertyFetch extends CodeError
|
||||
{
|
||||
}
|
@ -609,6 +609,12 @@ final class B extends A {}',
|
||||
echo $a->foo;',
|
||||
'error_message' => 'InvalidPropertyFetch',
|
||||
],
|
||||
'possiblyBadFetch' => [
|
||||
'<?php
|
||||
$a = rand(0, 5) > 3 ? "hello" : new stdClass;
|
||||
echo $a->foo;',
|
||||
'error_message' => 'PossiblyInvalidPropertyFetch',
|
||||
],
|
||||
'mixedPropertyFetch' => [
|
||||
'<?php
|
||||
class Foo {
|
||||
|
Loading…
Reference in New Issue
Block a user