From 733d86203e622100e82753528b54caffaef49377 Mon Sep 17 00:00:00 2001 From: Carlos Granados Date: Tue, 8 Oct 2024 19:50:30 +0200 Subject: [PATCH] Update to PHPStan 2.0 --- .github/workflows/all_tests.yml | 8 +++++-- composer.json | 24 ++++++++++++------- phpstan.neon | 5 ++-- psalm.xml | 1 - tests/AssertAttributeTest.php | 2 +- tests/AssertIfFalseAttributeTest.php | 2 +- tests/AssertIfTrueAttributeTest.php | 2 +- tests/DefineTypeAttributeTest.php | 7 +++--- tests/DeprecatedAttributeTest.php | 1 - tests/ImmutableAttributeTest.php | 4 +++- tests/ImportTypeAttributeTest.php | 3 +-- tests/ImpureAttributeTest.php | 2 +- tests/InternalAttributeTest.php | 2 -- tests/IsReadOnlyAttributeTest.php | 12 ---------- tests/MethodAttributeTest.php | 5 ++-- tests/MixinAttributeTest.php | 5 ++-- tests/ParamAttributeTest.php | 7 +++--- tests/ParamOutAttributeTest.php | 7 +++--- tests/PropertyAttributeTest.php | 7 +++--- tests/PropertyReadAttributeTest.php | 7 +++--- tests/PropertyWriteAttributeTest.php | 7 +++--- tests/PureAttributeTest.php | 2 +- tests/RequireExtendsAttributeTest.php | 4 +--- tests/RequireImplementsAttributeTest.php | 3 +-- tests/ReturnsAttributeTest.php | 7 ++---- tests/SelfOutAttributeTest.php | 4 +--- tests/TemplateAttributeTest.php | 6 ++--- tests/TemplateContravariantAttributeTest.php | 6 ++--- tests/TemplateCovariantAttributeTest.php | 11 +++++---- tests/TemplateExtendsAttributeTest.php | 6 ++--- tests/TemplateImplementsAttributeTest.php | 5 ++-- tests/ThrowsAttributeTest.php | 3 +-- tests/TypeAttributeTest.php | 7 ++---- .../MethodAssertIfFalseAttribute.php | 4 +++- .../MethodAssertIfTrueAttribute.php | 4 +++- tests/data/Throws/MethodThrowsAttribute.php | 3 +-- 36 files changed, 84 insertions(+), 111 deletions(-) diff --git a/.github/workflows/all_tests.yml b/.github/workflows/all_tests.yml index f23a0ed..522ffeb 100644 --- a/.github/workflows/all_tests.yml +++ b/.github/workflows/all_tests.yml @@ -14,10 +14,10 @@ jobs: fail-fast: false matrix: php-version: - - "8.0" - "8.1" - "8.2" - "8.3" + - "8.4" steps: - name: "Checkout" @@ -44,4 +44,8 @@ jobs: run: "composer install --no-interaction --no-progress" - name: "Run tests" - run: "composer tests" \ No newline at end of file + run: "composer tests-without-psalm" + + - name: "Run Psalm" + if: matrix.php-version != '8.4' # Psalm does not fully support PHP 8.4 yet + run: "composer psalm" \ No newline at end of file diff --git a/composer.json b/composer.json index 6d53369..d4ede7b 100644 --- a/composer.json +++ b/composer.json @@ -23,18 +23,18 @@ "minimum-stability": "dev", "prefer-stable": true, "require": { - "php": ">=8.0", - "php-static-analysis/attributes": "^0.3.1 || dev-main", - "php-static-analysis/node-visitor": "^0.3.1 || dev-main", - "phpstan/phpstan": "^1.8", + "php": ">=8.1", + "php-static-analysis/attributes": "^0.4.0 || dev-main", + "php-static-analysis/node-visitor": "^0.4.0 || dev-main", + "phpstan/phpstan": "^2.0", "webmozart/assert": "^1.11" }, "require-dev": { - "php-static-analysis/psalm-plugin": "dev-main", - "phpstan/phpstan-deprecation-rules": "^1.1", + "php-static-analysis/psalm-plugin": "^0.4.0 || dev-main", + "phpstan/phpstan-deprecation-rules": "^2.0", "phpunit/phpunit": "^9.0", "symplify/easy-coding-standard": "^12.1", - "vimeo/psalm": "^5" + "vimeo/psalm": "dev-master" }, "extra": { "phpstan": { @@ -44,7 +44,10 @@ } }, "config": { - "sort-packages": true + "sort-packages": true, + "allow-plugins": { + "php-static-analysis/psalm-plugin": true + } }, "scripts": { "phpstan": "phpstan analyse", @@ -58,6 +61,11 @@ "@phpstan", "@phpunit", "@psalm" + ], + "tests-without-psalm": [ + "@ecs", + "@phpstan", + "@phpunit" ] } } diff --git a/phpstan.neon b/phpstan.neon index 3f21a8f..dfd18fc 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,6 +1,5 @@ includes: - extension.neon - - phar://phpstan.phar/conf/bleedingEdge.neon parameters: level: max @@ -11,8 +10,8 @@ parameters: - tests/data/* ignoreErrors: - - message: '#^Accessing [a-zA-Z\\]+::class is not covered by backward compatibility promise. The class might change in a minor PHPStan version.$#' + identifier: phpstanApi.classConstant path: tests/BaseAttributeTestCase.php - - message: '#^Calling [a-zA-Z\\]+::[a-zA-Z]+\(\) is not covered by backward compatibility promise. The method might change in a minor PHPStan version.$#' + identifier: phpstanApi.method path: tests/BaseAttributeTestCase.php diff --git a/psalm.xml b/psalm.xml index 55a8ab4..94cb42c 100644 --- a/psalm.xml +++ b/psalm.xml @@ -12,7 +12,6 @@ - diff --git a/tests/AssertAttributeTest.php b/tests/AssertAttributeTest.php index 724216c..bdf2659 100644 --- a/tests/AssertAttributeTest.php +++ b/tests/AssertAttributeTest.php @@ -21,7 +21,7 @@ public function testInvalidMethodAssertAttribute(): void $errors = $this->analyse(__DIR__ . '/data/Assert/InvalidMethodAssertAttribute.php'); $expectedErrors = [ - 'Parameter #1 ...$params of attribute class PhpStaticAnalysis\Attributes\Assert constructor expects string, int given.' => 9, + 'PHPDoc tag @phpstan-assert has invalid value (): Unexpected token "\n ", expected type at offset 22 on line 2' => 10, 'Attribute class PhpStaticAnalysis\Attributes\Assert does not have the property target.' => 14, ]; diff --git a/tests/AssertIfFalseAttributeTest.php b/tests/AssertIfFalseAttributeTest.php index 387a94e..dd7daf6 100644 --- a/tests/AssertIfFalseAttributeTest.php +++ b/tests/AssertIfFalseAttributeTest.php @@ -22,7 +22,7 @@ public function testInvalidMethodAssertIfFalseAttribute(): void $errors = $this->analyse(__DIR__ . '/data/AssertIfFalse/InvalidMethodAssertIfFalseAttribute.php'); $expectedErrors = [ - 'Parameter #1 ...$params of attribute class PhpStaticAnalysis\Attributes\AssertIfFalse constructor expects string, int given.' => 9, + 'PHPDoc tag @phpstan-assert-if-false has invalid value (): Unexpected token "\n ", expected type at offset 31 on line 2' => 10, 'Attribute class PhpStaticAnalysis\Attributes\AssertIfFalse does not have the property target.' => 15, ]; diff --git a/tests/AssertIfTrueAttributeTest.php b/tests/AssertIfTrueAttributeTest.php index 16bee61..24865ee 100644 --- a/tests/AssertIfTrueAttributeTest.php +++ b/tests/AssertIfTrueAttributeTest.php @@ -22,7 +22,7 @@ public function testInvalidMethodAssertIfTrueAttribute(): void $errors = $this->analyse(__DIR__ . '/data/AssertIfTrue/InvalidMethodAssertIfTrueAttribute.php'); $expectedErrors = [ - 'Parameter #1 ...$params of attribute class PhpStaticAnalysis\Attributes\AssertIfTrue constructor expects string, int given.' => 9, + 'PHPDoc tag @phpstan-assert-if-true has invalid value (): Unexpected token "\n ", expected type at offset 30 on line 2' => 10, 'Attribute class PhpStaticAnalysis\Attributes\AssertIfTrue does not have the property target.' => 15, ]; diff --git a/tests/DefineTypeAttributeTest.php b/tests/DefineTypeAttributeTest.php index dc23dd9..ffe1e06 100644 --- a/tests/DefineTypeAttributeTest.php +++ b/tests/DefineTypeAttributeTest.php @@ -27,11 +27,10 @@ public function testInvalidClassDefineTypeAttribute(): void $errors = $this->analyse(__DIR__ . '/data/DefineType/InvalidClassDefineTypeAttribute.php'); $expectedErrors = [ - 'PHPDoc tag @phpstan-type has invalid value (): Unexpected token "\n * ", expected type at offset 20' => 7, - 'PHPDoc tag @phpstan-type name has invalid value: Unexpected token "(", expected TOKEN_PHPDOC_EOL at offset 72' => 7, - 'PHPDoc tag @phpstan-type string has invalid value: Unexpected token "\n * ", expected type at offset 44' => 7, - 'Parameter #1 ...$types of attribute class PhpStaticAnalysis\Attributes\DefineType constructor expects string, int given.' => 7, 'Type alias has an invalid name: string.' => 7, + 'PHPDoc tag @phpstan-type has invalid value (): Unexpected token "\n * ", expected type at offset 20 on line 2' => 8, + 'PHPDoc tag @phpstan-type string has invalid value: Unexpected token "\n * ", expected type at offset 44 on line 3' => 9, + 'PHPDoc tag @phpstan-type name has invalid value: Unexpected token "(", expected TOKEN_PHPDOC_EOL at offset 72 on line 4' => 10, 'Attribute class PhpStaticAnalysis\Attributes\DefineType does not have the method target.' => 12, ]; diff --git a/tests/DeprecatedAttributeTest.php b/tests/DeprecatedAttributeTest.php index 5715810..e28c4f1 100644 --- a/tests/DeprecatedAttributeTest.php +++ b/tests/DeprecatedAttributeTest.php @@ -54,7 +54,6 @@ public function testInvalidMethodDeprecatedAttribute(): void $expectedErrors = [ 'Attribute class PhpStaticAnalysis\Attributes\Deprecated does not have the parameter target.' => 12, - 'Attribute class PhpStaticAnalysis\Attributes\Deprecated is not repeatable but is already present above the method.' => 19, ]; $this->checkExpectedErrors($errors, $expectedErrors); diff --git a/tests/ImmutableAttributeTest.php b/tests/ImmutableAttributeTest.php index e61fcff..dc3d71f 100644 --- a/tests/ImmutableAttributeTest.php +++ b/tests/ImmutableAttributeTest.php @@ -9,6 +9,8 @@ public function testClassImmutableAttribute(): void { $errors = $this->analyse(__DIR__ . '/data/Immutable/ClassImmutableAttribute.php'); $expectedErrors = [ + '@readonly property cannot have a default value.' => 10, + '@readonly property test\PhpStaticAnalysis\PHPStanExtension\data\Immutable\ClassImmutableAttribute::$name is assigned outside of its declaring class.' => 14, ]; $this->checkExpectedErrors($errors, $expectedErrors); @@ -31,8 +33,8 @@ public function testInvalidClassImmutableAttribute(): void $errors = $this->analyse(__DIR__ . '/data/Immutable/InvalidClassImmutableAttribute.php'); $expectedErrors = [ - 'Attribute class PhpStaticAnalysis\Attributes\Immutable is not repeatable but is already present above the class.' => 10, 'Attribute class PhpStaticAnalysis\Attributes\Immutable does not have the property target.' => 13, + '@readonly property cannot have a default value.' => 14, ]; $this->checkExpectedErrors($errors, $expectedErrors); diff --git a/tests/ImportTypeAttributeTest.php b/tests/ImportTypeAttributeTest.php index e9aba3e..c18ebd6 100644 --- a/tests/ImportTypeAttributeTest.php +++ b/tests/ImportTypeAttributeTest.php @@ -27,8 +27,7 @@ public function testInvalidClassImportTypeAttribute(): void $errors = $this->analyse(__DIR__ . '/data/ImportType/InvalidClassImportTypeAttribute.php'); $expectedErrors = [ - 'PHPDoc tag @phpstan-import-type has invalid value (Unexpected token "(", expected \'*/\' at offset 98 on line 4): Unexpected token "(", expected \'*/\' at offset 98' => 8, - 'Parameter #1 ...$from of attribute class PhpStaticAnalysis\Attributes\ImportType constructor expects string, int given.' => 8, + 'PHPDoc tag @phpstan-import-type has invalid value (Unexpected token "(", expected \'*/\' at offset 98 on line 4): Unexpected token "(", expected \'*/\' at offset 98 on line 4' => 11, 'Attribute class PhpStaticAnalysis\Attributes\ImportType does not have the method target.' => 13, ]; diff --git a/tests/ImpureAttributeTest.php b/tests/ImpureAttributeTest.php index 25baa28..3c3da02 100644 --- a/tests/ImpureAttributeTest.php +++ b/tests/ImpureAttributeTest.php @@ -22,7 +22,7 @@ public function testInvalidMethodImpureAttribute(): void $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, + 'Method test\PhpStaticAnalysis\PHPStanExtension\data\Impure\InvalidMethodImpureAttribute::getMoreName() is marked as impure but does not have any side effects.' => 14, ]; $this->checkExpectedErrors($errors, $expectedErrors); diff --git a/tests/InternalAttributeTest.php b/tests/InternalAttributeTest.php index fdede1c..85b38a6 100644 --- a/tests/InternalAttributeTest.php +++ b/tests/InternalAttributeTest.php @@ -44,9 +44,7 @@ public function testInvalidMethodInternalAttribute(): void { $errors = $this->analyse(__DIR__ . '/data/Internal/InvalidMethodInternalAttribute.php'); $expectedErrors = [ - 'Parameter #1 $namespace of attribute class PhpStaticAnalysis\Attributes\Internal constructor expects string|null, int given.' => 9, 'Attribute class PhpStaticAnalysis\Attributes\Internal does not have the parameter target.' => 15, - 'Attribute class PhpStaticAnalysis\Attributes\Internal is not repeatable but is already present above the method.' => 22, ]; $this->checkExpectedErrors($errors, $expectedErrors); diff --git a/tests/IsReadOnlyAttributeTest.php b/tests/IsReadOnlyAttributeTest.php index e6154a7..502964f 100644 --- a/tests/IsReadOnlyAttributeTest.php +++ b/tests/IsReadOnlyAttributeTest.php @@ -19,21 +19,9 @@ public function testInvalidPropertyIsReadOnlyAttribute(): void $errors = $this->analyse(__DIR__ . '/data/IsReadOnly/InvalidPropertyIsReadOnlyAttribute.php'); $expectedErrors = [ - 'Attribute class PhpStaticAnalysis\Attributes\IsReadOnly constructor invoked with 1 parameter, 0 required.' => 9, - 'Attribute class PhpStaticAnalysis\Attributes\IsReadOnly is not repeatable but is already present above the property.' => 13, 'Attribute class PhpStaticAnalysis\Attributes\IsReadOnly does not have the method target.' => 16, ]; $this->checkExpectedErrors($errors, $expectedErrors); } - - public static function getAdditionalConfigFiles(): array - { - return array_merge( - parent::getAdditionalConfigFiles(), - [ - __DIR__ . '/conf/readonly.neon', - ] - ); - } } diff --git a/tests/MethodAttributeTest.php b/tests/MethodAttributeTest.php index c1b13de..2267f7d 100644 --- a/tests/MethodAttributeTest.php +++ b/tests/MethodAttributeTest.php @@ -27,9 +27,8 @@ public function testInvalidClassMethodAttribute(): void $errors = $this->analyse(__DIR__ . '/data/Method/InvalidClassMethodAttribute.php'); $expectedErrors = [ - 'PHPDoc tag @method has invalid value (): Unexpected token "\n * ", expected type at offset 14' => 8, - 'PHPDoc tag @method has invalid value (string): Unexpected token "\n * ", expected \'(\' at offset 32' => 8, - 'Parameter #1 ...$methods of attribute class PhpStaticAnalysis\Attributes\Method constructor expects string, int given.' => 8, + 'PHPDoc tag @method has invalid value (): Unexpected token "\n * ", expected type at offset 14 on line 2' => 9, + 'PHPDoc tag @method has invalid value (string): Unexpected token "\n * ", expected \'(\' at offset 32 on line 3' => 10, 'Attribute class PhpStaticAnalysis\Attributes\Method does not have the method target.' => 13, 'Call to an undefined method test\PhpStaticAnalysis\PHPStanExtension\data\Method\InvalidClassMethodAttribute::badFunction().' => 31, ]; diff --git a/tests/MixinAttributeTest.php b/tests/MixinAttributeTest.php index fe1d75c..f73b303 100644 --- a/tests/MixinAttributeTest.php +++ b/tests/MixinAttributeTest.php @@ -27,9 +27,8 @@ public function testInvalidClassMixinAttribute(): void $errors = $this->analyse(__DIR__ . '/data/Mixin/InvalidClassMixinAttribute.php'); $expectedErrors = [ - 'PHPDoc tag @mixin contains unknown class test\PhpStaticAnalysis\PHPStanExtension\data\Mixin\count.' => 7, - 'PHPDoc tag @mixin has invalid value (): Unexpected token "\n * ", expected type at offset 13' => 7, - 'Parameter #1 ...$classes of attribute class PhpStaticAnalysis\Attributes\Mixin constructor expects string, int given.' => 7, + 'PHPDoc tag @mixin has invalid value (): Unexpected token "\n * ", expected type at offset 13 on line 2' => 8, + 'PHPDoc tag @mixin has invalid value (count($a)): Unexpected token "(", expected TOKEN_HORIZONTAL_WS at offset 29 on line 3' => 9, 'Attribute class PhpStaticAnalysis\Attributes\Mixin does not have the method target.' => 11, ]; diff --git a/tests/ParamAttributeTest.php b/tests/ParamAttributeTest.php index aa93317..b28d695 100644 --- a/tests/ParamAttributeTest.php +++ b/tests/ParamAttributeTest.php @@ -21,10 +21,9 @@ public function testInvalidMethodParamAttribute(): void $errors = $this->analyse(__DIR__ . '/data/Param/InvalidMethodParamAttribute.php'); $expectedErrors = [ - 'PHPDoc tag @param has invalid value (): Unexpected token "\n ", expected type at offset 13' => 9, - 'Parameter #1 ...$params of attribute class PhpStaticAnalysis\Attributes\Param constructor expects string, int given.' => 9, - 'PHPDoc tag @param has invalid value (string): Unexpected token "\n ", expected variable at offset 20' => 15, - 'PHPDoc tag @param has invalid value (count($a) $name): Unexpected token "(", expected variable at offset 19' => 21, + 'PHPDoc tag @param has invalid value (): Unexpected token "\n ", expected type at offset 13 on line 2' => 10, + 'PHPDoc tag @param has invalid value (string): Unexpected token "\n ", expected variable at offset 20 on line 2' => 16, + 'PHPDoc tag @param has invalid value (count($a) $name): Unexpected token "(", expected variable at offset 19 on line 2' => 22, 'Attribute class PhpStaticAnalysis\Attributes\Param does not have the property target.' => 27, ]; diff --git a/tests/ParamOutAttributeTest.php b/tests/ParamOutAttributeTest.php index 6f6c8d1..7b52e0d 100644 --- a/tests/ParamOutAttributeTest.php +++ b/tests/ParamOutAttributeTest.php @@ -21,10 +21,9 @@ public function testInvalidMethodParamOutAttribute(): void $errors = $this->analyse(__DIR__ . '/data/ParamOut/InvalidMethodParamOutAttribute.php'); $expectedErrors = [ - 'PHPDoc tag @param-out has invalid value (): Unexpected token "\n ", expected type at offset 17' => 9, - 'Parameter #1 ...$params of attribute class PhpStaticAnalysis\Attributes\ParamOut constructor expects string, int given.' => 9, - 'PHPDoc tag @param-out has invalid value (string): Unexpected token "\n ", expected variable at offset 24' => 15, - 'PHPDoc tag @param-out has invalid value (count($a) $name): Unexpected token "(", expected variable at offset 23' => 21, + 'PHPDoc tag @param-out has invalid value (): Unexpected token "\n ", expected type at offset 17 on line 2' => 10, + 'PHPDoc tag @param-out has invalid value (string): Unexpected token "\n ", expected variable at offset 24 on line 2' => 16, + 'PHPDoc tag @param-out has invalid value (count($a) $name): Unexpected token "(", expected variable at offset 23 on line 2' => 22, 'Attribute class PhpStaticAnalysis\Attributes\ParamOut does not have the property target.' => 27, ]; diff --git a/tests/PropertyAttributeTest.php b/tests/PropertyAttributeTest.php index 659539f..5fd999c 100644 --- a/tests/PropertyAttributeTest.php +++ b/tests/PropertyAttributeTest.php @@ -27,10 +27,9 @@ public function testInvalidClassPropertyAttribute(): void $errors = $this->analyse(__DIR__ . '/data/Property/InvalidClassPropertyAttribute.php'); $expectedErrors = [ - 'PHPDoc tag @property has invalid value (): Unexpected token "\n * ", expected type at offset 16' => 7, - 'PHPDoc tag @property has invalid value (count($a) $name): Unexpected token "(", expected variable at offset 55' => 7, - 'PHPDoc tag @property has invalid value (string): Unexpected token "\n * ", expected variable at offset 36' => 7, - 'Parameter #1 ...$properties of attribute class PhpStaticAnalysis\Attributes\Property constructor expects string, int given.' => 7, + 'PHPDoc tag @property has invalid value (): Unexpected token "\n * ", expected type at offset 16 on line 2' => 8, + 'PHPDoc tag @property has invalid value (string): Unexpected token "\n * ", expected variable at offset 36 on line 3' => 9, + 'PHPDoc tag @property has invalid value (count($a) $name): Unexpected token "(", expected variable at offset 55 on line 4' => 10, 'Attribute class PhpStaticAnalysis\Attributes\Property does not have the method target.' => 12, ]; diff --git a/tests/PropertyReadAttributeTest.php b/tests/PropertyReadAttributeTest.php index 578a0ba..8bcbf09 100644 --- a/tests/PropertyReadAttributeTest.php +++ b/tests/PropertyReadAttributeTest.php @@ -27,10 +27,9 @@ 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 ...$properties of attribute class PhpStaticAnalysis\Attributes\PropertyRead constructor expects string, int given.' => 7, + 'PHPDoc tag @property-read has invalid value (): Unexpected token "\n * ", expected type at offset 21 on line 2' => 8, + 'PHPDoc tag @property-read has invalid value (string): Unexpected token "\n * ", expected variable at offset 46 on line 3' => 9, + 'PHPDoc tag @property-read has invalid value (count($a) $name): Unexpected token "(", expected variable at offset 70 on line 4' => 10, 'Attribute class PhpStaticAnalysis\Attributes\PropertyRead does not have the method target.' => 13, 'Property test\PhpStaticAnalysis\PHPStanExtension\data\PropertyRead\ClassPropertyReadAttribute::$age is not writable.' => 21, ]; diff --git a/tests/PropertyWriteAttributeTest.php b/tests/PropertyWriteAttributeTest.php index 2da8680..0c0402e 100644 --- a/tests/PropertyWriteAttributeTest.php +++ b/tests/PropertyWriteAttributeTest.php @@ -27,10 +27,9 @@ 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 ...$properties of attribute class PhpStaticAnalysis\Attributes\PropertyWrite constructor expects string, int given.' => 7, + 'PHPDoc tag @property-write has invalid value (): Unexpected token "\n * ", expected type at offset 22 on line 2' => 8, + 'PHPDoc tag @property-write has invalid value (string): Unexpected token "\n * ", expected variable at offset 48 on line 3' => 9, + 'PHPDoc tag @property-write has invalid value (count($a) $name): Unexpected token "(", expected variable at offset 73 on line 4' => 10, 'Attribute class PhpStaticAnalysis\Attributes\PropertyWrite does not have the method target.' => 13, 'Property test\PhpStaticAnalysis\PHPStanExtension\data\PropertyWrite\ClassPropertyWriteAttribute::$age is not readable.' => 21, ]; diff --git a/tests/PureAttributeTest.php b/tests/PureAttributeTest.php index 82662ed..77998d7 100644 --- a/tests/PureAttributeTest.php +++ b/tests/PureAttributeTest.php @@ -22,7 +22,7 @@ public function testInvalidMethodPureAttribute(): void $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, + 'Method test\PhpStaticAnalysis\PHPStanExtension\data\Pure\InvalidMethodPureAttribute::getMoreName() is marked as pure but returns void.' => 14, ]; $this->checkExpectedErrors($errors, $expectedErrors); diff --git a/tests/RequireExtendsAttributeTest.php b/tests/RequireExtendsAttributeTest.php index 8043694..6b04977 100644 --- a/tests/RequireExtendsAttributeTest.php +++ b/tests/RequireExtendsAttributeTest.php @@ -19,11 +19,9 @@ public function testInvalidClassRequireExtendsAttribute(): void $errors = $this->analyse(__DIR__ . '/data/RequireExtends/InvalidTraitRequireExtendsAttribute.php'); $expectedErrors = [ - 'PHPDoc tag @phpstan-require-extends has invalid value (): Unexpected token "\n ", expected type at offset 31' => 7, - 'Parameter #1 $class of attribute class PhpStaticAnalysis\Attributes\RequireExtends constructor expects string, int given.' => 7, + 'PHPDoc tag @phpstan-require-extends has invalid value (): Unexpected token "\n ", expected type at offset 31 on line 2' => 8, 'PHPDoc tag @phpstan-require-extends contains non-object type int.' => 12, 'PHPDoc tag @phpstan-require-extends can only be used once.' => 17, - 'Attribute class PhpStaticAnalysis\Attributes\RequireExtends is not repeatable but is already present above the class.' => 18, 'Attribute class PhpStaticAnalysis\Attributes\RequireExtends does not have the property target.' => 21, ]; diff --git a/tests/RequireImplementsAttributeTest.php b/tests/RequireImplementsAttributeTest.php index 1a2d573..da1976e 100644 --- a/tests/RequireImplementsAttributeTest.php +++ b/tests/RequireImplementsAttributeTest.php @@ -19,8 +19,7 @@ public function testInvalidClassRequireImplementsAttribute(): void $errors = $this->analyse(__DIR__ . '/data/RequireImplements/InvalidTraitRequireImplementsAttribute.php'); $expectedErrors = [ - 'PHPDoc tag @phpstan-require-implements has invalid value (): Unexpected token "\n ", expected type at offset 34' => 7, - 'Parameter #1 ...$interfaces of attribute class PhpStaticAnalysis\Attributes\RequireImplements constructor expects string, int given.' => 7, + 'PHPDoc tag @phpstan-require-implements has invalid value (): Unexpected token "\n ", expected type at offset 34 on line 2' => 8, 'PHPDoc tag @phpstan-require-implements contains non-object type int.' => 12, 'Attribute class PhpStaticAnalysis\Attributes\RequireImplements does not have the property target.' => 15, ]; diff --git a/tests/ReturnsAttributeTest.php b/tests/ReturnsAttributeTest.php index cbdc860..4b6a538 100644 --- a/tests/ReturnsAttributeTest.php +++ b/tests/ReturnsAttributeTest.php @@ -21,11 +21,8 @@ public function testInvalidMethodReturnsAttribute(): void $errors = $this->analyse(__DIR__ . '/data/Returns/InvalidMethodReturnsAttribute.php'); $expectedErrors = [ - 'PHPDoc tag @return has invalid value (): Unexpected token "\n ", expected type at offset 14' => 9, - 'Parameter #1 $type of attribute class PhpStaticAnalysis\Attributes\Returns constructor expects string, int given.' => 9, - 'Attribute class PhpStaticAnalysis\Attributes\Returns is not repeatable but is already present above the method.' => 16, - 'Attribute class PhpStaticAnalysis\Attributes\Returns constructor invoked with 2 parameters, 1 required.' => 22, - 'PHPDoc tag @return has invalid value ($a + $b): Unexpected token "$a", expected type at offset 15' => 28, + 'PHPDoc tag @return has invalid value (): Unexpected token "\n ", expected type at offset 14 on line 2' => 10, + 'PHPDoc tag @return has invalid value ($a + $b): Unexpected token "$a", expected type at offset 15 on line 2' => 29, 'Attribute class PhpStaticAnalysis\Attributes\Returns does not have the property target.' => 34, ]; diff --git a/tests/SelfOutAttributeTest.php b/tests/SelfOutAttributeTest.php index 8067f3c..ca810d2 100644 --- a/tests/SelfOutAttributeTest.php +++ b/tests/SelfOutAttributeTest.php @@ -15,9 +15,7 @@ public function testInvalidMethodSelfOutAttribute(): void $errors = $this->analyse(__DIR__ . '/data/SelfOut/InvalidMethodSelfOutAttribute.php'); $expectedErrors = [ - 'PHPDoc tag @phpstan-self-out has invalid value (): Unexpected token "\n ", expected type at offset 75' => 12, - 'Parameter #1 $type of attribute class PhpStaticAnalysis\Attributes\SelfOut constructor expects string, int given.' => 14, - 'Attribute class PhpStaticAnalysis\Attributes\SelfOut is not repeatable but is already present above the method.' => 22, + 'PHPDoc tag @phpstan-self-out has invalid value (): Unexpected token "\n ", expected type at offset 75 on line 4' => 15, 'Attribute class PhpStaticAnalysis\Attributes\SelfOut does not have the property target.' => 27, ]; diff --git a/tests/TemplateAttributeTest.php b/tests/TemplateAttributeTest.php index 747ef9a..985d6d5 100644 --- a/tests/TemplateAttributeTest.php +++ b/tests/TemplateAttributeTest.php @@ -39,11 +39,9 @@ public function testInvalidMethodTemplateAttribute(): void $errors = $this->analyse(__DIR__ . '/data/Template/InvalidMethodTemplateAttribute.php'); $expectedErrors = [ - 'PHPDoc tag @template has invalid value (): Unexpected token "\n ", expected type at offset 16' => 11, - 'Parameter #1 $name of attribute class PhpStaticAnalysis\Attributes\Template constructor expects string, int given.' => 11, - 'PHPDoc tag @template has invalid value (+5): Unexpected token "+5", expected type at offset 17' => 17, + 'PHPDoc tag @template has invalid value (): Unexpected token "\n ", expected type at offset 16 on line 2' => 12, + 'PHPDoc tag @template has invalid value (+5): Unexpected token "+5", expected type at offset 17 on line 2' => 18, 'Attribute class PhpStaticAnalysis\Attributes\Template does not have the property target.' => 23, - 'Parameter #2 $of of attribute class PhpStaticAnalysis\Attributes\Template constructor expects string|null, int given.' => 26 ]; $this->checkExpectedErrors($errors, $expectedErrors); diff --git a/tests/TemplateContravariantAttributeTest.php b/tests/TemplateContravariantAttributeTest.php index d7b21ea..1347e47 100644 --- a/tests/TemplateContravariantAttributeTest.php +++ b/tests/TemplateContravariantAttributeTest.php @@ -27,10 +27,8 @@ public function testInvalidClassTemplateContravariantAttribute(): void $errors = $this->analyse(__DIR__ . '/data/TemplateContravariant/InvalidClassTemplateContravariantAttribute.php'); $expectedErrors = [ - 'PHPDoc tag @template-contravariant has invalid value (): Unexpected token "\n * ", expected type at offset 30' => 7, - 'PHPDoc tag @template-contravariant has invalid value (+5): Unexpected token "+5", expected type at offset 58' => 7, - 'Parameter #1 $name of attribute class PhpStaticAnalysis\Attributes\TemplateContravariant constructor expects string, int given.' => 7, - 'Parameter #2 $of of attribute class PhpStaticAnalysis\Attributes\TemplateContravariant constructor expects string|null, int given.' => 9, + 'PHPDoc tag @template-contravariant has invalid value (): Unexpected token "\n * ", expected type at offset 30 on line 2' => 8, + 'PHPDoc tag @template-contravariant has invalid value (+5): Unexpected token "+5", expected type at offset 58 on line 3' => 9, 'Attribute class PhpStaticAnalysis\Attributes\TemplateContravariant does not have the property target.' => 12, ]; diff --git a/tests/TemplateCovariantAttributeTest.php b/tests/TemplateCovariantAttributeTest.php index bef34eb..507ddec 100644 --- a/tests/TemplateCovariantAttributeTest.php +++ b/tests/TemplateCovariantAttributeTest.php @@ -7,7 +7,10 @@ class TemplateCovariantAttributeTest extends BaseAttributeTestCase public function testClassTemplateCovariantAttribute(): void { $errors = $this->analyse(__DIR__ . '/data/TemplateCovariant/ClassTemplateCovariantAttribute.php'); - $this->assertCount(0, $errors); + $expectedErrors = [ + 'PHPDoc tag @var with type TCreable is not subtype of native type object.' => 28, + ]; + $this->checkExpectedErrors($errors, $expectedErrors); } public function testTraitTemplateCovariantAttribute(): void @@ -27,10 +30,8 @@ public function testInvalidClassTemplateCovariantAttribute(): void $errors = $this->analyse(__DIR__ . '/data/TemplateCovariant/InvalidClassTemplateCovariantAttribute.php'); $expectedErrors = [ - 'PHPDoc tag @template-covariant has invalid value (): Unexpected token "\n * ", expected type at offset 26' => 7, - 'PHPDoc tag @template-covariant has invalid value (+5): Unexpected token "+5", expected type at offset 50' => 7, - 'Parameter #1 $name of attribute class PhpStaticAnalysis\Attributes\TemplateCovariant constructor expects string, int given.' => 7, - 'Parameter #2 $of of attribute class PhpStaticAnalysis\Attributes\TemplateCovariant constructor expects string|null, int given.' => 9, + 'PHPDoc tag @template-covariant has invalid value (): Unexpected token "\n * ", expected type at offset 26 on line 2' => 8, + 'PHPDoc tag @template-covariant has invalid value (+5): Unexpected token "+5", expected type at offset 50 on line 3' => 9, 'Attribute class PhpStaticAnalysis\Attributes\TemplateCovariant does not have the property target.' => 12, ]; diff --git a/tests/TemplateExtendsAttributeTest.php b/tests/TemplateExtendsAttributeTest.php index dcca56f..b8c5306 100644 --- a/tests/TemplateExtendsAttributeTest.php +++ b/tests/TemplateExtendsAttributeTest.php @@ -16,11 +16,9 @@ public function testInvalidClassTemplateExtendsAttribute(): void $expectedErrors = [ 'Class test\PhpStaticAnalysis\PHPStanExtension\data\TemplateExtends\InvalidClassTemplateExtendsAttributeChild extends generic class test\PhpStaticAnalysis\PHPStanExtension\data\TemplateExtends\InvalidClassTemplateExtendsAttribute but does not specify its types: T' => 13, - 'PHPDoc tag @template-extends has invalid value (): Unexpected token "\n ", expected type at offset 24' => 13, - 'Parameter #1 $class of attribute class PhpStaticAnalysis\Attributes\TemplateExtends constructor expects string, int given.' => 13, + 'PHPDoc tag @template-extends has invalid value (): Unexpected token "\n ", expected type at offset 24 on line 2' => 14, 'Class test\PhpStaticAnalysis\PHPStanExtension\data\TemplateExtends\InvalidClassTemplateExtendsAttributeChild2 extends generic class test\PhpStaticAnalysis\PHPStanExtension\data\TemplateExtends\InvalidClassTemplateExtendsAttribute but does not specify its types: T' => 18, - 'PHPDoc tag @template-extends has invalid value (+5): Unexpected token "+5", expected type at offset 25' => 18, - 'Attribute class PhpStaticAnalysis\Attributes\TemplateExtends is not repeatable but is already present above the class.' => 24, + 'PHPDoc tag @template-extends has invalid value (+5): Unexpected token "+5", expected type at offset 25 on line 2' => 19, 'Attribute class PhpStaticAnalysis\Attributes\TemplateExtends does not have the property target.' => 27, ]; diff --git a/tests/TemplateImplementsAttributeTest.php b/tests/TemplateImplementsAttributeTest.php index b36f119..37ddc13 100644 --- a/tests/TemplateImplementsAttributeTest.php +++ b/tests/TemplateImplementsAttributeTest.php @@ -16,10 +16,9 @@ public function testInvalidInterfaceTemplateImplementsAttribute(): void $expectedErrors = [ 'Class test\PhpStaticAnalysis\PHPStanExtension\data\TemplateImplements\InvalidClassTemplateImplementsAttribute implements generic interface test\PhpStaticAnalysis\PHPStanExtension\data\TemplateImplements\InvalidInterfaceTemplateImplementsAttribute but does not specify its types: T' => 13, - 'PHPDoc tag @template-implements has invalid value (): Unexpected token "\n ", expected type at offset 27' => 13, - 'Parameter #1 ...$interfaces of attribute class PhpStaticAnalysis\Attributes\TemplateImplements constructor expects string, int given.' => 13, + 'PHPDoc tag @template-implements has invalid value (): Unexpected token "\n ", expected type at offset 27 on line 2' => 14, 'Class test\PhpStaticAnalysis\PHPStanExtension\data\TemplateImplements\InvalidClassTemplateImplementsAttribute2 implements generic interface test\PhpStaticAnalysis\PHPStanExtension\data\TemplateImplements\InvalidInterfaceTemplateImplementsAttribute but does not specify its types: T' => 18, - 'PHPDoc tag @template-implements has invalid value (+5): Unexpected token "+5", expected type at offset 28' => 18, + 'PHPDoc tag @template-implements has invalid value (+5): Unexpected token "+5", expected type at offset 28 on line 2' => 19, 'Attribute class PhpStaticAnalysis\Attributes\TemplateImplements does not have the property target.' => 21, ]; diff --git a/tests/ThrowsAttributeTest.php b/tests/ThrowsAttributeTest.php index ed4f363..77bdb2f 100644 --- a/tests/ThrowsAttributeTest.php +++ b/tests/ThrowsAttributeTest.php @@ -25,8 +25,7 @@ public function testInvalidMethodThrowsAttribute(): void $errors = $this->analyse(__DIR__ . '/data/Throws/InvalidMethodThrowsAttribute.php'); $expectedErrors = [ - 'PHPDoc tag @throws has invalid value (): Unexpected token "\n ", expected type at offset 14' => 10, - 'Parameter #1 ...$exceptions of attribute class PhpStaticAnalysis\Attributes\Throws constructor expects string, int given.' => 10, + 'PHPDoc tag @throws has invalid value (): Unexpected token "\n ", expected type at offset 14 on line 2' => 11, 'Method test\PhpStaticAnalysis\PHPStanExtension\data\Throws\InvalidMethodThrowsAttribute::getOtherNameLength() has string in PHPDoc @throws tag but it\'s not thrown.' => 16, 'PHPDoc tag @throws with type string is not subtype of Throwable' => 16, 'Attribute class PhpStaticAnalysis\Attributes\Throws does not have the property target.' => 22, diff --git a/tests/TypeAttributeTest.php b/tests/TypeAttributeTest.php index 14f03b3..08c4d3d 100644 --- a/tests/TypeAttributeTest.php +++ b/tests/TypeAttributeTest.php @@ -15,11 +15,8 @@ public function testInvalidPropertyTypeAttribute(): void $errors = $this->analyse(__DIR__ . '/data/Type/InvalidPropertyTypeAttribute.php'); $expectedErrors = [ - 'PHPDoc tag @var has invalid value (): Unexpected token "\n ", expected type at offset 11' => 9, - 'Parameter #1 $type of attribute class PhpStaticAnalysis\Attributes\Type constructor expects string, int given.' => 9, - 'Attribute class PhpStaticAnalysis\Attributes\Type is not repeatable but is already present above the property.' => 13, - 'Attribute class PhpStaticAnalysis\Attributes\Type constructor invoked with 2 parameters, 1 required.' => 16, - 'PHPDoc tag @var has invalid value ($a + $b): Unexpected token "$a", expected type at offset 12' => 19, + 'PHPDoc tag @var has invalid value (): Unexpected token "\n ", expected type at offset 11 on line 2' => 10, + 'PHPDoc tag @var has invalid value ($a + $b): Unexpected token "$a", expected type at offset 12 on line 2' => 20, 'Attribute class PhpStaticAnalysis\Attributes\Type does not have the parameter target.' => 23, ]; diff --git a/tests/data/AssertIfFalse/MethodAssertIfFalseAttribute.php b/tests/data/AssertIfFalse/MethodAssertIfFalseAttribute.php index cd2eddb..7b090d5 100644 --- a/tests/data/AssertIfFalse/MethodAssertIfFalseAttribute.php +++ b/tests/data/AssertIfFalse/MethodAssertIfFalseAttribute.php @@ -7,6 +7,8 @@ class MethodAssertIfFalseAttribute { + private mixed $name = 'name'; + #[AssertIfFalse(name: 'string')] // checks name is string public function checkString(mixed $name): bool { @@ -28,7 +30,7 @@ public function checkOtherString(mixed $name): bool #[AssertIfFalse('string $this->name')] public function checkOtherPropertyString(mixed $name): bool { - return !is_string($name); + return !is_string($this->name); } /** diff --git a/tests/data/AssertIfTrue/MethodAssertIfTrueAttribute.php b/tests/data/AssertIfTrue/MethodAssertIfTrueAttribute.php index 88d736a..4ae8e19 100644 --- a/tests/data/AssertIfTrue/MethodAssertIfTrueAttribute.php +++ b/tests/data/AssertIfTrue/MethodAssertIfTrueAttribute.php @@ -7,6 +7,8 @@ class MethodAssertIfTrueAttribute { + private mixed $name = 'name'; + #[AssertIfTrue(name: 'string')] // checks name is string public function checkString(mixed $name): bool { @@ -28,7 +30,7 @@ public function checkOtherString(mixed $name): bool #[AssertIfTrue('string $this->name')] public function checkOtherPropertyString(mixed $name): bool { - return is_string($name); + return is_string($this->name); } /** diff --git a/tests/data/Throws/MethodThrowsAttribute.php b/tests/data/Throws/MethodThrowsAttribute.php index 48bd955..bec07c8 100644 --- a/tests/data/Throws/MethodThrowsAttribute.php +++ b/tests/data/Throws/MethodThrowsAttribute.php @@ -70,9 +70,8 @@ public function countOtherTwoNames(string $name1, string $name2): int } #[Throws(Exception::class)] - public function countNoErrorName(string $name): int + public function countNoErrorName(): void { - return strlen($name); } /**