Skip to content

Commit ec6b4fc

Browse files
committed
PHPStan 2.0
1 parent 63d391c commit ec6b4fc

12 files changed

+72
-64
lines changed

.github/workflows/phpstan.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ jobs:
1818
php-version:
1919
- "7.4"
2020
- "8.0"
21+
- "8.1"
22+
- "8.2"
23+
- "8.3"
2124

2225
steps:
2326
- name: "Checkout"

.github/workflows/tests-code-coverage.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ jobs:
2121
- "7.4"
2222
- "8.0"
2323
- "8.1"
24+
- "8.2"
25+
- "8.3"
2426

2527
steps:
2628
- name: "Checkout"

.github/workflows/tests.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ jobs:
1717
matrix:
1818
php-version:
1919
- "7.1"
20+
- "8.0"
21+
- "8.1"
22+
- "8.2"
23+
- "8.3"
2024

2125
steps:
2226
- name: "Checkout"

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
"keywords": ["enum", "phpstan"],
66
"license": "BSD-3-Clause",
77
"require": {
8-
"php": "^7.1 | ^8.0",
8+
"php": "^7.4 | ^8.0",
99
"marc-mabe/php-enum": "^1.1 || ^2.0 || ^3.0 || ^4.0",
10-
"phpstan/phpstan": "^1.0"
10+
"phpstan/phpstan": "^2.0"
1111
},
1212
"require-dev": {
1313
"phpunit/phpunit": "^7.5 | ^8.5 | 9.4"

src/EnumDynamicReturnTypeExtension.php

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,9 @@ public function __construct()
5050
return $this->detectGetValueReturnType($class);
5151
};
5252

53-
if (method_exists(Enum::class, 'getvalues')) {
54-
$this->staticMethods['getvalues'] = function (string $class) {
55-
return $this->detectGetValuesReturnType($class);
56-
};
57-
}
53+
$this->staticMethods['getvalues'] = function (string $class) {
54+
return $this->detectGetValuesReturnType($class);
55+
};
5856

5957
// static methods can be called like object methods
6058
$this->objectMethods = array_merge($this->objectMethods, $this->staticMethods);
@@ -87,15 +85,23 @@ public function getTypeFromStaticMethodCall(
8785
// The call class is not a name
8886
// E.g. an expression on $enumClass::getValues()
8987
if (!$callClass instanceof Name) {
90-
return ParametersAcceptorSelector::selectSingle($methodReflection->getVariants())->getReturnType();
88+
return ParametersAcceptorSelector::selectFromArgs(
89+
$scope,
90+
$staticCall->getArgs(),
91+
$methodReflection->getVariants()
92+
)->getReturnType();
9193
}
9294

9395
$callClassName = $callClass->toString();
9496

9597
// Can't detect possible types on static::*()
9698
// as it depends on defined enumerators of unknown inherited classes
9799
if ($callClassName === 'static') {
98-
return ParametersAcceptorSelector::selectSingle($methodReflection->getVariants())->getReturnType();
100+
return ParametersAcceptorSelector::selectFromArgs(
101+
$scope,
102+
$staticCall->getArgs(),
103+
$methodReflection->getVariants()
104+
)->getReturnType();
99105
}
100106

101107
if ($callClassName === 'self') {

src/EnumMethodsClassReflectionExtension.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ public function hasMethod(ClassReflection $classReflection, string $methodName):
1515
return false;
1616
}
1717

18-
/** @var string|Enum $class */
1918
$class = $classReflection->getName();
2019
return array_key_exists($methodName, $class::getConstants());
2120
}

tests/integration/IntegrationTest.php

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?php declare(strict_types = 1);
1+
<?php declare(strict_types=1);
22

33
namespace MabeEnum\PHPStan\tests\integration;
44

