Skip to content

Commit

Permalink
Add Pure and Impure attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
carlos-granados committed Feb 25, 2024
1 parent 31eac4f commit 9876dee
Show file tree
Hide file tree
Showing 10 changed files with 219 additions and 25 deletions.
48 changes: 25 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,29 +94,31 @@ This extension works by interacting with the parser that PHPStan uses to parse t

These are the available attributes and their corresponding PHPDoc annotations:

| Attribute | PHPDoc Annotations |
|------------------------------------------------------------------------------------------------------------|--------------------------------------|
| [Deprecated](https://github.com/php-static-analysis/attributes/blob/main/doc/Deprecated.md) | `@deprecated` |
| [Internal](https://github.com/php-static-analysis/attributes/blob/main/doc/Internal.md) | `@internal` |
| [IsReadOnly](https://github.com/php-static-analysis/attributes/blob/main/doc/IsReadOnly.md) | `@readonly` |
| [Method](https://github.com/php-static-analysis/attributes/blob/main/doc/Method.md) | `@method` |
| [Mixin](https://github.com/php-static-analysis/attributes/blob/main/doc/Mixin.md) | `@mixin` |
| [Param](https://github.com/php-static-analysis/attributes/blob/main/doc/Param.md) | `@param` |
| [ParamOut](https://github.com/php-static-analysis/attributes/blob/main/doc/ParamOut.md) | `@param-out` |
| [Property](https://github.com/php-static-analysis/attributes/blob/main/doc/Property.md) | `@property` `@var` |
| [PropertyRead](https://github.com/php-static-analysis/attributes/blob/main/doc/PropertyRead.md) | `@property-read` |
| [PropertyWrite](https://github.com/php-static-analysis/attributes/blob/main/doc/PropertyWrite.md) | `@property-write` |
| [RequireExtends](https://github.com/php-static-analysis/attributes/blob/main/doc/RequireExtends.md) | `@require-extends` |
| [RequireImplements](https://github.com/php-static-analysis/attributes/blob/main/doc/RequireImplements.md) | `@require-implements` |
| [Returns](https://github.com/php-static-analysis/attributes/blob/main/doc/Returns.md) | `@return` |
| [SelfOut](https://github.com/php-static-analysis/attributes/blob/main/doc/SelfOut.md) | `@self-out` `@this-out` |
| [Template](https://github.com/php-static-analysis/attributes/blob/main/doc/Template.md) | `@template` |
| [TemplateContravariant](https://github.com/php-static-analysis/attributes/blob/main/doc/TemplateContravariant.md) | `@template-contravariant` |
| [TemplateCovariant](https://github.com/php-static-analysis/attributes/blob/main/doc/TemplateCovariant.md) | `@template-covariant` |
| [TemplateExtends](https://github.com/php-static-analysis/attributes/blob/main/doc/TemplateExtends.md) | `@extends` `@template-extends` |
| [TemplateImplements](https://github.com/php-static-analysis/attributes/blob/main/doc/TemplateImplements.md) | `@implements` `@template-implements` |
| [TemplateUse](https://github.com/php-static-analysis/attributes/blob/main/doc/TemplateUse.md) | `@use` `@template-use` |
| [Type](https://github.com/php-static-analysis/attributes/blob/main/doc/Type.md) | `@var` `@return` |
| Attribute | PHPDoc Annotations |
|--------------------------------------------------------------------------------------------------------------------|--------------------------------------|
| [Deprecated](https://github.com/php-static-analysis/attributes/blob/main/doc/Deprecated.md) | `@deprecated` |
| [Impure](https://github.com/php-static-analysis/attributes/blob/main/doc/Impure.md) | `@impure` |
| [Internal](https://github.com/php-static-analysis/attributes/blob/main/doc/Internal.md) | `@internal` |
| [IsReadOnly](https://github.com/php-static-analysis/attributes/blob/main/doc/IsReadOnly.md) | `@readonly` |
| [Method](https://github.com/php-static-analysis/attributes/blob/main/doc/Method.md) | `@method` |
| [Mixin](https://github.com/php-static-analysis/attributes/blob/main/doc/Mixin.md) | `@mixin` |
| [Param](https://github.com/php-static-analysis/attributes/blob/main/doc/Param.md) | `@param` |
| [ParamOut](https://github.com/php-static-analysis/attributes/blob/main/doc/ParamOut.md) | `@param-out` |
| [Property](https://github.com/php-static-analysis/attributes/blob/main/doc/Property.md) | `@property` `@var` |
| [PropertyRead](https://github.com/php-static-analysis/attributes/blob/main/doc/PropertyRead.md) | `@property-read` |
| [PropertyWrite](https://github.com/php-static-analysis/attributes/blob/main/doc/PropertyWrite.md) | `@property-write` |
| [Pure](https://github.com/php-static-analysis/attributes/blob/main/doc/Pure.md) | `@pure` |
| [RequireExtends](https://github.com/php-static-analysis/attributes/blob/main/doc/RequireExtends.md) | `@require-extends` |
| [RequireImplements](https://github.com/php-static-analysis/attributes/blob/main/doc/RequireImplements.md) | `@require-implements` |
| [Returns](https://github.com/php-static-analysis/attributes/blob/main/doc/Returns.md) | `@return` |
| [SelfOut](https://github.com/php-static-analysis/attributes/blob/main/doc/SelfOut.md) | `@self-out` `@this-out` |
| [Template](https://github.com/php-static-analysis/attributes/blob/main/doc/Template.md) | `@template` |
| [TemplateContravariant](https://github.com/php-static-analysis/attributes/blob/main/doc/TemplateContravariant.md) | `@template-contravariant` |
| [TemplateCovariant](https://github.com/php-static-analysis/attributes/blob/main/doc/TemplateCovariant.md) | `@template-covariant` |
| [TemplateExtends](https://github.com/php-static-analysis/attributes/blob/main/doc/TemplateExtends.md) | `@extends` `@template-extends` |
| [TemplateImplements](https://github.com/php-static-analysis/attributes/blob/main/doc/TemplateImplements.md) | `@implements` `@template-implements` |
| [TemplateUse](https://github.com/php-static-analysis/attributes/blob/main/doc/TemplateUse.md) | `@use` `@template-use` |
| [Type](https://github.com/php-static-analysis/attributes/blob/main/doc/Type.md) | `@var` `@return` |



Expand Down
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
"prefer-stable": true,
"require": {
"php": ">=8.0",
"php-static-analysis/attributes": "^0.1.14 || dev-main",
"php-static-analysis/node-visitor": "^0.1.14 || dev-main",
"php-static-analysis/attributes": "^0.1.15 || dev-main",
"php-static-analysis/node-visitor": "^0.1.15 || dev-main",
"phpstan/phpstan": "^1.8"
},
"require-dev": {
Expand Down
30 changes: 30 additions & 0 deletions tests/ImpureAttributeTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace test\PhpStaticAnalysis\PHPStanExtension;

class ImpureAttributeTest extends BaseAttributeTestCase
{
public function testMethodImpureAttribute(): void
{
$errors = $this->analyse(__DIR__ . '/data/Impure/MethodImpureAttribute.php');
$this->assertCount(0, $errors);
}

public function testFunctionImpureAttribute(): void
{
$errors = $this->analyse(__DIR__ . '/data/Impure/FunctionImpureAttribute.php');
$this->assertCount(0, $errors);
}

public function testInvalidMethodImpureAttribute(): void
{
$errors = $this->analyse(__DIR__ . '/data/Impure/InvalidMethodImpureAttribute.php');

$expectedErrors = [
'Attribute class PhpStaticAnalysis\Attributes\Impure does not have the property target.' => 11,
'Attribute class PhpStaticAnalysis\Attributes\Impure is not repeatable but is already present above the method.' => 15,
];

$this->checkExpectedErrors($errors, $expectedErrors);
}
}
30 changes: 30 additions & 0 deletions tests/PureAttributeTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace test\PhpStaticAnalysis\PHPStanExtension;

class PureAttributeTest extends BaseAttributeTestCase
{
public function testMethodPureAttribute(): void
{
$errors = $this->analyse(__DIR__ . '/data/Pure/MethodPureAttribute.php');
$this->assertCount(0, $errors);
}

public function testFunctionPureAttribute(): void
{
$errors = $this->analyse(__DIR__ . '/data/Pure/FunctionPureAttribute.php');
$this->assertCount(0, $errors);
}

public function testInvalidMethodPureAttribute(): void
{
$errors = $this->analyse(__DIR__ . '/data/Pure/InvalidMethodPureAttribute.php');

$expectedErrors = [
'Attribute class PhpStaticAnalysis\Attributes\Pure does not have the property target.' => 11,
'Attribute class PhpStaticAnalysis\Attributes\Pure is not repeatable but is already present above the method.' => 15,
];

$this->checkExpectedErrors($errors, $expectedErrors);
}
}
16 changes: 16 additions & 0 deletions tests/data/Impure/FunctionImpureAttribute.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace test\PhpStaticAnalysis\PHPStanExtension\data;

use PhpStaticAnalysis\Attributes\Impure;

$i = 0;

#[Impure]
function add(int $left): int
{
global $i;

$i += $left;
return $i;
}
19 changes: 19 additions & 0 deletions tests/data/Impure/InvalidMethodImpureAttribute.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace test\PhpStaticAnalysis\PHPStanExtension\data\Impure;

use PhpStaticAnalysis\Attributes\Impure;
use PhpStaticAnalysis\Attributes\Param;
use PhpStaticAnalysis\Attributes\Returns;

class InvalidMethodImpureAttribute
{
#[Impure]
public string $name = '';

#[Impure]
#[Impure]
public function getMoreName(): void
{
}
}
36 changes: 36 additions & 0 deletions tests/data/Impure/MethodImpureAttribute.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace test\PhpStaticAnalysis\PHPStanExtension\data\Impure;

use PhpStaticAnalysis\Attributes\Impure;

class MethodImpureAttribute
{
public static int $i = 0;

#[Impure]
public static function add(int $left): int
{
self::$i += $left;
return self::$i;
}

/**
* @codeCoverageIgnore
*/
#[Impure]
public function addAnother(int $left): int
{
self::$i += $left;
return self::$i;
}

/**
* @impure
*/
public function addMore(int $left): int
{
self::$i += $left;
return self::$i;
}
}
11 changes: 11 additions & 0 deletions tests/data/Pure/FunctionPureAttribute.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace test\PhpStaticAnalysis\PHPStanExtension\data;

use PhpStaticAnalysis\Attributes\Pure;

#[Pure]
function add(int $left, int $right): int
{
return $left + $right;
}
19 changes: 19 additions & 0 deletions tests/data/Pure/InvalidMethodPureAttribute.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace test\PhpStaticAnalysis\PHPStanExtension\data\Pure;

use PhpStaticAnalysis\Attributes\Param;
use PhpStaticAnalysis\Attributes\Pure;
use PhpStaticAnalysis\Attributes\Returns;

class InvalidMethodPureAttribute
{
#[Pure]
public string $name = '';

#[Pure]
#[Pure]
public function getMoreName(): void
{
}
}
31 changes: 31 additions & 0 deletions tests/data/Pure/MethodPureAttribute.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace test\PhpStaticAnalysis\PHPStanExtension\data\Pure;

use PhpStaticAnalysis\Attributes\Pure;

class MethodPureAttribute
{
#[Pure]
public function add(int $left, int $right): int
{
return $left + $right;
}

/**
* @codeCoverageIgnore
*/
#[Pure]
public function addAnother(int $left, int $right): int
{
return $left + $right;
}

/**
* @pure
*/
public function addMore(int $left, int $right): int
{
return $left + $right;
}
}

0 comments on commit 9876dee

Please sign in to comment.