Skip to content

Commit bd9bd37

Browse files
authored
Switch to PHPStan 2.0 | Merge pull request #11 from ebln/phpstan2
### Addded - Support for PHPStan 2 ### Removed - Dropped support for PHPStan < 2 c.f. #10
2 parents e7d6d2f + 0991e2e commit bd9bd37

8 files changed

+805
-517
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,17 @@ Intended to follow [«Keep a Changelog»](https://keepachangelog.com/en/)
1717
}
1818
}
1919
```
20+
- consider updating [getClassNames](https://github.com/phpstan/phpstan-src/blob/e6d9f0c3ec251ea6fad604d3f97e02bedb4d7f42/src/Rules/Classes/InstantiationRule.php#L235)
2021

2122
----
2223

24+
## [2.0.0]
25+
26+
### Addded
27+
- Support for PHPStan 2
28+
### Removed
29+
- Dropped support for PHPStan < 2
30+
2331
## [1.0.1]
2432

2533
### Fixed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"require": {
1313
"php": "7.4 - 8.4",
1414
"ebln/phpstan-factory-mark": "^1.1",
15-
"phpstan/phpstan": "^1.11"
15+
"phpstan/phpstan": "^2.0"
1616
},
1717
"require-dev": {
1818
"ergebnis/composer-normalize": "^2.15",

composer.lock

Lines changed: 751 additions & 502 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

phpstan-baseline-7.4.neon

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,37 @@
11
parameters:
22
ignoreErrors:
33
-
4-
message: "#^Call to an undefined method ReflectionClass\\:\\:getAttributes\\(\\)\\.$#"
4+
message: '#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\.$#'
5+
identifier: foreach.nonIterable
6+
count: 1
57
path: src/ForceFactoryRule.php
68

79
-
8-
message: "#^Method Ebln\\\\PHPStan\\\\EnforceFactory\\\\ForceFactoryRule\\:\\:getFactoriesFromAttributeByClass\\(\\) has parameter \\$reflection with generic class ReflectionClass but does not specify its types\\: T$#"
10+
message: '#^Call to an undefined method ReflectionClass\:\:getAttributes\(\)\.$#'
11+
identifier: method.notFound
12+
count: 1
913
path: src/ForceFactoryRule.php
1014

1115
-
12-
message: "#^PHPDoc tag @param for parameter \\$reflection with type PHPStan\\\\BetterReflection\\\\Reflection\\\\Adapter\\\\ReflectionClass\\|PHPStan\\\\BetterReflection\\\\Reflection\\\\Adapter\\\\ReflectionEnum is not subtype of native type ReflectionClass\\.$#"
16+
message: '#^Cannot call method getName\(\) on mixed\.$#'
17+
identifier: method.nonObject
18+
count: 1
19+
path: src/ForceFactoryRule.php
20+
21+
-
22+
message: '#^Cannot call method newInstance\(\) on mixed\.$#'
23+
identifier: method.nonObject
24+
count: 1
25+
path: src/ForceFactoryRule.php
26+
27+
-
28+
message: '#^Method Ebln\\PHPStan\\EnforceFactory\\ForceFactoryRule\:\:getFactoriesFromAttributeByClass\(\) has parameter \$reflection with generic class ReflectionClass but does not specify its types\: T$#'
29+
identifier: missingType.generics
30+
count: 1
31+
path: src/ForceFactoryRule.php
32+
33+
-
34+
message: '#^PHPDoc tag @param for parameter \$reflection with type PHPStan\\BetterReflection\\Reflection\\Adapter\\ReflectionClass\|PHPStan\\BetterReflection\\Reflection\\Adapter\\ReflectionEnum is not subtype of native type ReflectionClass\.$#'
35+
identifier: parameter.phpDocType
36+
count: 1
1337
path: src/ForceFactoryRule.php

src/ForceFactoryRule.php

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,23 +44,28 @@ public function processNode(Node $node, Scope $scope): array
4444
if ([] === $allowedFactories) {
4545
$errors[] = RuleErrorBuilder::message(
4646
ltrim($class, '\\') . ' has either no factories defined or a conflict between interface and attribute!'
47-
)->build();
47+
)->identifier('ebln.forceFactory.bogusDefinition')
48+
->build()
49+
;
4850

4951
continue; // bogus configuration
5052
}
5153

5254
/** @psalm-suppress PossiblyNullReference | sad that even phpstan cannot infer that from isInClass */
5355
if (
5456
$scope->isInClass()
55-
&& null !== $scope->getClassReflection()
57+
&& null !== $scope->getClassReflection() /** @phpstan-ignore notIdentical.alwaysTrue */
5658
&& in_array($scope->getClassReflection()->getName(), $allowedFactories, true)
5759
) {
5860
continue; // happy case: ForceFactoryInterface got created within an allowed class
5961
}
6062

6163
$errors[] = RuleErrorBuilder::message(
6264
ltrim($class, '\\') . ' must be instantiated by ' . implode(' or ', $allowedFactories) . '!'
63-
)->build();
65+
)->identifier('ebln.forceFactory.outOfFactoryInstanciation')
66+
->tip('Only use ' . implode(' or ', $allowedFactories) . ' to create an instance of ' . ltrim($class, '\\') . '!')
67+
->build()
68+
;
6469
}
6570

6671
return $errors;
@@ -76,6 +81,7 @@ public function processNode(Node $node, Scope $scope): array
7681
private function getAllowedFactories(string $className): ?array
7782
{
7883
$allowedFactories = $this->getFactoriesFromAttribute($className);
84+
/** @phpstan-ignore-next-line phpstanApi.runtimeReflection (seems okay for now) */
7985
if (is_a($className, ForceFactoryInterface::class, true)) {
8086
/* phpstan-var class-string<ForceFactoryInterface> $className */
8187
$interfaceFactories = $className::getFactories();
@@ -93,7 +99,7 @@ private function getAllowedFactories(string $className): ?array
9399
/**
94100
* @phpstan-param class-string $className
95101
*
96-
* @return array<class-string>
102+
* @return null|array<class-string>
97103
*/
98104
private function getFactoriesFromAttribute(string $className): ?array
99105
{

tests/AttribForceFactoryRuleTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
*/
1515
class AttribForceFactoryRuleTest extends RuleTestCase
1616
{
17-
private const ERROR_MESSAGE = 'Test\Ebln\PHPStan\EnforceFactory\dataAttrib\code\ForcedFactoryProduct must be instantiated by Test\Ebln\PHPStan\EnforceFactory\dataAttrib\ForcedFactory or Test\Ebln\PHPStan\EnforceFactory\dataAttrib\TraitFactory!';
17+
private const ERROR_MESSAGE = 'Test\Ebln\PHPStan\EnforceFactory\dataAttrib\code\ForcedFactoryProduct must be instantiated by Test\Ebln\PHPStan\EnforceFactory\dataAttrib\ForcedFactory or Test\Ebln\PHPStan\EnforceFactory\dataAttrib\TraitFactory!' . "\n 💡 Only use Test\Ebln\PHPStan\EnforceFactory\dataAttrib\ForcedFactory or Test\Ebln\PHPStan\EnforceFactory\dataAttrib\TraitFactory to create an instance of Test\Ebln\PHPStan\EnforceFactory\dataAttrib\code\ForcedFactoryProduct!";
1818

1919
// Sadly this remains a vector, as phpstan fails to infer the created class name
2020
public function testLoopholeFactory(): void
@@ -49,9 +49,9 @@ public function testRogueFactory(): void
4949
[self::ERROR_MESSAGE, 40 + $offset],
5050
[self::ERROR_MESSAGE, 51 + $offset],
5151
[self::ERROR_MESSAGE, 56 + $offset],
52-
['Test\Ebln\PHPStan\EnforceFactory\dataAttrib\code\ExtendedProduct must be instantiated by Test\Ebln\PHPStan\EnforceFactory\dataAttrib\ForcedFactory or Test\Ebln\PHPStan\EnforceFactory\dataAttrib\TraitFactory!', 69 + $offset],
52+
['Test\Ebln\PHPStan\EnforceFactory\dataAttrib\code\ExtendedProduct must be instantiated by Test\Ebln\PHPStan\EnforceFactory\dataAttrib\ForcedFactory or Test\Ebln\PHPStan\EnforceFactory\dataAttrib\TraitFactory!' . "\n 💡 Only use Test\Ebln\PHPStan\EnforceFactory\dataAttrib\ForcedFactory or Test\Ebln\PHPStan\EnforceFactory\dataAttrib\TraitFactory to create an instance of Test\Ebln\PHPStan\EnforceFactory\dataAttrib\code\ExtendedProduct!", 69 + $offset],
5353
[self::ERROR_MESSAGE, 95 + $offset],
54-
['Test\Ebln\PHPStan\EnforceFactory\dataAttrib\code\IndependentForcedFactoryProduct must be instantiated by Test\Ebln\PHPStan\EnforceFactory\dataAttrib\IndependentFactory!', 100 + $offset],
54+
['Test\Ebln\PHPStan\EnforceFactory\dataAttrib\code\IndependentForcedFactoryProduct must be instantiated by Test\Ebln\PHPStan\EnforceFactory\dataAttrib\IndependentFactory!' . "\n 💡 Only use Test\Ebln\PHPStan\EnforceFactory\dataAttrib\IndependentFactory to create an instance of Test\Ebln\PHPStan\EnforceFactory\dataAttrib\code\IndependentForcedFactoryProduct!", 100 + $offset],
5555
]);
5656
}
5757

tests/ForceFactoryRuleTest.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
*/
1414
class ForceFactoryRuleTest extends RuleTestCase
1515
{
16-
private const ERROR_MESSAGE = 'Test\Ebln\PHPStan\EnforceFactory\data\code\ForcedFactoryProduct must be instantiated by Test\Ebln\PHPStan\EnforceFactory\data\ForcedFactory or Test\Ebln\PHPStan\EnforceFactory\data\TraitFactory!';
16+
private const ERROR_MESSAGE = 'Test\Ebln\PHPStan\EnforceFactory\data\code\ForcedFactoryProduct must be instantiated by Test\Ebln\PHPStan\EnforceFactory\data\ForcedFactory or Test\Ebln\PHPStan\EnforceFactory\data\TraitFactory!'
17+
. "\n 💡 Only use Test\Ebln\PHPStan\EnforceFactory\data\ForcedFactory or Test\Ebln\PHPStan\EnforceFactory\data\TraitFactory to create an instance of Test\Ebln\PHPStan\EnforceFactory\data\code\ForcedFactoryProduct!";
1718

1819
// Sadly this remains a vector, as phpstan fails to infer the created class name
1920
public function testLoopholeFactory(): void
@@ -41,7 +42,7 @@ public function testRogueFactory(): void
4142
[self::ERROR_MESSAGE, 40],
4243
[self::ERROR_MESSAGE, 51],
4344
[self::ERROR_MESSAGE, 56],
44-
['Test\Ebln\PHPStan\EnforceFactory\data\code\ExtendedProduct must be instantiated by Test\Ebln\PHPStan\EnforceFactory\data\ForcedFactory or Test\Ebln\PHPStan\EnforceFactory\data\TraitFactory!', 69],
45+
['Test\Ebln\PHPStan\EnforceFactory\data\code\ExtendedProduct must be instantiated by Test\Ebln\PHPStan\EnforceFactory\data\ForcedFactory or Test\Ebln\PHPStan\EnforceFactory\data\TraitFactory!' . "\n 💡 Only use Test\Ebln\PHPStan\EnforceFactory\data\ForcedFactory or Test\Ebln\PHPStan\EnforceFactory\data\TraitFactory to create an instance of Test\Ebln\PHPStan\EnforceFactory\data\code\ExtendedProduct!", 69],
4546
[self::ERROR_MESSAGE, 95],
4647
]);
4748
}

tests/MixedForceFactoryRuleTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ public function testAttributeFactory(): void
2828
public function testRogueAttributeFactory(): void
2929
{
3030
$this->analyse([__DIR__ . '/dataMixed/RogueAttributeFactory.php'], [
31-
['Test\Ebln\PHPStan\EnforceFactory\dataMixed\code\AttributeProduct must be instantiated by Test\Ebln\PHPStan\EnforceFactory\dataMixed\AttributeFactory!', 14],
32-
['Test\Ebln\PHPStan\EnforceFactory\dataMixed\code\MixedProduct must be instantiated by Test\Ebln\PHPStan\EnforceFactory\dataMixed\AttributeFactory or Test\Ebln\PHPStan\EnforceFactory\dataMixed\ForcedFactory!', 19],
31+
['Test\Ebln\PHPStan\EnforceFactory\dataMixed\code\AttributeProduct must be instantiated by Test\Ebln\PHPStan\EnforceFactory\dataMixed\AttributeFactory!' . "\n 💡 Only use Test\Ebln\PHPStan\EnforceFactory\dataMixed\AttributeFactory to create an instance of Test\Ebln\PHPStan\EnforceFactory\dataMixed\code\AttributeProduct!", 14],
32+
['Test\Ebln\PHPStan\EnforceFactory\dataMixed\code\MixedProduct must be instantiated by Test\Ebln\PHPStan\EnforceFactory\dataMixed\AttributeFactory or Test\Ebln\PHPStan\EnforceFactory\dataMixed\ForcedFactory!' . "\n 💡 Only use Test\Ebln\PHPStan\EnforceFactory\dataMixed\AttributeFactory or Test\Ebln\PHPStan\EnforceFactory\dataMixed\ForcedFactory to create an instance of Test\Ebln\PHPStan\EnforceFactory\dataMixed\code\MixedProduct!", 19],
3333

3434
]);
3535
}

0 commit comments

Comments
 (0)