Skip to content

Commit f23011f

Browse files
Add Immutable attribute
1 parent 911b2f7 commit f23011f

File tree

4 files changed

+102
-10
lines changed

4 files changed

+102
-10
lines changed

Diff for: README.md

+11-10
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,6 @@ In particular, these repositories are:
1818
- [Psalm plugin](https://github.com/php-static-analysis/psalm-plugin)
1919
- [RectorPHP rules to migrate annotations to attributes](https://github.com/php-static-analysis/rector-rule)
2020

21-
## PHPStorm
22-
A plugin that fully supports these attributes will need to be created. Until this is ready you can get partial support by installing PHPStan, our PHPStan extension and enabling PHPStan support in PHPStorm (as described [here](https://www.jetbrains.com/help/phpstorm/using-phpstan.html)). You will then be able to see errors and messages related to these attributes in your code.
23-
24-
Alternatively install Psalm, our Psalm extension and enable Psalm support in PHPStorm (as described [here](https://www.jetbrains.com/help/phpstorm/using-psalm.html))
25-
26-
## VS Code Support
27-
An extension that fully supports these attributes will need to be created. Until this is ready you can get partial support by installing PHPStan, our PHPStan extension and a VS Code extension that supports PHPStan (for example [this one](https://github.com/SanderRonde/phpstan-vscode)). When you enable the extension you will be able to see errors and messages related to these attributes in your code.
28-
29-
Alternatively install Psalm, our Psalm extension and a VS Code extension that supports Psam (for example [this one](https://github.com/psalm/psalm-vscode-plugin))
30-
3121
## Example
3222

3323
In order to show how code would look with these attributes, we can look at the following example. This is how a class looks like with the current annotations:
@@ -95,6 +85,7 @@ These are the available attributes and their corresponding PHPDoc annotations:
9585
| Attribute | PHPDoc Annotations |
9686
|-------------------------------------------------------|--------------------------------------|
9787
| [Deprecated](doc/Deprecated.md) | `@deprecated` |
88+
| [Immutable](doc/Immutable.md) | `@immutable` |
9889
| [Impure](doc/Impure.md) | `@impure` |
9990
| [Internal](doc/Internal.md) | `@internal` |
10091
| [IsReadOnly](doc/IsReadOnly.md) | `@readonly` |
@@ -119,3 +110,13 @@ These are the available attributes and their corresponding PHPDoc annotations:
119110
| [Throws](doc/Throws.md) | `@throws` |
120111
| [Type](doc/Type.md) | `@var` `@return` |
121112

113+
## PHPStorm Support
114+
A plugin that fully supports these attributes will need to be created. Until this is ready you can get partial support by installing PHPStan, our PHPStan extension and enabling PHPStan support in PHPStorm (as described [here](https://www.jetbrains.com/help/phpstorm/using-phpstan.html)). You will then be able to see errors and messages related to these attributes in your code.
115+
116+
Alternatively install Psalm, our Psalm extension and enable Psalm support in PHPStorm (as described [here](https://www.jetbrains.com/help/phpstorm/using-psalm.html))
117+
118+
## VS Code Support
119+
An extension that fully supports these attributes will need to be created. Until this is ready you can get partial support by installing PHPStan, our PHPStan extension and a VS Code extension that supports PHPStan (for example [this one](https://github.com/SanderRonde/phpstan-vscode)). When you enable the extension you will be able to see errors and messages related to these attributes in your code.
120+
121+
Alternatively install Psalm, our Psalm extension and a VS Code extension that supports Psam (for example [this one](https://github.com/psalm/psalm-vscode-plugin))
122+

Diff for: doc/Immutable.md

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# `Immutable` Attribute
2+
3+
This attribute is the equivalent of the `@immutable` annotation for classes, traits and interfaces.
4+
5+
## Arguments
6+
7+
The attribute accepts no arguments.
8+
9+
## Example usage
10+
11+
```php
12+
<?php
13+
14+
use PhpStaticAnalysis\Attributes\Immutable;
15+
16+
#[Immutable] // All properties are readonly
17+
class ImmutableExample
18+
{
19+
...
20+
}
21+
```

Diff for: src/Immutable.php

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpStaticAnalysis\Attributes;
6+
7+
use Attribute;
8+
9+
#[Attribute(
10+
Attribute::TARGET_CLASS
11+
)]
12+
final class Immutable
13+
{
14+
public function __construct()
15+
{
16+
}
17+
}

Diff for: tests/ImmutableTest.php

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use PhpStaticAnalysis\Attributes\Immutable;
6+
use PHPUnit\Framework\TestCase;
7+
8+
#[Immutable]
9+
class ImmutableTest extends TestCase
10+
{
11+
public function testClassImmutable(): void
12+
{
13+
$reflection = new ReflectionClass($this);
14+
$this->assertTrue(self::getImmutableFromReflection($reflection));
15+
}
16+
17+
public function testTraitImmutable(): void
18+
{
19+
$reflection = new ReflectionClass(ImmutableTestTrait::class);
20+
$this->assertTrue(self::getImmutableFromReflection($reflection));
21+
}
22+
23+
public function testInterfaceImmutable(): void
24+
{
25+
$reflection = new ReflectionClass(ImmutableTestInterface::class);
26+
$this->assertTrue(self::getImmutableFromReflection($reflection));
27+
}
28+
29+
public static function getImmutableFromReflection(
30+
ReflectionClass $reflection
31+
): bool {
32+
$attributes = $reflection->getAttributes();
33+
$immutable = false;
34+
foreach ($attributes as $attribute) {
35+
if ($attribute->getName() === Immutable::class) {
36+
$attribute->newInstance();
37+
$immutable = true;
38+
}
39+
}
40+
41+
return $immutable;
42+
}
43+
}
44+
45+
#[Immutable]
46+
trait ImmutableTestTrait
47+
{
48+
}
49+
50+
#[Immutable]
51+
interface ImmutableTestInterface
52+
{
53+
}

0 commit comments

Comments
 (0)