@@ -11,18 +11,13 @@ final class IntegrationTest extends LevelsTestCase
1111
/**
1212
* @return string[][]
1313
*/
14-
public function dataTopics(): array
14+
public static function dataTopics(): array
1515
{
16-
$dataTopics = [
16+
return [
1717
['EnumMethodsClassReflection'],
1818
['EnumGetValueReturnType'],
19+
['EnumGetValuesReturnType'],
1920
];
20-
21-
if (method_exists(Enum::class, 'getValues')) {
22-
$dataTopics[] = ['EnumGetValuesReturnType'];
23-
}
24-
25-
return $dataTopics;
2621
}
2722

2823
public function getDataPath(): string

tests/integration/data/EnumGetValuesReturnType-3.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
[
2+
{
3+
"message": "Method MabeEnum\\PHPStan\\tests\\integration\\data\\EnumGetValuesReturnType\\Example::staticBaseExprMethodFail() should return array<int, null> but returns array<int, array<int|string, mixed>|bool|float|int|string|null>.",
4+
"line": 21,
5+
"ignorable": true
6+
},
27
{
38
"message": "Method MabeEnum\\PHPStan\\tests\\integration\\data\\EnumGetValuesReturnType\\Example::staticMethodFail() should return array<int, null> but returns array<int, float|int|string>.",
49
"line": 40,
@@ -14,9 +19,19 @@
1419
"line": 70,
1520
"ignorable": true
1621
},
22+
{
23+
"message": "Method MabeEnum\\PHPStan\\tests\\integration\\data\\EnumGetValuesReturnType\\MyEnum::staticGetValuesFail() should return array<int, null> but returns array<int, array<int|string, mixed>|bool|float|int|string|null>.",
24+
"line": 76,
25+
"ignorable": true
26+
},
1727
{
1828
"message": "Method MabeEnum\\PHPStan\\tests\\integration\\data\\EnumGetValuesReturnType\\MyInheritedEnum::inheritSelfGetValuesFail() should return array<int, null> but returns array<int, float|int|string>.",
1929
"line": 93,
2030
"ignorable": true
31+
},
32+
{
33+
"message": "Method MabeEnum\\PHPStan\\tests\\integration\\data\\EnumGetValuesReturnType\\MyInheritedEnum::inheritStaticGetValuesFail() should return array<int, null> but returns array<int, array<int|string, mixed>|bool|float|int|string|null>.",
34+
"line": 99,
35+
"ignorable": true
2136
}
2237
]

tests/integration/data/EnumGetValuesReturnType-7.json

Lines changed: 0 additions & 17 deletions
This file was deleted.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[
2+
{
3+
"message": "Method MabeEnum\\PHPStan\\tests\\integration\\data\\EnumMethodsClassReflection\\Example::fail() should return MabeEnum\\PHPStan\\tests\\integration\\data\\EnumMethodsClassReflection\\MyEnum but returns mixed.",
4+
"line": 16,
5+
"ignorable": true
6+
}
7+
]

tests/unit/EnumDynamicReturnTypeExtensionTest.php

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,7 @@ public function testIsMethodSupportedShouldReturnFalse(): void
7272

7373
public function staticMethodsProvider(): array
7474
{
75-
$staticMethods = [];
76-
77-
if (method_exists(Enum::class, 'getValues')) {
78-
$staticMethods[] = ['getValues'];
79-
}
80-
81-
return $staticMethods;
75+
return [['getValues']];
8276
}
8377

8478
public function objectMethodsProvider(): array

tests/unit/EnumMethodReflectionTest.php

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use PHPStan\Reflection\ParametersAcceptorSelector;
1010
use PHPStan\Testing\PHPStanTestCase;
1111
use PHPStan\Type\VerbosityLevel;
12+
use PHPStan\Analyser\Scope;
1213

1314
class EnumMethodReflectionTest extends PHPStanTestCase
1415
{
@@ -30,59 +31,68 @@ public function setUp(): void
3031

3132
public function testGetName(): void
3233
{
33-
$classReflection = $this->reflectionProvider->getClass(VisibilityEnum::class);
34+
$classReflection = $this->reflectionProvider->getClass(VisibilityEnum::class);
3435
$methodReflection = $this->reflectionExtension->getMethod($classReflection, 'STR');
3536

3637
$this->assertSame('STR', $methodReflection->getName());
3738
}
3839

3940
public function testGetDeclaringClass(): void
4041
{
41-
$classReflection = $this->reflectionProvider->getClass(VisibilityEnum::class);
42+
$classReflection = $this->reflectionProvider->getClass(VisibilityEnum::class);
4243
$methodReflection = $this->reflectionExtension->getMethod($classReflection, 'STR');
4344

4445
$this->assertSame($classReflection, $methodReflection->getDeclaringClass());
4546
}
4647

4748
public function testShouldBeStatic(): void
4849
{
49-
$classReflection = $this->reflectionProvider->getClass(VisibilityEnum::class);
50+
$classReflection = $this->reflectionProvider->getClass(VisibilityEnum::class);
5051
$methodReflection = $this->reflectionExtension->getMethod($classReflection, 'STR');
5152

5253
$this->assertTrue($methodReflection->isStatic());
5354
}
5455

5556
public function testShouldNotBePrivate(): void
5657
{
57-
$classReflection = $this->reflectionProvider->getClass(VisibilityEnum::class);
58+
$classReflection = $this->reflectionProvider->getClass(VisibilityEnum::class);
5859
$methodReflection = $this->reflectionExtension->getMethod($classReflection, 'STR');
5960

6061
$this->assertFalse($methodReflection->isPrivate());
6162
}
6263

6364
public function testShouldBePublic(): void
6465
{
65-
$classReflection = $this->reflectionProvider->getClass(VisibilityEnum::class);
66+
$classReflection = $this->reflectionProvider->getClass(VisibilityEnum::class);
6667
$methodReflection = $this->reflectionExtension->getMethod($classReflection, 'STR');
6768

6869
$this->assertTrue($methodReflection->isPublic());
6970
}
7071

7172
public function testGetPrototype(): void
7273
{
73-
$classReflection = $this->reflectionProvider->getClass(VisibilityEnum::class);
74+
$classReflection = $this->reflectionProvider->getClass(VisibilityEnum::class);
7475
$methodReflection = $this->reflectionExtension->getMethod($classReflection, 'STR');
7576

7677
$this->assertSame($methodReflection, $methodReflection->getPrototype());
7778
}
7879

7980
public function testGetVariants(): void
8081
{
81-
$classReflection = $this->reflectionProvider->getClass(VisibilityEnum::class);
82+
$classReflection = $this->reflectionProvider->getClass(VisibilityEnum::class);
8283
$methodReflection = $this->reflectionExtension->getMethod($classReflection, 'STR');
83-
$parametersAcceptor = ParametersAcceptorSelector::selectSingle($methodReflection->getVariants());
8484

85-
$this->assertSame(VisibilityEnum::class, $parametersAcceptor->getReturnType()->describe(VerbosityLevel::value()));
85+
$scope = $this->createMock(Scope::class);
86+
$parametersAcceptor = ParametersAcceptorSelector::selectFromArgs(
87+
$scope,
88+
[],
89+
$methodReflection->getVariants()
90+
);
91+
92+
$this->assertSame(
93+
VisibilityEnum::class,
94+
$parametersAcceptor->getReturnType()->describe(VerbosityLevel::value())
95+
);
8696
}
8797

8898
public function testGetDocComment(): void
@@ -155,21 +165,11 @@ public function testHasSideEffects(): void
155165

156166
public static function assertMatchesRegularExpression(string $pattern, string $string, string $message = ''): void
157167
{
158-
if (method_exists(parent::class, 'assertMatchesRegularExpression')) {
159-
parent::assertMatchesRegularExpression($pattern, $string, $message);
160-
return;
161-
}
162-
163-
self::assertRegExp($pattern, $string, $message);
168+
parent::assertMatchesRegularExpression($pattern, $string, $message);
164169
}
165170

166171
public static function assertDoesNotMatchRegularExpression(string $pattern, string $string, string $message = ''): void
167172
{
168-
if (method_exists(parent::class, 'assertDoesNotMatchRegularExpression')) {
169-
parent::assertDoesNotMatchRegularExpression($pattern, $string, $message);
170-
return;
171-
}
172-
173-
self::assertNotRegExp($pattern, $string, $message);
173+
parent::assertDoesNotMatchRegularExpression($pattern, $string, $message);
174174
}
175175
}

0 commit comments

Comments
 (0)