Skip to content

Commit

Permalink
Fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
muglug committed Jan 6, 2020
1 parent 867511d commit 4e85967
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 20 deletions.
2 changes: 2 additions & 0 deletions config.xsd
Expand Up @@ -341,6 +341,8 @@
<xs:element name="UndefinedFunction" type="FunctionIssueHandlerType" minOccurs="0" />
<xs:element name="UndefinedInterface" type="ClassIssueHandlerType" minOccurs="0" />
<xs:element name="UndefinedInterfaceMethod" type="MethodIssueHandlerType" minOccurs="0" />
<xs:element name="UndefinedMagicPropertyAssignment" type="PropertyIssueHandlerType" minOccurs="0" />
<xs:element name="UndefinedMagicPropertyFetch" type="PropertyIssueHandlerType" minOccurs="0" />
<xs:element name="UndefinedMethod" type="MethodIssueHandlerType" minOccurs="0" />
<xs:element name="UndefinedPropertyAssignment" type="PropertyIssueHandlerType" minOccurs="0" />
<xs:element name="UndefinedPropertyFetch" type="PropertyIssueHandlerType" minOccurs="0" />
Expand Down
33 changes: 33 additions & 0 deletions docs/running_psalm/issues.md
Expand Up @@ -2304,6 +2304,39 @@ class C {}
interface I extends C {}
```

### UndefinedMagicPropertyAssignment

Emitted when assigning a property on an object that doesn’t have that magic property defined

```php
/**
* @property string $bar
*/
class A {
/** @param mixed $value */
public function __set(string $name, $value) {}
}
$a = new A();
$a->foo = "bar";
```

### UndefinedMagicPropertyFetch

Emitted when getting a property on an object that doesn’t have that magic property defined

```php
/**
* @property string $bar
*/
class A {
public function __get(string $name) {
return "cool";
}
}
$a = new A();
echo $a->foo;
```

### UndefinedMethod

Emitted when calling a method that doesn’t exist
Expand Down
Expand Up @@ -341,6 +341,8 @@ public static function analyzeInstance(
$property_id = $fq_class_name . '::$' . $prop_name;
$property_ids[] = $property_id;

$has_magic_setter = false;

if ($codebase->methodExists($fq_class_name . '::__set')
&& (!$codebase->properties->propertyExists($property_id, false, $statements_analyzer, $context)
|| ($lhs_var_id !== '$this'
Expand All @@ -355,6 +357,7 @@ public static function analyzeInstance(
) !== true)
)
) {
$has_magic_setter = true;
$class_storage = $codebase->classlike_storage_provider->get($fq_class_name);

if ($var_id) {
Expand Down Expand Up @@ -495,15 +498,28 @@ public static function analyzeInstance(
// fall through
}
} else {
if (IssueBuffer::accepts(
new UndefinedPropertyAssignment(
'Instance property ' . $property_id . ' is not defined',
new CodeLocation($statements_analyzer->getSource(), $stmt),
$property_id
),
$statements_analyzer->getSuppressedIssues()
)) {
// fall through
if ($has_magic_setter) {
if (IssueBuffer::accepts(
new UndefinedMagicPropertyAssignment(
'Magic instance property ' . $property_id . ' is not defined',
new CodeLocation($statements_analyzer->getSource(), $stmt),
$property_id
),
$statements_analyzer->getSuppressedIssues()
)) {
// fall through
}
} else {
if (IssueBuffer::accepts(
new UndefinedPropertyAssignment(
'Instance property ' . $property_id . ' is not defined',
new CodeLocation($statements_analyzer->getSource(), $stmt),
$property_id
),
$statements_analyzer->getSuppressedIssues()
)) {
// fall through
}
}
}

Expand Down
Expand Up @@ -413,6 +413,8 @@ public static function analyzeInstance(

$override_property_visibility = false;

$has_magic_getter = false;

$class_exists = false;
$interface_exists = false;

Expand Down Expand Up @@ -498,6 +500,8 @@ public static function analyzeInstance(
) !== true)
)
) {
$has_magic_getter = true;

$class_storage = $codebase->classlike_storage_provider->get($fq_class_name);

if (isset($class_storage->pseudo_property_get_types['$' . $prop_name])) {
Expand Down Expand Up @@ -636,15 +640,28 @@ public static function analyzeInstance(
// fall through
}
} else {
if (IssueBuffer::accepts(
new UndefinedPropertyFetch(
'Instance property ' . $property_id . ' is not defined',
new CodeLocation($statements_analyzer->getSource(), $stmt),
$property_id
),
$statements_analyzer->getSuppressedIssues()
)) {
// fall through
if ($has_magic_getter) {
if (IssueBuffer::accepts(
new UndefinedMagicPropertyFetch(
'Magic instance property ' . $property_id . ' is not defined',
new CodeLocation($statements_analyzer->getSource(), $stmt),
$property_id
),
$statements_analyzer->getSuppressedIssues()
)) {
// fall through
}
} else {
if (IssueBuffer::accepts(
new UndefinedPropertyFetch(
'Instance property ' . $property_id . ' is not defined',
new CodeLocation($statements_analyzer->getSource(), $stmt),
$property_id
),
$statements_analyzer->getSuppressedIssues()
)) {
// fall through
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions tests/MagicPropertyTest.php
Expand Up @@ -653,7 +653,7 @@ public function __set(string $name, $value): void {
$a = new A();
$a->bar = 5;',
'error_message' => 'UndefinedPropertyAssignment',
'error_message' => 'UndefinedMagicPropertyAssignment',
],
'propertySealedDocblockDefinedPropertyAssignment' => [
'<?php
Expand Down Expand Up @@ -719,7 +719,7 @@ public function __set(string $name, $value): void {
$a = new A();
echo $a->bar;',
'error_message' => 'UndefinedPropertyFetch',
'error_message' => 'UndefinedMagicPropertyFetch',
],
/**
* The property $foo is not defined on the object, but accessed with the magic setter.
Expand Down

0 comments on commit 4e85967

Please sign in to comment.