Skip to content

Commit

Permalink
Upgraded roave/better-reflection to be compatible with Roave/Better…
Browse files Browse the repository at this point in the history
…Reflection@1f7a13b

This also handles the upcoming BC break of Roave/BetterReflection#900

Some big changes:

 * `PropertyDocumentedTypeChanged` no longer exists: we use only `PropertyTypeChanged` for now. This
   is a step backwards, but it is needed to prevent issues around docblocks being too advanced for
   this library to parse them, for now.
    * see CuyZ/Valinor#6
    * see https://github.com/phpstan/phpstan-src/tree/447cd102d946a2d9883ac82793195275f54296a9/src/Type
    * see https://github.com/vimeo/psalm/tree/f1d47cc662500589e200a978e3af85488a5236cf/src/Psalm/Type
    * see https://github.com/phpDocumentor/ReflectionDocBlock/blob/622548b623e81ca6d78b721c5e029f4ce664f170/src/DocBlock/Tags/Param.php#L35
    * see https://github.com/phpstan/phpdoc-parser/blob/d639142cf83e91a07b4862217a6f8aa65ee10d08/tests/PHPStan/Parser/TypeParserTest.php#L64
    * /cc @tomasnorre this sadly effectively reverts #340 - it
      is too much effort to dive into further advanced types :-(
 * `PropertyTypeChanged` only expects the property to be both covariant and contravariant: if not,
   then a BC break was introduced (this re-uses some internal variance checks, simplifying code
   substantially)
 * usage of `ReflectionFunctionAbstract` is no longer present in the library: always using an union
   of `ReflectionMethod|ReflectionFunction` instead (as in `roave/better-reflection:^5`)
 * `FunctionName` is now `@internal`, since it's only used for internal rendering purposes
  • Loading branch information
Ocramius committed Dec 5, 2021
1 parent cfc9528 commit f8c25b3
Show file tree
Hide file tree
Showing 36 changed files with 556 additions and 449 deletions.
8 changes: 4 additions & 4 deletions bin/roave-backward-compatibility-check.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ static function (string $installationPath) use ($composerIo): Installer {
new PropertyBased\SkipPropertyBasedErrors(new PropertyBased\OnlyPublicPropertyChanged(
new PropertyBased\MultipleChecksOnAProperty(
new PropertyBased\SkipPropertyBasedErrors(new PropertyBased\PropertyBecameInternal()),
new PropertyBased\SkipPropertyBasedErrors(new PropertyBased\PropertyDocumentedTypeChanged()),
new PropertyBased\SkipPropertyBasedErrors(new PropertyBased\PropertyTypeChanged(new TypeIsContravariant(), new TypeIsCovariant())),
new PropertyBased\SkipPropertyBasedErrors(new PropertyBased\PropertyDefaultValueChanged()),
new PropertyBased\SkipPropertyBasedErrors(new PropertyBased\PropertyVisibilityReduced()),
new PropertyBased\SkipPropertyBasedErrors(new PropertyBased\PropertyScopeChanged())
Expand All @@ -123,7 +123,7 @@ static function (string $installationPath) use ($composerIo): Installer {
new PropertyBased\SkipPropertyBasedErrors(new PropertyBased\OnlyProtectedPropertyChanged(
new PropertyBased\MultipleChecksOnAProperty(
new PropertyBased\SkipPropertyBasedErrors(new PropertyBased\PropertyBecameInternal()),
new PropertyBased\SkipPropertyBasedErrors(new PropertyBased\PropertyDocumentedTypeChanged()),
new PropertyBased\SkipPropertyBasedErrors(new PropertyBased\PropertyTypeChanged(new TypeIsContravariant(), new TypeIsCovariant())),
new PropertyBased\SkipPropertyBasedErrors(new PropertyBased\PropertyDefaultValueChanged()),
new PropertyBased\SkipPropertyBasedErrors(new PropertyBased\PropertyVisibilityReduced()),
new PropertyBased\SkipPropertyBasedErrors(new PropertyBased\PropertyScopeChanged())
Expand Down Expand Up @@ -193,7 +193,7 @@ static function (string $installationPath) use ($composerIo): Installer {
new PropertyBased\SkipPropertyBasedErrors(new PropertyBased\OnlyPublicPropertyChanged(
new PropertyBased\MultipleChecksOnAProperty(
new PropertyBased\SkipPropertyBasedErrors(new PropertyBased\PropertyBecameInternal()),
new PropertyBased\SkipPropertyBasedErrors(new PropertyBased\PropertyDocumentedTypeChanged()),
new PropertyBased\SkipPropertyBasedErrors(new PropertyBased\PropertyTypeChanged(new TypeIsContravariant(), new TypeIsCovariant())),
new PropertyBased\SkipPropertyBasedErrors(new PropertyBased\PropertyDefaultValueChanged()),
new PropertyBased\SkipPropertyBasedErrors(new PropertyBased\PropertyVisibilityReduced()),
new PropertyBased\SkipPropertyBasedErrors(new PropertyBased\PropertyScopeChanged())
Expand Down Expand Up @@ -271,7 +271,7 @@ static function (string $installationPath) use ($composerIo): Installer {
new ClassBased\SkipClassBasedErrors(new ClassBased\PropertyChanged(
new PropertyBased\MultipleChecksOnAProperty(
new PropertyBased\SkipPropertyBasedErrors(new PropertyBased\PropertyBecameInternal()),
new PropertyBased\SkipPropertyBasedErrors(new PropertyBased\PropertyDocumentedTypeChanged()),
new PropertyBased\SkipPropertyBasedErrors(new PropertyBased\PropertyTypeChanged(new TypeIsContravariant(), new TypeIsCovariant())),
new PropertyBased\SkipPropertyBasedErrors(new PropertyBased\PropertyDefaultValueChanged()),
new PropertyBased\SkipPropertyBasedErrors(new PropertyBased\PropertyVisibilityReduced()),
new PropertyBased\SkipPropertyBasedErrors(new PropertyBased\PropertyScopeChanged())
Expand Down
6 changes: 3 additions & 3 deletions src/DetectChanges/BCBreak/ClassBased/MethodRemoved.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@
use Psl\Vec;
use Roave\BackwardCompatibility\Change;
use Roave\BackwardCompatibility\Changes;
use Roave\BackwardCompatibility\Formatter\ReflectionFunctionAbstractName;
use Roave\BackwardCompatibility\Formatter\FunctionName;
use Roave\BetterReflection\Reflection\ReflectionClass;
use Roave\BetterReflection\Reflection\ReflectionMethod;

final class MethodRemoved implements ClassBased
{
private ReflectionFunctionAbstractName $formatFunction;
private FunctionName $formatFunction;

public function __construct()
{
$this->formatFunction = new ReflectionFunctionAbstractName();
$this->formatFunction = new FunctionName();
}

public function __invoke(ReflectionClass $fromClass, ReflectionClass $toClass): Changes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

use Psl\Regex;
use Roave\BackwardCompatibility\Changes;
use Roave\BetterReflection\Reflection\ReflectionFunctionAbstract;
use Roave\BetterReflection\Reflection\ReflectionFunction;
use Roave\BetterReflection\Reflection\ReflectionMethod;

/**
* Functions marked "internal" (docblock) are not affected by BC checks.
Expand All @@ -20,8 +21,10 @@ public function __construct(FunctionBased $check)
$this->check = $check;
}

public function __invoke(ReflectionFunctionAbstract $fromFunction, ReflectionFunctionAbstract $toFunction): Changes
{
public function __invoke(
ReflectionMethod|ReflectionFunction $fromFunction,
ReflectionMethod|ReflectionFunction $toFunction
): Changes {
if ($this->isInternalDocComment($fromFunction->getDocComment())) {
return Changes::empty();
}
Expand Down
14 changes: 12 additions & 2 deletions src/DetectChanges/BCBreak/FunctionBased/FunctionBased.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,19 @@
namespace Roave\BackwardCompatibility\DetectChanges\BCBreak\FunctionBased;

use Roave\BackwardCompatibility\Changes;
use Roave\BetterReflection\Reflection\ReflectionFunctionAbstract;
use Roave\BetterReflection\Reflection\ReflectionFunction;
use Roave\BetterReflection\Reflection\ReflectionMethod;

interface FunctionBased
{
public function __invoke(ReflectionFunctionAbstract $fromFunction, ReflectionFunctionAbstract $toFunction): Changes;
/**
* @template T of ReflectionMethod|ReflectionFunction
*
* @param T $fromFunction
* @param T $toFunction
*/
public function __invoke(
ReflectionMethod|ReflectionFunction $fromFunction,
ReflectionMethod|ReflectionFunction $toFunction
): Changes;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,26 @@
use Psl\Str;
use Roave\BackwardCompatibility\Change;
use Roave\BackwardCompatibility\Changes;
use Roave\BackwardCompatibility\Formatter\ReflectionFunctionAbstractName;
use Roave\BetterReflection\Reflection\ReflectionFunctionAbstract;
use Roave\BackwardCompatibility\Formatter\FunctionName;
use Roave\BetterReflection\Reflection\ReflectionFunction;
use Roave\BetterReflection\Reflection\ReflectionMethod;

/**
* A function that is marked internal is no available to downstream consumers.
*/
final class FunctionBecameInternal implements FunctionBased
{
private ReflectionFunctionAbstractName $formatFunction;
private FunctionName $formatFunction;

public function __construct()
{
$this->formatFunction = new ReflectionFunctionAbstractName();
$this->formatFunction = new FunctionName();
}

public function __invoke(ReflectionFunctionAbstract $fromFunction, ReflectionFunctionAbstract $toFunction): Changes
{
public function __invoke(
ReflectionMethod|ReflectionFunction $fromFunction,
ReflectionMethod|ReflectionFunction $toFunction
): Changes {
if (
$this->isInternalDocComment($toFunction->getDocComment())
&& ! $this->isInternalDocComment($fromFunction->getDocComment())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

use Roave\BackwardCompatibility\Change;
use Roave\BackwardCompatibility\Changes;
use Roave\BetterReflection\Reflection\ReflectionFunctionAbstract;
use Roave\BetterReflection\Reflection\ReflectionFunction;
use Roave\BetterReflection\Reflection\ReflectionMethod;

final class MultipleChecksOnAFunction implements FunctionBased
{
Expand All @@ -18,14 +19,25 @@ public function __construct(FunctionBased ...$checks)
$this->checks = $checks;
}

public function __invoke(ReflectionFunctionAbstract $fromFunction, ReflectionFunctionAbstract $toFunction): Changes
{
public function __invoke(
ReflectionMethod|ReflectionFunction $fromFunction,
ReflectionMethod|ReflectionFunction $toFunction
): Changes {
return Changes::fromIterator($this->multipleChecks($fromFunction, $toFunction));
}

/** @return iterable<int, Change> */
private function multipleChecks(ReflectionFunctionAbstract $fromFunction, ReflectionFunctionAbstract $toFunction): iterable
{
/**
* @template T of ReflectionMethod|ReflectionFunction
*
* @param T $fromFunction
* @param T $toFunction
*
* @return iterable<int, Change>
*/
private function multipleChecks(
ReflectionMethod|ReflectionFunction $fromFunction,
ReflectionMethod|ReflectionFunction $toFunction
): iterable {
foreach ($this->checks as $check) {
yield from $check($fromFunction, $toFunction);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
use Psl\Str;
use Roave\BackwardCompatibility\Change;
use Roave\BackwardCompatibility\Changes;
use Roave\BackwardCompatibility\Formatter\ReflectionFunctionAbstractName;
use Roave\BetterReflection\Reflection\ReflectionFunctionAbstract;
use Roave\BackwardCompatibility\Formatter\FunctionName;
use Roave\BetterReflection\Reflection\ReflectionFunction;
use Roave\BetterReflection\Reflection\ReflectionMethod;
use Roave\BetterReflection\Reflection\ReflectionParameter;

/**
Expand All @@ -19,15 +20,17 @@
*/
final class ParameterByReferenceChanged implements FunctionBased
{
private ReflectionFunctionAbstractName $formatFunction;
private FunctionName $formatFunction;

public function __construct()
{
$this->formatFunction = new ReflectionFunctionAbstractName();
$this->formatFunction = new FunctionName();
}

public function __invoke(ReflectionFunctionAbstract $fromFunction, ReflectionFunctionAbstract $toFunction): Changes
{
public function __invoke(
ReflectionMethod|ReflectionFunction $fromFunction,
ReflectionMethod|ReflectionFunction $toFunction
): Changes {
$fromParameters = $fromFunction->getParameters();
$toParameters = $toFunction->getParameters();
$changes = Changes::empty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
use Psl\Str;
use Roave\BackwardCompatibility\Change;
use Roave\BackwardCompatibility\Changes;
use Roave\BackwardCompatibility\Formatter\ReflectionFunctionAbstractName;
use Roave\BetterReflection\Reflection\ReflectionFunctionAbstract;
use Roave\BackwardCompatibility\Formatter\FunctionName;
use Roave\BetterReflection\Reflection\ReflectionFunction;
use Roave\BetterReflection\Reflection\ReflectionMethod;
use Roave\BetterReflection\Reflection\ReflectionParameter;

use function var_export;
Expand All @@ -20,15 +21,17 @@
*/
final class ParameterDefaultValueChanged implements FunctionBased
{
private ReflectionFunctionAbstractName $formatFunction;
private FunctionName $formatFunction;

public function __construct()
{
$this->formatFunction = new ReflectionFunctionAbstractName();
$this->formatFunction = new FunctionName();
}

public function __invoke(ReflectionFunctionAbstract $fromFunction, ReflectionFunctionAbstract $toFunction): Changes
{
public function __invoke(
ReflectionMethod|ReflectionFunction $fromFunction,
ReflectionMethod|ReflectionFunction $toFunction
): Changes {
$fromParametersWithDefaults = $this->defaultParameterValues($fromFunction);
$toParametersWithDefaults = $this->defaultParameterValues($toFunction);

Expand Down Expand Up @@ -58,7 +61,7 @@ public function __invoke(ReflectionFunctionAbstract $fromFunction, ReflectionFun
}

/** @return ReflectionParameter[] indexed by parameter index */
private function defaultParameterValues(ReflectionFunctionAbstract $function): array
private function defaultParameterValues(ReflectionMethod|ReflectionFunction $function): array
{
return Dict\filter(
$function->getParameters(),
Expand Down
15 changes: 9 additions & 6 deletions src/DetectChanges/BCBreak/FunctionBased/ParameterTypeChanged.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
use Psl\Str;
use Roave\BackwardCompatibility\Change;
use Roave\BackwardCompatibility\Changes;
use Roave\BackwardCompatibility\Formatter\ReflectionFunctionAbstractName;
use Roave\BetterReflection\Reflection\ReflectionFunctionAbstract;
use Roave\BackwardCompatibility\Formatter\FunctionName;
use Roave\BetterReflection\Reflection\ReflectionFunction;
use Roave\BetterReflection\Reflection\ReflectionMethod;
use Roave\BetterReflection\Reflection\ReflectionParameter;
use Roave\BetterReflection\Reflection\ReflectionType;

Expand All @@ -21,15 +22,17 @@
*/
final class ParameterTypeChanged implements FunctionBased
{
private ReflectionFunctionAbstractName $formatFunction;
private FunctionName $formatFunction;

public function __construct()
{
$this->formatFunction = new ReflectionFunctionAbstractName();
$this->formatFunction = new FunctionName();
}

public function __invoke(ReflectionFunctionAbstract $fromFunction, ReflectionFunctionAbstract $toFunction): Changes
{
public function __invoke(
ReflectionMethod|ReflectionFunction $fromFunction,
ReflectionMethod|ReflectionFunction $toFunction
): Changes {
return Changes::fromIterator($this->checkSymbols(
$fromFunction->getParameters(),
$toFunction->getParameters()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,14 @@

use Psl\Dict;
use Psl\Str;
use Psl\Type;
use ReflectionProperty;
use Roave\BackwardCompatibility\Change;
use Roave\BackwardCompatibility\Changes;
use Roave\BackwardCompatibility\DetectChanges\Variance\TypeIsContravariant;
use Roave\BackwardCompatibility\DetectChanges\Variance\TypeWithReflectorScope;
use Roave\BackwardCompatibility\Formatter\ReflectionFunctionAbstractName;
use Roave\BetterReflection\Reflection\ReflectionFunctionAbstract;
use Roave\BackwardCompatibility\Formatter\FunctionName;
use Roave\BetterReflection\Reflection\ReflectionFunction;
use Roave\BetterReflection\Reflection\ReflectionMethod;
use Roave\BetterReflection\Reflection\ReflectionParameter;
use Roave\BetterReflection\Reflection\ReflectionType;
use Roave\BetterReflection\Reflector\Reflector;

/**
* When a parameter type changes, the new type should be wider than the previous type, or else
Expand All @@ -26,16 +23,18 @@ final class ParameterTypeContravarianceChanged implements FunctionBased
{
private TypeIsContravariant $typeIsContravariant;

private ReflectionFunctionAbstractName $formatFunction;
private FunctionName $formatFunction;

public function __construct(TypeIsContravariant $typeIsContravariant)
{
$this->typeIsContravariant = $typeIsContravariant;
$this->formatFunction = new ReflectionFunctionAbstractName();
$this->formatFunction = new FunctionName();
}

public function __invoke(ReflectionFunctionAbstract $fromFunction, ReflectionFunctionAbstract $toFunction): Changes
{
public function __invoke(
ReflectionMethod|ReflectionFunction $fromFunction,
ReflectionMethod|ReflectionFunction $toFunction
): Changes {
$fromParameters = $fromFunction->getParameters();
$toParameters = $toFunction->getParameters();
$changes = Changes::empty();
Expand All @@ -52,13 +51,7 @@ private function compareParameter(ReflectionParameter $fromParameter, Reflection
$fromType = $fromParameter->getType();
$toType = $toParameter->getType();


if (
($this->typeIsContravariant)(
new TypeWithReflectorScope($fromType, $this->extractReflector($fromParameter)),
new TypeWithReflectorScope($toType, $this->extractReflector($toParameter)),
)
) {
if (($this->typeIsContravariant)($fromType, $toType)) {
return Changes::empty();
}

Expand All @@ -82,15 +75,4 @@ private function typeToString(?ReflectionType $type): string

return $type->__toString();
}

/** @TODO may the gods of BC compliance be merciful on me */
private function extractReflector(ReflectionParameter $parameter): Reflector
{
$reflectionReflector = new ReflectionProperty(ReflectionFunctionAbstract::class, 'reflector');

$reflectionReflector->setAccessible(true);

return Type\object(Reflector::class)
->coerce($reflectionReflector->getValue($parameter->getDeclaringFunction()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,27 @@
use Psl\Str;
use Roave\BackwardCompatibility\Change;
use Roave\BackwardCompatibility\Changes;
use Roave\BackwardCompatibility\Formatter\ReflectionFunctionAbstractName;
use Roave\BetterReflection\Reflection\ReflectionFunctionAbstract;
use Roave\BackwardCompatibility\Formatter\FunctionName;
use Roave\BetterReflection\Reflection\ReflectionFunction;
use Roave\BetterReflection\Reflection\ReflectionMethod;

/**
* When new parameters are added, they must be optional, or else the callers will provide an insufficient
* amount of parameters to the function.
*/
final class RequiredParameterAmountIncreased implements FunctionBased
{
private ReflectionFunctionAbstractName $formatFunction;
private FunctionName $formatFunction;

public function __construct()
{
$this->formatFunction = new ReflectionFunctionAbstractName();
$this->formatFunction = new FunctionName();
}

public function __invoke(ReflectionFunctionAbstract $fromFunction, ReflectionFunctionAbstract $toFunction): Changes
{
public function __invoke(
ReflectionMethod|ReflectionFunction $fromFunction,
ReflectionMethod|ReflectionFunction $toFunction
): Changes {
$fromRequiredParameters = $fromFunction->getNumberOfRequiredParameters();
$toRequiredParameters = $toFunction->getNumberOfRequiredParameters();

Expand Down
Loading

0 comments on commit f8c25b3

Please sign in to comment.