Skip to content

Commit

Permalink
Change the Issue type and add documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
robchett committed May 7, 2023
1 parent cad5288 commit aa85669
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 15 deletions.
1 change: 1 addition & 0 deletions config.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@
<xs:element name="InaccessibleClassConstant" type="IssueHandlerType" minOccurs="0" />
<xs:element name="InaccessibleMethod" type="MethodIssueHandlerType" minOccurs="0" />
<xs:element name="InaccessibleProperty" type="IssueHandlerType" minOccurs="0" />
<xs:element name="InheritorViolation" type="ClassIssueHandlerType" minOccurs="0" />
<xs:element name="InterfaceInstantiation" type="IssueHandlerType" minOccurs="0" />
<xs:element name="InternalClass" type="ClassIssueHandlerType" minOccurs="0" />
<xs:element name="InternalMethod" type="MethodIssueHandlerType" minOccurs="0" />
Expand Down
12 changes: 3 additions & 9 deletions docs/annotating_code/supported_annotations.md
Original file line number Diff line number Diff line change
Expand Up @@ -743,19 +743,13 @@ Used to tell Psalm that a class can only be extended by a certain subset of clas

For example,
```php
<?php
/**
* @psalm-inheritors FooClass|BarClass
*/
class BaseClass {}

class FooClass extends BaseClass {
public function thing(string $s) : void { return $s . "hello"; }
}

class BarClass extends BaseClass {
public function thing(int $i) : string { return $i . "hello"; }
}

class FooClass extends BaseClass {}
class BarClass extends BaseClass {}
class BazClass extends BaseClass {} // this is an error
```

Expand Down
1 change: 1 addition & 0 deletions docs/running_psalm/issues.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
- [InaccessibleClassConstant](issues/InaccessibleClassConstant.md)
- [InaccessibleMethod](issues/InaccessibleMethod.md)
- [InaccessibleProperty](issues/InaccessibleProperty.md)
- [InheritorViolation](issues/InheritorViolation.md)
- [InterfaceInstantiation](issues/InterfaceInstantiation.md)
- [InternalClass](issues/InternalClass.md)
- [InternalMethod](issues/InternalMethod.md)
Expand Down
17 changes: 17 additions & 0 deletions docs/running_psalm/issues/InheritorViolation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# InheritorViolation

Emitted when a class/interface using `@psalm-inheritors` is extended/implemented
by a class that does not fulfil it's requirements.

```php
<?php

/**
* @psalm-inheritors FooClass|BarClass
*/
class BaseClass {}
class BazClass extends BaseClass {}
// InheritorViolation is emitted, as BaseClass can only be extended
// by FooClass|BarClass, which is not the case
$a = new BazClass();
```
5 changes: 2 additions & 3 deletions src/Psalm/Internal/Analyzer/ClassLikeAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TemplateStandinTypeReplacer;
use Psalm\Issue\InaccessibleProperty;
use Psalm\Issue\InheritorViolation;
use Psalm\Issue\InvalidClass;
use Psalm\Issue\InvalidExtendClass;
use Psalm\Issue\InvalidTemplateParam;
use Psalm\Issue\MissingDependency;
use Psalm\Issue\MissingTemplateParam;
Expand Down Expand Up @@ -340,10 +340,9 @@ public static function checkFullyQualifiedClassLikeName(
if ($parent_storage && $parent_storage->inheritors) {
if (!UnionTypeComparator::isContainedBy($codebase, $classUnion, $parent_storage->inheritors)) {
IssueBuffer::maybeAdd(
new InvalidExtendClass(
new InheritorViolation(
'Class ' . $fq_class_name . ' is not an allowed inheritor of parent class ' . $parent_class,
$code_location,
$fq_class_name,
),
$suppressed_issues,
);
Expand Down
9 changes: 9 additions & 0 deletions src/Psalm/Issue/InheritorViolation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace Psalm\Issue;

final class InheritorViolation extends CodeIssue
{
public const ERROR_LEVEL = 4;
public const SHORTCODE = 283;
}
6 changes: 3 additions & 3 deletions tests/ClassTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1393,7 +1393,7 @@ class BaseClass {}
class BazClass extends BaseClass {} // this is an error
$a = new BazClass();
PHP,
'error_message' => 'InvalidExtendClass',
'error_message' => 'InheritorViolation',
'ignored_issues' => [],
],
'classCannotImplementIfNotInInheritors' => [
Expand All @@ -1406,7 +1406,7 @@ interface BaseInterface {}
class BazClass implements BaseInterface {}
$a = new BazClass();
PHP,
'error_message' => 'InvalidExtendClass',
'error_message' => 'InheritorViolation',
'ignored_issues' => [],
],
'UnfulfilledInterfaceInheritors' => [
Expand All @@ -1423,7 +1423,7 @@ interface InterfaceB {}
class BazClass implements InterFaceA, InterFaceB {}
$a = new BazClass();
PHP,
'error_message' => 'InvalidExtendClass',
'error_message' => 'InheritorViolation',
'ignored_issues' => [],
],
];
Expand Down

0 comments on commit aa85669

Please sign in to comment.