Skip to content

Commit d726548

Browse files
Add RequireExtends and RequireImplements attributes
1 parent 833e1b2 commit d726548

8 files changed

+161
-2
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ These are the available attributes and their corresponding PHPDoc annotations:
109109
| [Property](https://github.com/php-static-analysis/attributes/blob/main/doc/Property.md) | `@property` `@var` |
110110
| [PropertyRead](https://github.com/php-static-analysis/attributes/blob/main/doc/PropertyRead.md) | `@property-read` |
111111
| [PropertyWrite](https://github.com/php-static-analysis/attributes/blob/main/doc/PropertyWrite.md) | `@property-write` |
112+
| [RequireExtends](https://github.com/php-static-analysis/attributes/blob/main/doc/RequireExtends.md) | `@require-extends` |
113+
| [RequireImplements](https://github.com/php-static-analysis/attributes/blob/main/doc/RequireImplements.md) | `@require-implements` |
112114
| [Returns](https://github.com/php-static-analysis/attributes/blob/main/doc/Returns.md) | `@return` |
113115
| [SelfOut](https://github.com/php-static-analysis/attributes/blob/main/doc/SelfOut.md) | `@self-out` `@this-out` |
114116
| [Template](https://github.com/php-static-analysis/attributes/blob/main/doc/Template.md) | `@template` |

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
"require": {
2727
"php": ">=8.0",
2828
"ext-simplexml": "*",
29-
"php-static-analysis/attributes": "^0.1.13 || dev-main",
30-
"php-static-analysis/node-visitor": "^0.1.13 || dev-main",
29+
"php-static-analysis/attributes": "^0.1.14 || dev-main",
30+
"php-static-analysis/node-visitor": "^0.1.14 || dev-main",
3131
"vimeo/psalm": "^5"
3232
},
3333
"require-dev": {

tests/RequireExtendsAttributeTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
4+
namespace test\PhpStaticAnalysis\PsalmPlugin;
5+
6+
class RequireExtendsAttributeTest extends BaseAttributeTestCase
7+
{
8+
public function testClassRequireExtendsAttribute(): void
9+
{
10+
$errors = $this->analyzeTestFile('/data/RequireExtends/TraitRequireExtendsAttribute.php');
11+
$expectedErrors = [
12+
'test\PhpStaticAnalysis\PsalmPlugin\data\RequireExtends\TraitRequireExtendsAttribute requires using class to extend test\PhpStaticAnalysis\PsalmPlugin\data\RequireExtends\ClassRequireExtendsAttribute, but test\PhpStaticAnalysis\PsalmPlugin\data\RequireExtends\ClassRequireExtendsAttributeChild2 does not' => 23,
13+
];
14+
15+
$this->checkExpectedErrors($errors, $expectedErrors);
16+
}
17+
18+
public function testInvalidClassRequireExtendsAttribute(): void
19+
{
20+
$errors = $this->analyzeTestFile( '/data/RequireExtends/InvalidTraitRequireExtendsAttribute.php');
21+
22+
$expectedErrors = [
23+
'Attribute RequireExtends cannot be used on a property' => 10,
24+
];
25+
26+
$this->checkExpectedErrors($errors, $expectedErrors);
27+
}
28+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
namespace test\PhpStaticAnalysis\PsalmPlugin;
4+
5+
class RequireImplementsAttributeTest extends BaseAttributeTestCase
6+
{
7+
public function testClassRequireImplementsAttribute(): void
8+
{
9+
$errors = $this->analyzeTestFile('/data/RequireImplements/TraitRequireImplementsAttribute.php');
10+
$expectedErrors = [
11+
'test\PhpStaticAnalysis\PsalmPlugin\data\RequireImplements\TraitRequireImplementsAttribute requires using class to implement test\PhpStaticAnalysis\PsalmPlugin\data\RequireImplements\InterfaceRequireImplementsAttribute3, but test\PhpStaticAnalysis\PsalmPlugin\data\RequireImplements\ClassRequireImplementsAttribute2 does not' => 35,
12+
];
13+
14+
$this->checkExpectedErrors($errors, $expectedErrors);
15+
}
16+
17+
public function testInvalidClassRequireImplementsAttribute(): void
18+
{
19+
$errors = $this->analyzeTestFile( '/data/RequireImplements/InvalidTraitRequireImplementsAttribute.php');
20+
21+
$expectedErrors = [
22+
'Attribute RequireImplements cannot be used on a property' => 10,
23+
];
24+
25+
$this->checkExpectedErrors($errors, $expectedErrors);
26+
}
27+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace test\PhpStaticAnalysis\PsalmPlugin\data\RequireExtends;
4+
5+
use PhpStaticAnalysis\Attributes\RequireExtends;
6+
7+
#[RequireExtends('InvalidClassRequireExtendsAttribute')]
8+
trait InvalidTraitRequireExtendsAttribute
9+
{
10+
#[RequireExtends('InvalidClassRequireExtendsAttribute')]
11+
public string $name = '';
12+
}
13+
14+
class InvalidClassRequireExtendsAttribute
15+
{
16+
}
17+
18+
class InvalidClassRequireExtendsAttributeChild extends InvalidClassRequireExtendsAttribute
19+
{
20+
use InvalidTraitRequireExtendsAttribute;
21+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace test\PhpStaticAnalysis\PsalmPlugin\data\RequireExtends;
4+
5+
use PhpStaticAnalysis\Attributes\RequireExtends;
6+
7+
#[RequireExtends('ClassRequireExtendsAttribute')] // the class using this trait needs to extend this class
8+
trait TraitRequireExtendsAttribute
9+
{
10+
}
11+
12+
class ClassRequireExtendsAttribute
13+
{
14+
}
15+
16+
class ClassRequireExtendsAttributeChild extends ClassRequireExtendsAttribute
17+
{
18+
use TraitRequireExtendsAttribute;
19+
}
20+
21+
class ClassRequireExtendsAttributeChild2
22+
{
23+
use TraitRequireExtendsAttribute;
24+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace test\PhpStaticAnalysis\PsalmPlugin\data\RequireImplements;
4+
5+
use PhpStaticAnalysis\Attributes\RequireImplements;
6+
7+
#[RequireImplements('InvalidInterfaceRequireImplementsAttribute')]
8+
trait InvalidTraitRequireImplementsAttribute
9+
{
10+
#[RequireImplements('InvalidInterfaceRequireImplementsAttribute')]
11+
public string $name = '';
12+
}
13+
14+
interface InvalidInterfaceRequireImplementsAttribute
15+
{
16+
}
17+
18+
class InvalidClassRequireImplementsAttribute implements InvalidInterfaceRequireImplementsAttribute
19+
{
20+
use InvalidTraitRequireImplementsAttribute;
21+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace test\PhpStaticAnalysis\PsalmPlugin\data\RequireImplements;
4+
5+
use PhpStaticAnalysis\Attributes\RequireImplements;
6+
7+
#[RequireImplements('InterfaceRequireImplementsAttribute')] // the class that uses this trait needs to implement these interfaces
8+
#[RequireImplements(
9+
'InterfaceRequireImplementsAttribute2',
10+
'InterfaceRequireImplementsAttribute3'
11+
)]
12+
trait TraitRequireImplementsAttribute
13+
{
14+
}
15+
16+
interface InterfaceRequireImplementsAttribute
17+
{
18+
}
19+
20+
interface InterfaceRequireImplementsAttribute2
21+
{
22+
}
23+
24+
interface InterfaceRequireImplementsAttribute3
25+
{
26+
}
27+
28+
class ClassRequireImplementsAttribute implements InterfaceRequireImplementsAttribute, InterfaceRequireImplementsAttribute2, InterfaceRequireImplementsAttribute3
29+
{
30+
use TraitRequireImplementsAttribute;
31+
}
32+
33+
class ClassRequireImplementsAttribute2 implements InterfaceRequireImplementsAttribute, InterfaceRequireImplementsAttribute2
34+
{
35+
use TraitRequireImplementsAttribute;
36+
}

0 commit comments

Comments
 (0)