Skip to content

Commit

Permalink
Support all attribute targets
Browse files Browse the repository at this point in the history
This adds support for properties, class constants, params, enums

Close #224
  • Loading branch information
spaze committed Dec 6, 2023
1 parent f0a6f69 commit e55870f
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 6 deletions.
12 changes: 12 additions & 0 deletions src/Usages/AttributeUsages.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@
use PhpParser\Node\Attribute;
use PhpParser\Node\AttributeGroup;
use PhpParser\Node\FunctionLike;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt\ClassConst;
use PhpParser\Node\Stmt\ClassLike;
use PhpParser\Node\Stmt\EnumCase;
use PhpParser\Node\Stmt\Property;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use Spaze\PHPStan\Rules\Disallowed\DisallowedAttribute;
Expand Down Expand Up @@ -72,6 +76,14 @@ public function processNode(Node $node, Scope $scope): array
$this->addAttrs(array_values($node->attrGroups));
} elseif ($node instanceof FunctionLike) {
$this->addAttrs(array_values($node->getAttrGroups()));
} elseif ($node instanceof Property) {
$this->addAttrs(array_values($node->attrGroups));
} elseif ($node instanceof ClassConst) {
$this->addAttrs(array_values($node->attrGroups));
} elseif ($node instanceof Param) {
$this->addAttrs(array_values($node->attrGroups));
} elseif ($node instanceof EnumCase) {
$this->addAttrs(array_values($node->attrGroups));
} else {
return [];
}
Expand Down
34 changes: 33 additions & 1 deletion tests/Usages/AttributeUsagesAllowParamsMultipleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,25 @@ public function testRule(): void
// on this line:
8,
],
[
'Attribute Attributes\AttributeEntity is forbidden.',
12,
],
[
'Attribute Attributes\AttributeEntity is forbidden.',
15,
],
[
'Attribute Attributes\AttributeEntity is forbidden.',
18,
],
[
'Attribute Attributes\AttributeClass is forbidden.',
30,
40,
],
[
'Attribute Attributes\AttributeEntity is forbidden.',
42,
],
]);
$this->analyse([__DIR__ . '/../src/disallowed-allow/ClassWithAttributesAllow.php'], [
Expand All @@ -85,10 +101,26 @@ public function testRule(): void
'Attribute Attributes\AttributeEntity is forbidden.',
12,
],
[
'Attribute Attributes\AttributeEntity is forbidden.',
15,
],
[
'Attribute Attributes\AttributeEntity is forbidden.',
18,
],
[
'Attribute Attributes\AttributeEntity is forbidden.',
22,
],
[
'Attribute Attributes\AttributeEntity is forbidden.',
28,
],
[
'Attribute Attributes\AttributeEntity is forbidden.',
42,
],
]);
}

Expand Down
31 changes: 30 additions & 1 deletion tests/Usages/AttributeUsagesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ protected function getRule(): Rule
],
'allowIn' => [
'../src/disallowed-allow/ClassWithAttributesAllow.php',
'../src/disallowed-allow/EnumWithAttributesAllow.php',
],
'allowParamsAnywhereAnyValue' => [
[
Expand Down Expand Up @@ -63,12 +64,40 @@ public function testRule(): void
// on this line:
8,
],
[
'Attribute Attributes\AttributeEntity is forbidden.',
12,
],
[
'Attribute Attributes\AttributeEntity is forbidden.',
15,
],
[
'Attribute Attributes\AttributeEntity is forbidden.',
18,
],
[
'Attribute Attributes\AttributeClass is forbidden.',
30,
40,
],
[
'Attribute Attributes\AttributeEntity is forbidden.',
42,
],
]);
$this->analyse([__DIR__ . '/../src/disallowed-allow/ClassWithAttributesAllow.php'], []);

$this->analyse([__DIR__ . '/../src/disallowed/EnumWithAttributes.php'], [
[
'Attribute Attributes\AttributeEntity is forbidden.',
6,
],
[
'Attribute Attributes\AttributeEntity is forbidden.',
10,
],
]);
$this->analyse([__DIR__ . '/../src/disallowed-allow/EnumWithAttributesAllow.php'], []);
}

}
16 changes: 14 additions & 2 deletions tests/src/disallowed-allow/ClassWithAttributesAllow.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@
class ClassWithAttributesAllow
{

#[AttributeEntity] // allowed by path in all tests
private const MAYO = true;

#[AttributeEntity] // allowed by path in all tests
public $cheddar = 'plz';

#[AttributeEntity] // disallowed
public static $pepper = 'ofc';


#[\Attributes\AttributeEntity(repositoryClass: \Attributes\UserRepository::class, readOnly: false)] // allowed by path in AttributeUsagesTest, disallowed in AttributeUsagesAllowParamsMultipleTest because $repositoryClass has other value
public function hasAvocado(): bool
{
Expand All @@ -28,8 +38,10 @@ public function hasKetchup(): bool


#[AttributeClass()] // allowed by path in all tests
public function hasPineapple(): bool
{
public function hasPineapple(
#[AttributeEntity] // allowed by path in all tests
bool $really
): bool {
}

}
15 changes: 15 additions & 0 deletions tests/src/disallowed-allow/EnumWithAttributesAllow.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php
declare(strict_types = 1);

namespace Attributes;

use Attributes\AttributeEntity;

#[AttributeEntity] // disallowed
enum EnumWithAttributesAllow
{

#[AttributeEntity] // disallowed
case Foo;

}
16 changes: 14 additions & 2 deletions tests/src/disallowed/ClassWithAttributes.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@
class ClassWithAttributes
{

#[AttributeEntity] // disallowed
private const MAYO = true;

#[AttributeEntity] // disallowed
public $cheddar = 'plz';

#[AttributeEntity] // disallowed
public static $pepper = 'ofc';


#[AttributeEntity(repositoryClass: UserRepository::class, readOnly: false)] // disallowed, $repositoryClass present with any value
public function hasAvocado(): bool
{
Expand All @@ -28,8 +38,10 @@ public function hasKetchup(): bool


#[AttributeClass()] // disallowed
public function hasPineapple(): bool
{
public function hasPineapple(
#[AttributeEntity] // disallowed
bool $really
): bool {
}

}
13 changes: 13 additions & 0 deletions tests/src/disallowed/EnumWithAttributes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php
declare(strict_types = 1);

namespace Attributes;

#[AttributeEntity] // disallowed
enum EnumWithAttributes
{

#[AttributeEntity] // disallowed
case Foo;

}

0 comments on commit e55870f

Please sign in to comment.