Skip to content

Commit 8bbe200

Browse files
authored
Merge pull request #986 from acoulton/bug-remove-protected-method-from-final-class
bug: `protected` method in final class -> `private` is not a BC break
2 parents be346a8 + 922f11b commit 8bbe200

2 files changed

Lines changed: 54 additions & 3 deletions

File tree

src/DetectChanges/BCBreak/ClassBased/MethodRemoved.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,8 @@ public function __invoke(ReflectionClass $fromClass, ReflectionClass $toClass):
4444
/** @return array<string, ReflectionMethod> */
4545
private function accessibleMethods(ReflectionClass $class): array
4646
{
47-
$methods = Vec\filter($class->getMethods(), function (ReflectionMethod $method): bool {
48-
return ($method->isPublic()
49-
|| $method->isProtected())
47+
$methods = Vec\filter($class->getMethods(), function (ReflectionMethod $method) use ($class): bool {
48+
return $this->isAccessibleMethod($method, $class)
5049
&& ! $this->isInternalDocComment($method->getDocComment());
5150
});
5251

@@ -58,6 +57,15 @@ private function accessibleMethods(ReflectionClass $class): array
5857
);
5958
}
6059

60+
private function isAccessibleMethod(ReflectionMethod $method, ReflectionClass $class): bool
61+
{
62+
if ($method->isPublic()) {
63+
return true;
64+
}
65+
66+
return $method->isProtected() && ! $class->isFinal();
67+
}
68+
6169
private function isInternalDocComment(string|null $comment): bool
6270
{
6371
return $comment !== null

test/unit/DetectChanges/BCBreak/ClassBased/MethodRemovedTest.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use Roave\BetterReflection\Reflection\ReflectionClass;
1414
use Roave\BetterReflection\Reflector\DefaultReflector;
1515
use Roave\BetterReflection\SourceLocator\Type\SingleFileSourceLocator;
16+
use Roave\BetterReflection\SourceLocator\Type\StringSourceLocator;
1617

1718
use function array_map;
1819
use function iterator_to_array;
@@ -60,6 +61,48 @@ public static function classesToBeTested(): array
6061
'[BC] REMOVED: Method RoaveTestAsset\ClassWithMethodsBeingRemoved#removedProtectedMethod() was removed',
6162
],
6263
],
64+
'final class with protected changing to private' => [
65+
(new DefaultReflector(new StringSourceLocator(
66+
<<<'PHP'
67+
<?php
68+
final class FinalClassWithProtectedMethod {
69+
protected function foo(string $bar): void {}
70+
}
71+
PHP,
72+
$locator,
73+
)))->reflectClass('FinalClassWithProtectedMethod'),
74+
(new DefaultReflector(new StringSourceLocator(
75+
<<<'PHP'
76+
<?php
77+
final class FinalClassWithProtectedMethod {
78+
private function foo(string $bar): void {}
79+
}
80+
PHP,
81+
$locator,
82+
)))->reflectClass('FinalClassWithProtectedMethod'),
83+
[],
84+
],
85+
'final class with public changing to private' => [
86+
(new DefaultReflector(new StringSourceLocator(
87+
<<<'PHP'
88+
<?php
89+
final class FinalClassWithPublicMethod {
90+
public function foo(string $bar): void {}
91+
}
92+
PHP,
93+
$locator,
94+
)))->reflectClass('FinalClassWithPublicMethod'),
95+
(new DefaultReflector(new StringSourceLocator(
96+
<<<'PHP'
97+
<?php
98+
final class FinalClassWithPublicMethod {
99+
private function foo(string $bar): void {}
100+
}
101+
PHP,
102+
$locator,
103+
)))->reflectClass('FinalClassWithPublicMethod'),
104+
['[BC] REMOVED: Method FinalClassWithPublicMethod#foo() was removed'],
105+
],
63106
];
64107
}
65108
}

0 commit comments

Comments
 (0)