diff --git a/README.md b/README.md index fb4b167..76956f6 100644 --- a/README.md +++ b/README.md @@ -94,13 +94,16 @@ 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 Annotation | -|---------------------------------------------------------------------------------------------|-------------------| -| [IsReadOnly](https://github.com/php-static-analysis/attributes/blob/main/doc/IsReadOnly.md) | `@readonly` | -| [Param](https://github.com/php-static-analysis/attributes/blob/main/doc/Param.md) | `@param` | -| [Returns](https://github.com/php-static-analysis/attributes/blob/main/doc/Returns.md) | `@return` | -| [Template](https://github.com/php-static-analysis/attributes/blob/main/doc/Template.md) | `@template` | -| [Type](https://github.com/php-static-analysis/attributes/blob/main/doc/Type.md) | `@var` | +| Attribute | PHPDoc Annotations | +|---------------------------------------------------------------------------------------------------|--------------------| +| [IsReadOnly](https://github.com/php-static-analysis/attributes/blob/main/doc/IsReadOnly.md) | `@readonly` | +| [Param](https://github.com/php-static-analysis/attributes/blob/main/doc/Param.md) | `@param` | +| [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` | +| [Returns](https://github.com/php-static-analysis/attributes/blob/main/doc/Returns.md) | `@return` | +| [Template](https://github.com/php-static-analysis/attributes/blob/main/doc/Template.md) | `@template` | +| [Type](https://github.com/php-static-analysis/attributes/blob/main/doc/Type.md) | `@var` `@return` | diff --git a/composer.json b/composer.json index 1182ef5..ba03bef 100644 --- a/composer.json +++ b/composer.json @@ -24,8 +24,8 @@ "prefer-stable": true, "require": { "php": ">=8.0", - "php-static-analysis/attributes": "^0.1.3 || dev-main", - "php-static-analysis/node-visitor": "^0.1.3 || dev-main", + "php-static-analysis/attributes": "^0.1.4 || dev-main", + "php-static-analysis/node-visitor": "^0.1.4 || dev-main", "phpstan/phpstan": "^1.8" }, "require-dev": { diff --git a/tests/IsReadOnlyAttributeTest.php b/tests/IsReadOnlyAttributeTest.php index c0c6717..e6154a7 100644 --- a/tests/IsReadOnlyAttributeTest.php +++ b/tests/IsReadOnlyAttributeTest.php @@ -6,9 +6,9 @@ class IsReadOnlyAttributeTest extends BaseAttributeTestCase { public function testPropertyTypeAttribute(): void { - $errors = $this->analyse(__DIR__ . '/data/PropertyIsReadOnlyAttribute.php'); + $errors = $this->analyse(__DIR__ . '/data/IsReadOnly/PropertyIsReadOnlyAttribute.php'); $expectedErrors = [ - '@readonly property test\PhpStaticAnalysis\PHPStanExtension\data\PropertyIsReadOnlyAttribute::$name is assigned outside of its declaring class.' => 19, + '@readonly property test\PhpStaticAnalysis\PHPStanExtension\data\IsReadOnly\PropertyIsReadOnlyAttribute::$name is assigned outside of its declaring class.' => 19, ]; $this->checkExpectedErrors($errors, $expectedErrors); @@ -16,7 +16,7 @@ public function testPropertyTypeAttribute(): void public function testInvalidPropertyIsReadOnlyAttribute(): void { - $errors = $this->analyse(__DIR__ . '/data/InvalidPropertyIsReadOnlyAttribute.php'); + $errors = $this->analyse(__DIR__ . '/data/IsReadOnly/InvalidPropertyIsReadOnlyAttribute.php'); $expectedErrors = [ 'Attribute class PhpStaticAnalysis\Attributes\IsReadOnly constructor invoked with 1 parameter, 0 required.' => 9, diff --git a/tests/ParamAttributeTest.php b/tests/ParamAttributeTest.php index 9b5792f..4ebe8f5 100644 --- a/tests/ParamAttributeTest.php +++ b/tests/ParamAttributeTest.php @@ -6,19 +6,19 @@ class ParamAttributeTest extends BaseAttributeTestCase { public function testMethodParamAttribute(): void { - $errors = $this->analyse(__DIR__ . '/data/MethodParamAttribute.php'); + $errors = $this->analyse(__DIR__ . '/data/Param/MethodParamAttribute.php'); $this->assertCount(0, $errors); } public function testFunctionParamAttribute(): void { - $errors = $this->analyse(__DIR__ . '/data/FunctionParamAttribute.php'); + $errors = $this->analyse(__DIR__ . '/data/Param/FunctionParamAttribute.php'); $this->assertCount(0, $errors); } public function testInvalidMethodReturnsAttribute(): void { - $errors = $this->analyse(__DIR__ . '/data/InvalidMethodParamAttribute.php'); + $errors = $this->analyse(__DIR__ . '/data/Param/InvalidMethodParamAttribute.php'); $expectedErrors = [ 'PHPDoc tag @param has invalid value (): Unexpected token "\n ", expected type at offset 13' => 9, diff --git a/tests/PropertyAttributeTest.php b/tests/PropertyAttributeTest.php index 97707a8..984c6ee 100644 --- a/tests/PropertyAttributeTest.php +++ b/tests/PropertyAttributeTest.php @@ -6,13 +6,13 @@ class PropertyAttributeTest extends BaseAttributeTestCase { public function testClassPropertyAttribute(): void { - $errors = $this->analyse(__DIR__ . '/data/ClassPropertyAttribute.php'); + $errors = $this->analyse(__DIR__ . '/data/Property/ClassPropertyAttribute.php'); $this->assertCount(0, $errors); } public function testInvalidClassPropertyAttribute(): void { - $errors = $this->analyse(__DIR__ . '/data/InvalidClassPropertyAttribute.php'); + $errors = $this->analyse(__DIR__ . '/data/Property/InvalidClassPropertyAttribute.php'); $expectedErrors = [ 'PHPDoc tag @property has invalid value (): Unexpected token "\n * ", expected type at offset 16' => 7, diff --git a/tests/PropertyReadAttributeTest.php b/tests/PropertyReadAttributeTest.php new file mode 100644 index 0000000..90f55e0 --- /dev/null +++ b/tests/PropertyReadAttributeTest.php @@ -0,0 +1,28 @@ +analyse(__DIR__ . '/data/PropertyRead/ClassPropertyReadAttribute.php'); + $this->assertCount(0, $errors); + } + + public function testInvalidClassPropertyReadAttribute(): void + { + $errors = $this->analyse(__DIR__ . '/data/PropertyRead/InvalidClassPropertyReadAttribute.php'); + + $expectedErrors = [ + 'PHPDoc tag @property-read has invalid value (): Unexpected token "\n * ", expected type at offset 21' => 7, + 'PHPDoc tag @property-read has invalid value (count($a) $name): Unexpected token "(", expected variable at offset 70' => 7, + 'PHPDoc tag @property-read has invalid value (string): Unexpected token "\n * ", expected variable at offset 46' => 7, + 'Parameter #1 ...$params of attribute class PhpStaticAnalysis\Attributes\PropertyRead constructor expects string, int given.' => 7, + 'Attribute class PhpStaticAnalysis\Attributes\PropertyRead does not have the method target.' => 13, + 'Property test\PhpStaticAnalysis\PHPStanExtension\data\PropertyRead\ClassPropertyReadAttribute::$age is not writable.' => 21, + ]; + + $this->checkExpectedErrors($errors, $expectedErrors); + } +} diff --git a/tests/PropertyWriteAttributeTest.php b/tests/PropertyWriteAttributeTest.php new file mode 100644 index 0000000..2b2b20e --- /dev/null +++ b/tests/PropertyWriteAttributeTest.php @@ -0,0 +1,28 @@ +analyse(__DIR__ . '/data/PropertyWrite/ClassPropertyWriteAttribute.php'); + $this->assertCount(0, $errors); + } + + public function testInvalidClassPropertyWriteAttribute(): void + { + $errors = $this->analyse(__DIR__ . '/data/PropertyWrite/InvalidClassPropertyWriteAttribute.php'); + + $expectedErrors = [ + 'PHPDoc tag @property-write has invalid value (): Unexpected token "\n * ", expected type at offset 22' => 7, + 'PHPDoc tag @property-write has invalid value (count($a) $name): Unexpected token "(", expected variable at offset 73' => 7, + 'PHPDoc tag @property-write has invalid value (string): Unexpected token "\n * ", expected variable at offset 48' => 7, + 'Parameter #1 ...$params of attribute class PhpStaticAnalysis\Attributes\PropertyWrite constructor expects string, int given.' => 7, + 'Attribute class PhpStaticAnalysis\Attributes\PropertyWrite does not have the method target.' => 13, + 'Property test\PhpStaticAnalysis\PHPStanExtension\data\PropertyWrite\ClassPropertyWriteAttribute::$age is not readable.' => 21, + ]; + + $this->checkExpectedErrors($errors, $expectedErrors); + } +} diff --git a/tests/ReturnsAttributeTest.php b/tests/ReturnsAttributeTest.php index 1d0eab9..cbdc860 100644 --- a/tests/ReturnsAttributeTest.php +++ b/tests/ReturnsAttributeTest.php @@ -6,19 +6,19 @@ class ReturnsAttributeTest extends BaseAttributeTestCase { public function testMethodReturnsAttribute(): void { - $errors = $this->analyse(__DIR__ . '/data/MethodReturnsAttribute.php'); + $errors = $this->analyse(__DIR__ . '/data/Returns/MethodReturnsAttribute.php'); $this->assertCount(0, $errors); } public function testFunctionReturnsAttribute(): void { - $errors = $this->analyse(__DIR__ . '/data/FunctionReturnsAttribute.php'); + $errors = $this->analyse(__DIR__ . '/data/Returns/FunctionReturnsAttribute.php'); $this->assertCount(0, $errors); } public function testInvalidMethodReturnsAttribute(): void { - $errors = $this->analyse(__DIR__ . '/data/InvalidMethodReturnsAttribute.php'); + $errors = $this->analyse(__DIR__ . '/data/Returns/InvalidMethodReturnsAttribute.php'); $expectedErrors = [ 'PHPDoc tag @return has invalid value (): Unexpected token "\n ", expected type at offset 14' => 9, diff --git a/tests/TemplateAttributeTest.php b/tests/TemplateAttributeTest.php index c6885c5..747ef9a 100644 --- a/tests/TemplateAttributeTest.php +++ b/tests/TemplateAttributeTest.php @@ -6,37 +6,37 @@ class TemplateAttributeTest extends BaseAttributeTestCase { public function testClassTemplateAttribute(): void { - $errors = $this->analyse(__DIR__ . '/data/ClassTemplateAttribute.php'); + $errors = $this->analyse(__DIR__ . '/data/Template/ClassTemplateAttribute.php'); $this->assertCount(0, $errors); } public function testTraitTemplateAttribute(): void { - $errors = $this->analyse(__DIR__ . '/data/TraitTemplateAttribute.php'); + $errors = $this->analyse(__DIR__ . '/data/Template/TraitTemplateAttribute.php'); $this->assertCount(0, $errors); } public function testInterfaceTemplateAttribute(): void { - $errors = $this->analyse(__DIR__ . '/data/InterfaceTemplateAttribute.php'); + $errors = $this->analyse(__DIR__ . '/data/Template/InterfaceTemplateAttribute.php'); $this->assertCount(0, $errors); } public function testMethodTemplateAttribute(): void { - $errors = $this->analyse(__DIR__ . '/data/MethodTemplateAttribute.php'); + $errors = $this->analyse(__DIR__ . '/data/Template/MethodTemplateAttribute.php'); $this->assertCount(0, $errors); } public function testFunctionTemplateAttribute(): void { - $errors = $this->analyse(__DIR__ . '/data/FunctionTemplateAttribute.php'); + $errors = $this->analyse(__DIR__ . '/data/Template/FunctionTemplateAttribute.php'); $this->assertCount(0, $errors); } public function testInvalidMethodTemplateAttribute(): void { - $errors = $this->analyse(__DIR__ . '/data/InvalidMethodTemplateAttribute.php'); + $errors = $this->analyse(__DIR__ . '/data/Template/InvalidMethodTemplateAttribute.php'); $expectedErrors = [ 'PHPDoc tag @template has invalid value (): Unexpected token "\n ", expected type at offset 16' => 11, diff --git a/tests/TypeAttributeTest.php b/tests/TypeAttributeTest.php index 5f3384b..49d8cf2 100644 --- a/tests/TypeAttributeTest.php +++ b/tests/TypeAttributeTest.php @@ -6,13 +6,13 @@ class TypeAttributeTest extends BaseAttributeTestCase { public function testPropertyTypeAttribute(): void { - $errors = $this->analyse(__DIR__ . '/data/PropertyTypeAttribute.php'); + $errors = $this->analyse(__DIR__ . '/data/Type/PropertyTypeAttribute.php'); $this->assertCount(0, $errors); } public function testInvalidPropertyTypeAttribute(): void { - $errors = $this->analyse(__DIR__ . '/data/InvalidPropertyTypeAttribute.php'); + $errors = $this->analyse(__DIR__ . '/data/Type/InvalidPropertyTypeAttribute.php'); $expectedErrors = [ 'Attribute class PhpStaticAnalysis\Attributes\Type does not have the class target.' => 7, diff --git a/tests/data/InvalidPropertyIsReadOnlyAttribute.php b/tests/data/IsReadOnly/InvalidPropertyIsReadOnlyAttribute.php similarity index 87% rename from tests/data/InvalidPropertyIsReadOnlyAttribute.php rename to tests/data/IsReadOnly/InvalidPropertyIsReadOnlyAttribute.php index f291089..98ffc70 100644 --- a/tests/data/InvalidPropertyIsReadOnlyAttribute.php +++ b/tests/data/IsReadOnly/InvalidPropertyIsReadOnlyAttribute.php @@ -1,6 +1,6 @@ $name = $value; + } } $class = new ClassPropertyAttribute(); $foo = $class->name; -$bar = $class->age; +$class->age = 7; $indexes = $class->index1 + $class->index2; diff --git a/tests/data/InvalidClassPropertyAttribute.php b/tests/data/Property/InvalidClassPropertyAttribute.php similarity index 68% rename from tests/data/InvalidClassPropertyAttribute.php rename to tests/data/Property/InvalidClassPropertyAttribute.php index 5deb135..0f812df 100644 --- a/tests/data/InvalidClassPropertyAttribute.php +++ b/tests/data/Property/InvalidClassPropertyAttribute.php @@ -1,6 +1,6 @@ name; +$bar = $class->age; +$indexes = $class->index1 + $class->index2; diff --git a/tests/data/PropertyRead/InvalidClassPropertyReadAttribute.php b/tests/data/PropertyRead/InvalidClassPropertyReadAttribute.php new file mode 100644 index 0000000..de9109e --- /dev/null +++ b/tests/data/PropertyRead/InvalidClassPropertyReadAttribute.php @@ -0,0 +1,21 @@ +age = 7; diff --git a/tests/data/PropertyWrite/ClassPropertyWriteAttribute.php b/tests/data/PropertyWrite/ClassPropertyWriteAttribute.php new file mode 100644 index 0000000..05d1d40 --- /dev/null +++ b/tests/data/PropertyWrite/ClassPropertyWriteAttribute.php @@ -0,0 +1,25 @@ +$name = $value; + } +} + +$class = new ClassPropertyWriteAttribute(); +$class->name = 'John'; +$class->age = 7; +$class->index1 = []; +$class->index2 = []; diff --git a/tests/data/PropertyWrite/InvalidClassPropertyWriteAttribute.php b/tests/data/PropertyWrite/InvalidClassPropertyWriteAttribute.php new file mode 100644 index 0000000..691766d --- /dev/null +++ b/tests/data/PropertyWrite/InvalidClassPropertyWriteAttribute.php @@ -0,0 +1,21 @@ +age; diff --git a/tests/data/FunctionReturnsAttribute.php b/tests/data/Returns/FunctionReturnsAttribute.php similarity index 68% rename from tests/data/FunctionReturnsAttribute.php rename to tests/data/Returns/FunctionReturnsAttribute.php index efab30d..c0c153d 100644 --- a/tests/data/FunctionReturnsAttribute.php +++ b/tests/data/Returns/FunctionReturnsAttribute.php @@ -1,6 +1,6 @@