-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
…lity-change Feature/#5 detected property visibility change
- Loading branch information
Showing
15 changed files
with
635 additions
and
18 deletions.
There are no files selected for viewing
46 changes: 46 additions & 0 deletions
46
src/Comparator/BackwardsCompatibility/ClassBased/MethodRemoved.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Roave\ApiCompare\Comparator\BackwardsCompatibility\ClassBased; | ||
|
||
use Assert\Assert; | ||
use Roave\ApiCompare\Change; | ||
use Roave\ApiCompare\Changes; | ||
use Roave\BetterReflection\Reflection\ReflectionClass; | ||
use Roave\BetterReflection\Reflection\ReflectionMethod; | ||
|
||
final class MethodRemoved implements ClassBased | ||
{ | ||
public function compare(ReflectionClass $fromClass, ReflectionClass $toClass) : Changes | ||
{ | ||
Assert::that($fromClass->getName())->same($toClass->getName()); | ||
|
||
$removedMethods = array_diff_key( | ||
array_change_key_case($this->accessibleMethods($fromClass), \CASE_UPPER), | ||
array_change_key_case($this->accessibleMethods($toClass), \CASE_UPPER) | ||
); | ||
|
||
return Changes::fromArray(array_values(array_map(function (ReflectionMethod $method) use ($fromClass) : Change { | ||
return Change::removed( | ||
sprintf('Method %s#%s() was removed', $fromClass->getName(), $method->getName()), | ||
true | ||
); | ||
}, $removedMethods))); | ||
} | ||
|
||
/** @return ReflectionMethod[] */ | ||
private function accessibleMethods(ReflectionClass $class) : array | ||
{ | ||
$methods = array_filter($class->getMethods(), function (ReflectionMethod $method) : bool { | ||
return $method->isPublic() || $method->isProtected(); | ||
}); | ||
|
||
return array_combine( | ||
array_map(function (ReflectionMethod $method) : string { | ||
return $method->getName(); | ||
}, $methods), | ||
$methods | ||
); | ||
} | ||
} |
83 changes: 83 additions & 0 deletions
83
src/Comparator/BackwardsCompatibility/ClassBased/MethodVisibilityReduced.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Roave\ApiCompare\Comparator\BackwardsCompatibility\ClassBased; | ||
|
||
use Assert\Assert; | ||
use Roave\ApiCompare\Change; | ||
use Roave\ApiCompare\Changes; | ||
use Roave\BetterReflection\Reflection\ReflectionClass; | ||
use Roave\BetterReflection\Reflection\ReflectionMethod; | ||
|
||
final class MethodVisibilityReduced implements ClassBased | ||
{ | ||
private const VISIBILITY_PRIVATE = 'private'; | ||
|
||
private const VISIBILITY_PROTECTED = 'protected'; | ||
|
||
private const VISIBILITY_PUBLIC = 'public'; | ||
|
||
public function compare(ReflectionClass $fromClass, ReflectionClass $toClass) : Changes | ||
{ | ||
Assert::that($fromClass->getName())->same($toClass->getName()); | ||
|
||
$visibilitiesFrom = $this->methodVisibilities($fromClass); | ||
$visibilitiesTo = $this->methodVisibilities($toClass); | ||
|
||
$affectedVisibilities = array_filter( | ||
array_combine( | ||
array_keys(array_intersect_key($visibilitiesFrom, $visibilitiesTo)), | ||
array_map( | ||
function (string $visibilityFrom, string $visibilityTo) : array { | ||
return [$visibilityFrom, $visibilityTo]; | ||
}, | ||
array_intersect_key($visibilitiesFrom, $visibilitiesTo), | ||
array_intersect_key($visibilitiesTo, $visibilitiesFrom) | ||
) | ||
), | ||
function (array $visibilities) : bool { | ||
// Note: works because public, protected and private are (luckily) sortable | ||
return $visibilities[0] > $visibilities[1]; | ||
} | ||
); | ||
|
||
return Changes::fromArray(array_values(array_map(function (string $methodName, array $visibilities) use ( | ||
$fromClass | ||
) : Change { | ||
return Change::changed( | ||
sprintf( | ||
'Method %s#%s() changed visibility from %s to %s', | ||
$fromClass->getName(), | ||
$fromClass->getMethod($methodName)->getName(), | ||
$visibilities[0], | ||
$visibilities[1] | ||
), | ||
true | ||
); | ||
}, array_keys($affectedVisibilities), $affectedVisibilities))); | ||
} | ||
|
||
/** @return string[] */ | ||
private function methodVisibilities(ReflectionClass $class) : array | ||
{ | ||
$methods = $class->getMethods(); | ||
|
||
return array_combine( | ||
array_map(function (ReflectionMethod $method) : string { | ||
return $method->getName(); | ||
}, $methods), | ||
array_map(function (ReflectionMethod $method) : string { | ||
if ($method->isPublic()) { | ||
return self::VISIBILITY_PUBLIC; | ||
} | ||
|
||
if ($method->isProtected()) { | ||
return self::VISIBILITY_PROTECTED; | ||
} | ||
|
||
return self::VISIBILITY_PRIVATE; | ||
}, $methods) | ||
); | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
src/Comparator/BackwardsCompatibility/ClassBased/MultiClassBased.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Roave\ApiCompare\Comparator\BackwardsCompatibility\ClassBased; | ||
|
||
use Roave\ApiCompare\Changes; | ||
use Roave\BetterReflection\Reflection\ReflectionClass; | ||
|
||
final class MultiClassBased implements ClassBased | ||
{ | ||
/** @var ClassBased[] */ | ||
private $checks; | ||
|
||
public function __construct(ClassBased ...$checks) | ||
{ | ||
$this->checks = $checks; | ||
} | ||
|
||
public function compare(ReflectionClass $fromClass, ReflectionClass $toClass) : Changes | ||
{ | ||
return array_reduce( | ||
$this->checks, | ||
function (Changes $changes, ClassBased $check) use ($fromClass, $toClass) : Changes { | ||
return $changes->mergeWith($check->compare($fromClass, $toClass)); | ||
}, | ||
Changes::new() | ||
); | ||
} | ||
} |
76 changes: 76 additions & 0 deletions
76
src/Comparator/BackwardsCompatibility/ClassBased/PropertyVisibilityReduced.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Roave\ApiCompare\Comparator\BackwardsCompatibility\ClassBased; | ||
|
||
use Assert\Assert; | ||
use Roave\ApiCompare\Change; | ||
use Roave\ApiCompare\Changes; | ||
use Roave\BetterReflection\Reflection\ReflectionClass; | ||
use Roave\BetterReflection\Reflection\ReflectionProperty; | ||
|
||
final class PropertyVisibilityReduced implements ClassBased | ||
{ | ||
private const VISIBILITY_PRIVATE = 'private'; | ||
|
||
private const VISIBILITY_PROTECTED = 'protected'; | ||
|
||
private const VISIBILITY_PUBLIC = 'public'; | ||
|
||
public function compare(ReflectionClass $fromClass, ReflectionClass $toClass) : Changes | ||
{ | ||
Assert::that($fromClass->getName())->same($toClass->getName()); | ||
|
||
$visibilitiesFrom = $this->propertyVisibilities($fromClass); | ||
$visibilitiesTo = $this->propertyVisibilities($toClass); | ||
|
||
$affectedVisibilities = array_filter( | ||
array_combine( | ||
array_keys(array_intersect_key($visibilitiesFrom, $visibilitiesTo)), | ||
array_map( | ||
function (string $visibilityFrom, string $visibilityTo) : array { | ||
return [$visibilityFrom, $visibilityTo]; | ||
}, | ||
array_intersect_key($visibilitiesFrom, $visibilitiesTo), | ||
array_intersect_key($visibilitiesTo, $visibilitiesFrom) | ||
) | ||
), | ||
function (array $visibilities) : bool { | ||
// Note: works because public, protected and private are (luckily) sortable | ||
return $visibilities[0] > $visibilities[1]; | ||
} | ||
); | ||
|
||
return Changes::fromArray(array_values(array_map(function (string $propertyName, array $visibilities) use ( | ||
$fromClass | ||
) : Change { | ||
return Change::changed( | ||
sprintf( | ||
'Property %s#%s changed visibility from %s to %s', | ||
$fromClass->getName(), | ||
$propertyName, | ||
$visibilities[0], | ||
$visibilities[1] | ||
), | ||
true | ||
); | ||
}, array_keys($affectedVisibilities), $affectedVisibilities))); | ||
} | ||
|
||
/** @return string[] */ | ||
private function propertyVisibilities(ReflectionClass $class) : array | ||
{ | ||
return array_map(function (ReflectionProperty $property) : string { | ||
if ($property->isPublic()) { | ||
return self::VISIBILITY_PUBLIC; | ||
} | ||
|
||
if ($property->isProtected()) { | ||
return self::VISIBILITY_PROTECTED; | ||
} | ||
|
||
return self::VISIBILITY_PRIVATE; | ||
}, $class->getProperties()); | ||
} | ||
} |
35 changes: 35 additions & 0 deletions
35
test/asset/api/new/ClassWithMethodVisibilitiesBeingChanged.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace RoaveTestAsset; | ||
|
||
class ClassWithMethodVisibilitiesBeingChanged | ||
{ | ||
public function publicMaintainedPublic() | ||
{ | ||
} | ||
protected function publicReducedToProtected() | ||
{ | ||
} | ||
private function publicReducedToPrivate() | ||
{ | ||
} | ||
protected function protectedMaintainedProtected() | ||
{ | ||
} | ||
private function protectedReducedToPrivate() | ||
{ | ||
} | ||
public function protectedIncreasedToPublic() | ||
{ | ||
} | ||
private function privateMaintainedPrivate() | ||
{ | ||
} | ||
protected function privateIncreasedToProtected() | ||
{ | ||
} | ||
public function privateIncreasedToPublic() | ||
{ | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace RoaveTestAsset; | ||
|
||
class ClassWithMethodsBeingRemoved | ||
{ | ||
public function nameCaseChangePublicMethod() { | ||
} | ||
public function keptPublicMethod() { | ||
} | ||
protected function nameCaseChangeProtectedMethod() { | ||
} | ||
protected function keptProtectedMethod() { | ||
} | ||
private function nameCaseChangePrivateMethod() { | ||
} | ||
private function keptPrivateMethod() { | ||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
test/asset/api/new/ClassWithPropertyVisibilitiesBeingChanged.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace RoaveTestAsset; | ||
|
||
class ClassWithPropertyVisibilitiesBeingChanged | ||
{ | ||
public $publicMaintainedPublic; | ||
protected $publicReducedToProtected; | ||
private $publicReducedToPrivate; | ||
protected $protectedMaintainedProtected; | ||
private $protectedReducedToPrivate; | ||
public $protectedIncreasedToPublic; | ||
private $privateMaintainedPrivate; | ||
protected $privateIncreasedToProtected; | ||
public $privateIncreasedToPublic; | ||
} |
35 changes: 35 additions & 0 deletions
35
test/asset/api/old/ClassWithMethodVisibilitiesBeingChanged.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace RoaveTestAsset; | ||
|
||
class ClassWithMethodVisibilitiesBeingChanged | ||
{ | ||
public function publicMaintainedPublic() | ||
{ | ||
} | ||
public function publicReducedToProtected() | ||
{ | ||
} | ||
public function publicReducedToPrivate() | ||
{ | ||
} | ||
protected function protectedMaintainedProtected() | ||
{ | ||
} | ||
protected function protectedReducedToPrivate() | ||
{ | ||
} | ||
protected function protectedIncreasedToPublic() | ||
{ | ||
} | ||
private function privateMaintainedPrivate() | ||
{ | ||
} | ||
private function privateIncreasedToProtected() | ||
{ | ||
} | ||
private function privateIncreasedToPublic() | ||
{ | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace RoaveTestAsset; | ||
|
||
class ClassWithMethodsBeingRemoved | ||
{ | ||
public function removedPublicMethod() { | ||
} | ||
public function nameCaseChangePublicMethod() { | ||
} | ||
public function keptPublicMethod() { | ||
} | ||
protected function removedProtectedMethod() { | ||
} | ||
protected function nameCaseChangeProtectedMethod() { | ||
} | ||
protected function keptProtectedMethod() { | ||
} | ||
private function removedPrivateMethod() { | ||
} | ||
private function nameCaseChangePrivateMethod() { | ||
} | ||
private function keptPrivateMethod() { | ||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
test/asset/api/old/ClassWithPropertyVisibilitiesBeingChanged.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace RoaveTestAsset; | ||
|
||
class ClassWithPropertyVisibilitiesBeingChanged | ||
{ | ||
public $publicMaintainedPublic; | ||
public $publicReducedToProtected; | ||
public $publicReducedToPrivate; | ||
protected $protectedMaintainedProtected; | ||
protected $protectedReducedToPrivate; | ||
protected $protectedIncreasedToPublic; | ||
private $privateMaintainedPrivate; | ||
private $privateIncreasedToProtected; | ||
private $privateIncreasedToPublic; | ||
} |
Oops, something went wrong.