mirror of
https://github.com/danog/psalm.git
synced 2025-01-21 21:31:13 +01:00
Add more robust property assignment when property not defined
This commit is contained in:
parent
a651fad6f0
commit
81493a639e
@ -127,7 +127,6 @@
|
||||
<xs:element name="MissingClosureReturnType" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="MissingConstructor" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="MissingFile" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="MissingPropertyDeclaration" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="MissingPropertyType" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="MissingReturnType" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="MixedArgument" type="IssueHandlerType" minOccurs="0" />
|
||||
|
@ -19,7 +19,6 @@ use Psalm\Issue\FailedTypeResolution;
|
||||
use Psalm\Issue\InvalidArrayAssignment;
|
||||
use Psalm\Issue\InvalidPropertyAssignment;
|
||||
use Psalm\Issue\InvalidScope;
|
||||
use Psalm\Issue\MissingPropertyDeclaration;
|
||||
use Psalm\Issue\MixedAssignment;
|
||||
use Psalm\Issue\MixedPropertyAssignment;
|
||||
use Psalm\Issue\MixedStringOffsetAssignment;
|
||||
@ -470,6 +469,8 @@ class AssignmentChecker
|
||||
|
||||
$project_checker = $statements_checker->getFileChecker()->project_checker;
|
||||
|
||||
$property_exists = false;
|
||||
|
||||
if ($stmt instanceof PropertyProperty) {
|
||||
if (!$context->self || !$stmt->default) {
|
||||
return null;
|
||||
@ -481,6 +482,8 @@ class AssignmentChecker
|
||||
return null;
|
||||
}
|
||||
|
||||
$property_exists = true;
|
||||
|
||||
$declaring_property_class = ClassLikeChecker::getDeclaringClassForProperty($project_checker, $property_id);
|
||||
|
||||
$class_storage = $project_checker->classlike_storage_provider->get((string)$declaring_property_class);
|
||||
@ -647,6 +650,7 @@ class AssignmentChecker
|
||||
$class_property_types[] =
|
||||
clone $class_storage->pseudo_property_set_types['$' . $prop_name];
|
||||
$has_regular_setter = true;
|
||||
$property_exists = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -672,10 +676,12 @@ class AssignmentChecker
|
||||
$property_id = $lhs_type_part->value . '::$' . $prop_name;
|
||||
|
||||
if (!ClassLikeChecker::propertyExists($project_checker, $property_id)) {
|
||||
$has_regular_setter = true;
|
||||
|
||||
if ($stmt->var instanceof PhpParser\Node\Expr\Variable && $stmt->var->name === 'this') {
|
||||
// if this is a proper error, we'll see it on the first pass
|
||||
if ($context->collect_mutations) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IssueBuffer::accepts(
|
||||
@ -702,6 +708,8 @@ class AssignmentChecker
|
||||
continue;
|
||||
}
|
||||
|
||||
$property_exists = true;
|
||||
|
||||
if (ClassLikeChecker::checkPropertyVisibility(
|
||||
$property_id,
|
||||
$context->self,
|
||||
@ -779,17 +787,7 @@ class AssignmentChecker
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!$class_property_types) {
|
||||
if (IssueBuffer::accepts(
|
||||
new MissingPropertyDeclaration(
|
||||
'Missing property declaration for ' . $var_id,
|
||||
new CodeLocation($statements_checker->getSource(), $stmt)
|
||||
),
|
||||
$statements_checker->getSuppressedIssues()
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$property_exists) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -1,6 +0,0 @@
|
||||
<?php
|
||||
namespace Psalm\Issue;
|
||||
|
||||
class MissingPropertyDeclaration extends CodeError
|
||||
{
|
||||
}
|
@ -406,13 +406,14 @@ class AnnotationTest extends TestCase
|
||||
* @property string $foo
|
||||
*/
|
||||
class A {
|
||||
public function __get($name) : ?string {
|
||||
public function __get(string $name) : ?string {
|
||||
if ($name === "foo") {
|
||||
return "hello";
|
||||
}
|
||||
}
|
||||
|
||||
public function __set($name, $value) : void {
|
||||
/** @param mixed $value */
|
||||
public function __set(string $name, $value) : void {
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -532,17 +532,6 @@ final class B extends A {}',
|
||||
}',
|
||||
'error_message' => 'UndefinedThisPropertyFetch',
|
||||
],
|
||||
'missingPropertyDeclaration' => [
|
||||
'<?php
|
||||
class A {
|
||||
}
|
||||
|
||||
/** @psalm-suppress UndefinedPropertyAssignment */
|
||||
function fooDo() : void {
|
||||
(new A)->foo = "cool";
|
||||
}',
|
||||
'error_message' => 'MissingPropertyDeclaration',
|
||||
],
|
||||
'missingPropertyType' => [
|
||||
'<?php
|
||||
class A {
|
||||
|
Loading…
x
Reference in New Issue
Block a user