Skip to content

Commit 702fde2

Browse files
committed
Merge branch 2.2.x into 2.3.x
2 parents 9433e9f + 0ff0c25 commit 702fde2

7 files changed

Lines changed: 135 additions & 3 deletions

‎src/Rules/Methods/ConsistentConstructorRule.php‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public function processNode(Node $node, Scope&NodeCallbackInvoker&CollectedDataE
5050

5151
return array_merge(
5252
$this->methodParameterComparisonHelper->compare($parentConstructor, $parentConstructor->getDeclaringClass(), $method, $scope, true),
53-
$this->methodVisibilityComparisonHelper->compare($parentConstructor, $parentConstructor->getDeclaringClass(), $method),
53+
$this->methodVisibilityComparisonHelper->compare($parentConstructor, $parentConstructor->getDeclaringClass(), $method, $node->getOriginalNode()),
5454
);
5555
}
5656

‎src/Rules/Methods/MethodVisibilityComparisonHelper.php‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace PHPStan\Rules\Methods;
44

5+
use PhpParser\Node\Stmt\ClassMethod;
56
use PHPStan\DependencyInjection\AutowiredService;
67
use PHPStan\Reflection\ClassReflection;
78
use PHPStan\Reflection\ExtendedMethodReflection;
@@ -15,7 +16,7 @@ final class MethodVisibilityComparisonHelper
1516
{
1617

1718
/** @return list<IdentifierRuleError> */
18-
public function compare(ExtendedMethodReflection $prototype, ClassReflection $prototypeDeclaringClass, PhpMethodFromParserNodeReflection $method): array
19+
public function compare(ExtendedMethodReflection $prototype, ClassReflection $prototypeDeclaringClass, PhpMethodFromParserNodeReflection $method, ClassMethod $node): array
1920
{
2021
/** @var list<IdentifierRuleError> $messages */
2122
$messages = [];
@@ -32,6 +33,7 @@ public function compare(ExtendedMethodReflection $prototype, ClassReflection $pr
3233
))
3334
->nonIgnorable()
3435
->identifier('method.visibility')
36+
->line($node->name->getStartLine())
3537
->build();
3638
}
3739
} elseif ($method->isPrivate()) {
@@ -44,6 +46,7 @@ public function compare(ExtendedMethodReflection $prototype, ClassReflection $pr
4446
))
4547
->nonIgnorable()
4648
->identifier('method.visibility')
49+
->line($node->name->getStartLine())
4750
->build();
4851
}
4952

‎src/Rules/Methods/OverridingMethodRule.php‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ public function processNode(Node $node, Scope&NodeCallbackInvoker&CollectedDataE
223223
}
224224

225225
if ($checkVisibility) {
226-
$messages = array_merge($messages, $this->methodVisibilityComparisonHelper->compare($prototype, $prototypeDeclaringClass, $method));
226+
$messages = array_merge($messages, $this->methodVisibilityComparisonHelper->compare($prototype, $prototypeDeclaringClass, $method, $node->getOriginalNode()));
227227
}
228228

229229
$prototypeVariants = $prototype->getVariants();

‎tests/PHPStan/Rules/Methods/ConsistentConstructorRuleTest.php‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use PHPStan\Rules\Classes\ConsistentConstructorHelper;
66
use PHPStan\Rules\Rule;
77
use PHPStan\Testing\RuleTestCase;
8+
use PHPUnit\Framework\Attributes\RequiresPhp;
89
use function sprintf;
910

1011
/** @extends RuleTestCase<ConsistentConstructorRule> */
@@ -62,4 +63,15 @@ public function testBug12137(): void
6263
]);
6364
}
6465

66+
#[RequiresPhp('>= 8.0.0')]
67+
public function testBug14398(): void
68+
{
69+
$this->analyse([__DIR__ . '/data/bug-14398-consistent-constructor.php'], [
70+
[
71+
'Protected method Bug14398ConsistentConstructor\ChildClass::__construct() overriding public method Bug14398ConsistentConstructor\ParentClass::__construct() should also be public.',
72+
25,
73+
],
74+
]);
75+
}
76+
6577
}

‎tests/PHPStan/Rules/Methods/OverridingMethodRuleTest.php‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -881,4 +881,28 @@ public function testBug14457(): void
881881
]);
882882
}
883883

884+
#[RequiresPhp('>= 8.0.0')]
885+
public function testBug14398(): void
886+
{
887+
$this->phpVersionId = PHP_VERSION_ID;
888+
$this->analyse([__DIR__ . '/data/bug-14398.php'], [
889+
[
890+
'Private method Bug14398\ChildClass::publicMethod() overriding public method Bug14398\ParentClass::publicMethod() should also be public.',
891+
40,
892+
],
893+
[
894+
'Protected method Bug14398\ChildClass::publicWithDocblock() overriding public method Bug14398\ParentClass::publicWithDocblock() should also be public.',
895+
50,
896+
],
897+
[
898+
'Private method Bug14398\ChildClass::protectedMethod() overriding protected method Bug14398\ParentClass::protectedMethod() should be protected or public.',
899+
56,
900+
],
901+
[
902+
'Private method Bug14398\ChildClass::withoutAttribute() overriding public method Bug14398\ParentClass::withoutAttribute() should also be public.',
903+
60,
904+
],
905+
]);
906+
}
907+
884908
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php // lint >= 8.0
2+
3+
namespace Bug14398ConsistentConstructor;
4+
5+
#[\Attribute]
6+
class Marker
7+
{
8+
9+
}
10+
11+
/** @phpstan-consistent-constructor */
12+
class ParentClass
13+
{
14+
15+
public function __construct()
16+
{
17+
}
18+
19+
}
20+
21+
class ChildClass extends ParentClass
22+
{
23+
24+
#[Marker]
25+
protected function __construct()
26+
{
27+
}
28+
29+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php // lint >= 8.0
2+
3+
namespace Bug14398;
4+
5+
#[\Attribute]
6+
class Marker
7+
{
8+
9+
public function __construct(string $name = '')
10+
{
11+
}
12+
13+
}
14+
15+
class ParentClass
16+
{
17+
18+
public function publicMethod(): void
19+
{
20+
}
21+
22+
public function publicWithDocblock(): void
23+
{
24+
}
25+
26+
protected function protectedMethod(): void
27+
{
28+
}
29+
30+
public function withoutAttribute(): void
31+
{
32+
}
33+
34+
}
35+
36+
class ChildClass extends ParentClass
37+
{
38+
39+
#[\Override]
40+
private function publicMethod(): void
41+
{
42+
}
43+
44+
/**
45+
* Docblock above a multi-line attribute.
46+
*/
47+
#[Marker(
48+
name: 'foo',
49+
)]
50+
protected function publicWithDocblock(): void
51+
{
52+
}
53+
54+
#[Marker]
55+
#[\Override]
56+
private function protectedMethod(): void
57+
{
58+
}
59+
60+
private function withoutAttribute(): void
61+
{
62+
}
63+
64+
}

0 commit comments

Comments
 (0)