diff --git a/src/BetterReflection.php b/src/BetterReflection.php index be795d522..8042d7b85 100644 --- a/src/BetterReflection.php +++ b/src/BetterReflection.php @@ -28,25 +28,55 @@ final class BetterReflection { public static int $phpVersion = PHP_VERSION_ID; - private static SourceLocator|null $sharedSourceLocator = null; + /** + * @var \Roave\BetterReflection\SourceLocator\Type\SourceLocator|null + */ + private static $sharedSourceLocator = null; - private SourceLocator|null $sourceLocator = null; + /** + * @var \Roave\BetterReflection\SourceLocator\Type\SourceLocator|null + */ + private $sourceLocator = null; - private static Reflector|null $sharedReflector = null; + /** + * @var \Roave\BetterReflection\Reflector\Reflector|null + */ + private static $sharedReflector = null; - private Reflector|null $reflector = null; + /** + * @var \Roave\BetterReflection\Reflector\Reflector|null + */ + private $reflector = null; - private static Parser|null $sharedPhpParser = null; + /** + * @var \PhpParser\Parser|null + */ + private static $sharedPhpParser = null; - private Parser|null $phpParser = null; + /** + * @var \PhpParser\Parser|null + */ + private $phpParser = null; - private AstLocator|null $astLocator = null; + /** + * @var AstLocator|null + */ + private $astLocator = null; - private FindReflectionOnLine|null $findReflectionOnLine = null; + /** + * @var \Roave\BetterReflection\Util\FindReflectionOnLine|null + */ + private $findReflectionOnLine = null; - private SourceStubber|null $sourceStubber = null; + /** + * @var \Roave\BetterReflection\SourceLocator\SourceStubber\SourceStubber|null + */ + private $sourceStubber = null; - private static SourceStubber|null $sharedSourceStubber = null; + /** + * @var \Roave\BetterReflection\SourceLocator\SourceStubber\SourceStubber|null + */ + private static $sharedSourceStubber = null; /** * @var Standard|null @@ -58,14 +88,8 @@ final class BetterReflection */ private $printer = null; - public static function populate( - int $phpVersion, - SourceLocator $sourceLocator, - Reflector $classReflector, - Parser $phpParser, - SourceStubber $sourceStubber, - Standard $printer, - ): void { + public static function populate(int $phpVersion, SourceLocator $sourceLocator, Reflector $classReflector, Parser $phpParser, SourceStubber $sourceStubber, Standard $printer): void + { self::$phpVersion = $phpVersion; self::$sharedSourceLocator = $sourceLocator; self::$sharedReflector = $classReflector; diff --git a/src/Identifier/Identifier.php b/src/Identifier/Identifier.php index dd2e2ab41..8cf12a65f 100644 --- a/src/Identifier/Identifier.php +++ b/src/Identifier/Identifier.php @@ -14,6 +14,7 @@ class Identifier { + private IdentifierType $type; public const WILDCARD = '*'; private const VALID_NAME_REGEXP = '/([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)(\\\\[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*/'; @@ -21,12 +22,13 @@ class Identifier private string $name; /** @throws InvalidIdentifierName */ - public function __construct(string $name, private IdentifierType $type) + public function __construct(string $name, IdentifierType $type) { + $this->type = $type; if ( $name === self::WILDCARD || $name === ReflectionFunction::CLOSURE_NAME - || str_starts_with($name, ReflectionClass::ANONYMOUS_CLASS_NAME_PREFIX) + || strncmp($name, ReflectionClass::ANONYMOUS_CLASS_NAME_PREFIX, strlen(ReflectionClass::ANONYMOUS_CLASS_NAME_PREFIX)) === 0 ) { $this->name = $name; diff --git a/src/NodeCompiler/CompileNodeToValue.php b/src/NodeCompiler/CompileNodeToValue.php index b8aeb2b65..c8a290d06 100644 --- a/src/NodeCompiler/CompileNodeToValue.php +++ b/src/NodeCompiler/CompileNodeToValue.php @@ -52,7 +52,7 @@ public function __invoke(Node $node, CompilerContext $context): CompiledValue $constantName = $this->resolveClassConstantName($node, $context); } - $constExprEvaluator = new ConstExprEvaluator(function (Node\Expr $node) use ($context, $constantName): mixed { + $constExprEvaluator = new ConstExprEvaluator(function (Node\Expr $node) use ($context, $constantName) { if ($node instanceof Node\Expr\ConstFetch) { return $this->getConstantValue($node, $constantName, $context); } @@ -111,7 +111,7 @@ public function __invoke(Node $node, CompilerContext $context): CompiledValue } if ($node instanceof Node\Scalar\MagicConst\Function_) { - return $context->getFunction()?->getName() ?? ''; + return (($nullsafeVariable1 = $context->getFunction()) ? $nullsafeVariable1->getName() : null) ?? ''; } if ($node instanceof Node\Scalar\MagicConst\Trait_) { @@ -151,7 +151,10 @@ public function __invoke(Node $node, CompilerContext $context): CompiledValue return new CompiledValue($value, $constantName); } - private function getEnumPropertyValue(Node\Expr\PropertyFetch $node, CompilerContext $context): mixed + /** + * @return mixed + */ + private function getEnumPropertyValue(Node\Expr\PropertyFetch $node, CompilerContext $context) { assert($node->var instanceof Node\Expr\ClassConstFetch); assert($node->var->class instanceof Node\Name); @@ -175,11 +178,14 @@ private function getEnumPropertyValue(Node\Expr\PropertyFetch $node, CompilerCon assert($node->name instanceof Node\Identifier); - return match ($node->name->toString()) { - 'value' => $case->getValue(), - 'name' => $case->getName(), - default => throw Exception\UnableToCompileNode::becauseOfInvalidEnumCasePropertyFetch($context, $class, $node), - }; + switch ($node->name->toString()) { + case 'value': + return $case->getValue(); + case 'name': + return $case->getName(); + default: + throw Exception\UnableToCompileNode::becauseOfInvalidEnumCasePropertyFetch($context, $class, $node); + } } private function resolveConstantName(Node\Expr\ConstFetch $constNode, CompilerContext $context): string @@ -212,12 +218,15 @@ private function constantExists(string $constantName, CompilerContext $context): $context->getReflector()->reflectConstant($constantName); return true; - } catch (IdentifierNotFound) { + } catch (IdentifierNotFound $exception) { return false; } } - private function getConstantValue(Node\Expr\ConstFetch $node, string|null $constantName, CompilerContext $context): mixed + /** + * @return mixed + */ + private function getConstantValue(Node\Expr\ConstFetch $node, ?string $constantName, CompilerContext $context) { // It's not resolved when constant value is expression // @infection-ignore-all Assignment, AssignCoalesce: There's no difference, ??= is just optimization @@ -240,7 +249,10 @@ private function resolveClassConstantName(Node\Expr\ClassConstFetch $node, Compi return sprintf('%s::%s', $this->resolveClassName($className, $context), $constantName); } - private function getClassConstantValue(Node\Expr\ClassConstFetch $node, string|null $classConstantName, CompilerContext $context): mixed + /** + * @return mixed + */ + private function getClassConstantValue(Node\Expr\ClassConstFetch $node, ?string $classConstantName, CompilerContext $context) { // It's not resolved when constant value is expression // @infection-ignore-all Assignment, AssignCoalesce: There's no difference, ??= is just optimization @@ -336,7 +348,7 @@ private function compileFileConstant(CompilerContext $context, Node\Scalar\Magic */ private function compileClassConstant(CompilerContext $context): string { - return $context->getClass()?->getName() ?? ''; + return (($nullsafeVariable2 = $context->getClass()) ? $nullsafeVariable2->getName() : null) ?? ''; } private function resolveClassName(string $className, CompilerContext $context): string diff --git a/src/NodeCompiler/CompiledValue.php b/src/NodeCompiler/CompiledValue.php index 3a4354e20..93531ed72 100644 --- a/src/NodeCompiler/CompiledValue.php +++ b/src/NodeCompiler/CompiledValue.php @@ -7,7 +7,20 @@ /** @internal */ class CompiledValue { - public function __construct(public mixed $value, public string|null $constantName = null) + /** + * @var mixed + */ + public $value; + /** + * @var string|null + */ + public $constantName = null; + /** + * @param mixed $value + */ + public function __construct($value, ?string $constantName = null) { + $this->value = $value; + $this->constantName = $constantName; } } diff --git a/src/NodeCompiler/CompilerContext.php b/src/NodeCompiler/CompilerContext.php index 3544b2eb9..6d184d2fc 100644 --- a/src/NodeCompiler/CompilerContext.php +++ b/src/NodeCompiler/CompilerContext.php @@ -18,19 +18,26 @@ /** @internal */ class CompilerContext { - public function __construct( - private Reflector $reflector, - private ReflectionClass|ReflectionProperty|ReflectionClassConstant|ReflectionEnumCase|ReflectionMethod|ReflectionFunction|ReflectionParameter|ReflectionConstant $contextReflection, - ) { + private Reflector $reflector; + /** + * @var \Roave\BetterReflection\Reflection\ReflectionClass|\Roave\BetterReflection\Reflection\ReflectionProperty|\Roave\BetterReflection\Reflection\ReflectionClassConstant|\Roave\BetterReflection\Reflection\ReflectionEnumCase|\Roave\BetterReflection\Reflection\ReflectionMethod|\Roave\BetterReflection\Reflection\ReflectionFunction|\Roave\BetterReflection\Reflection\ReflectionParameter|\Roave\BetterReflection\Reflection\ReflectionConstant + */ + private $contextReflection; + /** + * @param \Roave\BetterReflection\Reflection\ReflectionClass|\Roave\BetterReflection\Reflection\ReflectionProperty|\Roave\BetterReflection\Reflection\ReflectionClassConstant|\Roave\BetterReflection\Reflection\ReflectionEnumCase|\Roave\BetterReflection\Reflection\ReflectionMethod|\Roave\BetterReflection\Reflection\ReflectionFunction|\Roave\BetterReflection\Reflection\ReflectionParameter|\Roave\BetterReflection\Reflection\ReflectionConstant $contextReflection + */ + public function __construct(Reflector $reflector, $contextReflection) + { + $this->reflector = $reflector; + $this->contextReflection = $contextReflection; } - public function getReflector(): Reflector { return $this->reflector; } /** @return non-empty-string|null */ - public function getFileName(): string|null + public function getFileName(): ?string { if ($this->contextReflection instanceof ReflectionConstant) { $fileName = $this->contextReflection->getFileName(); @@ -41,7 +48,7 @@ public function getFileName(): string|null return $this->realPath($fileName); } - $fileName = $this->getClass()?->getFileName() ?? $this->getFunction()?->getFileName(); + $fileName = (($nullsafeVariable1 = $this->getClass()) ? $nullsafeVariable1->getFileName() : null) ?? (($nullsafeVariable2 = $this->getFunction()) ? $nullsafeVariable2->getFileName() : null); if ($fileName === null) { return null; } @@ -54,17 +61,17 @@ private function realPath(string $fileName): string return FileHelper::normalizePath($fileName, '/'); } - public function getNamespace(): string|null + public function getNamespace(): ?string { if ($this->contextReflection instanceof ReflectionConstant) { return $this->contextReflection->getNamespaceName(); } // @infection-ignore-all Coalesce: There's no difference - return $this->getClass()?->getNamespaceName() ?? $this->getFunction()?->getNamespaceName(); + return (($nullsafeVariable3 = $this->getClass()) ? $nullsafeVariable3->getNamespaceName() : null) ?? (($nullsafeVariable4 = $this->getFunction()) ? $nullsafeVariable4->getNamespaceName() : null); } - public function getClass(): ReflectionClass|null + public function getClass(): ?\Roave\BetterReflection\Reflection\ReflectionClass { if ($this->contextReflection instanceof ReflectionClass) { return $this->contextReflection; @@ -89,7 +96,10 @@ public function getClass(): ReflectionClass|null return $this->contextReflection->getImplementingClass(); } - public function getFunction(): ReflectionMethod|ReflectionFunction|null + /** + * @return \Roave\BetterReflection\Reflection\ReflectionMethod|\Roave\BetterReflection\Reflection\ReflectionFunction|null + */ + public function getFunction() { if ($this->contextReflection instanceof ReflectionMethod) { return $this->contextReflection; diff --git a/src/NodeCompiler/Exception/UnableToCompileNode.php b/src/NodeCompiler/Exception/UnableToCompileNode.php index 75c20e133..da0b0b838 100644 --- a/src/NodeCompiler/Exception/UnableToCompileNode.php +++ b/src/NodeCompiler/Exception/UnableToCompileNode.php @@ -16,9 +16,12 @@ /** @internal */ class UnableToCompileNode extends LogicException { - private string|null $constantName = null; + /** + * @var string|null + */ + private $constantName = null; - public function constantName(): string|null + public function constantName(): ?string { return $this->constantName; } @@ -28,19 +31,15 @@ public static function forUnRecognizedExpressionInContext(Node\Expr $expression, return new self(sprintf( 'Unable to compile expression in %s: unrecognized node type %s in file %s (line %d)', self::compilerContextToContextDescription($context), - $expression::class, + get_class($expression), self::getFileName($context), $expression->getStartLine(), )); } - public static function becauseOfNotFoundClassConstantReference( - CompilerContext $fetchContext, - ReflectionClass $targetClass, - Node\Expr\ClassConstFetch $constantFetch, - ): self { + public static function becauseOfNotFoundClassConstantReference(CompilerContext $fetchContext, ReflectionClass $targetClass, Node\Expr\ClassConstFetch $constantFetch): self + { assert($constantFetch->name instanceof Node\Identifier); - return new self(sprintf( 'Could not locate constant %s::%s while trying to evaluate constant expression in %s in file %s (line %d)', $targetClass->getName(), @@ -51,11 +50,8 @@ public static function becauseOfNotFoundClassConstantReference( )); } - public static function becauseOfNotFoundConstantReference( - CompilerContext $fetchContext, - Node\Expr\ConstFetch $constantFetch, - string $constantName, - ): self { + public static function becauseOfNotFoundConstantReference(CompilerContext $fetchContext, Node\Expr\ConstFetch $constantFetch, string $constantName): self + { $exception = new self(sprintf( 'Could not locate constant "%s" while evaluating expression in %s in file %s (line %d)', $constantName, @@ -63,21 +59,15 @@ public static function becauseOfNotFoundConstantReference( self::getFileName($fetchContext), $constantFetch->getStartLine(), )); - $exception->constantName = $constantName; - return $exception; } - public static function becauseOfInvalidEnumCasePropertyFetch( - CompilerContext $fetchContext, - ReflectionClass $targetClass, - Node\Expr\PropertyFetch $propertyFetch, - ): self { + public static function becauseOfInvalidEnumCasePropertyFetch(CompilerContext $fetchContext, ReflectionClass $targetClass, Node\Expr\PropertyFetch $propertyFetch): self + { assert($propertyFetch->var instanceof Node\Expr\ClassConstFetch); assert($propertyFetch->var->name instanceof Node\Identifier); assert($propertyFetch->name instanceof Node\Identifier); - return new self(sprintf( 'Could not get %s::%s->%s while trying to evaluate constant expression in %s in file %s (line %d)', $targetClass->getName(), @@ -89,10 +79,11 @@ public static function becauseOfInvalidEnumCasePropertyFetch( )); } - public static function becauseOfMissingFileName( - CompilerContext $context, - Node\Scalar\MagicConst\Dir|Node\Scalar\MagicConst\File $node, - ): self { + /** + * @param \PhpParser\Node\Scalar\MagicConst\Dir|\PhpParser\Node\Scalar\MagicConst\File $node + */ + public static function becauseOfMissingFileName(CompilerContext $context, $node): self + { return new self(sprintf( 'No file name for %s (line %d)', self::compilerContextToContextDescription($context), @@ -100,10 +91,8 @@ public static function becauseOfMissingFileName( )); } - public static function becauseOfNonexistentFile( - CompilerContext $context, - string $fileName, - ): self { + public static function becauseOfNonexistentFile(CompilerContext $context, string $fileName): self + { return new self(sprintf( 'File not found for %s: %s', self::compilerContextToContextDescription($context), @@ -111,11 +100,8 @@ public static function becauseOfNonexistentFile( )); } - public static function becauseOfClassCannotBeLoaded( - CompilerContext $context, - Node\Expr\New_ $newNode, - string $className, - ): self { + public static function becauseOfClassCannotBeLoaded(CompilerContext $context, Node\Expr\New_ $newNode, string $className): self + { return new self(sprintf( 'Cound not load class "%s" while evaluating expression in %s in file %s (line %d)', $className, @@ -125,13 +111,9 @@ public static function becauseOfClassCannotBeLoaded( )); } - public static function becauseOfValueIsEnum( - CompilerContext $fetchContext, - ReflectionClass $targetClass, - Node\Expr\ClassConstFetch $constantFetch, - ): self { + public static function becauseOfValueIsEnum(CompilerContext $fetchContext, ReflectionClass $targetClass, Node\Expr\ClassConstFetch $constantFetch): self + { assert($constantFetch->name instanceof Node\Identifier); - return new self(sprintf( 'An enum expression %s::%s is not supported in %s in file %s (line %d)', $targetClass->getName(), diff --git a/src/Reflection/Adapter/FakeReflectionAttribute.php b/src/Reflection/Adapter/FakeReflectionAttribute.php index 3068327cd..eabca6468 100644 --- a/src/Reflection/Adapter/FakeReflectionAttribute.php +++ b/src/Reflection/Adapter/FakeReflectionAttribute.php @@ -9,8 +9,10 @@ final class FakeReflectionAttribute { - public function __construct(private BetterReflectionAttribute $betterReflectionAttribute) + private BetterReflectionAttribute $betterReflectionAttribute; + public function __construct(BetterReflectionAttribute $betterReflectionAttribute) { + $this->betterReflectionAttribute = $betterReflectionAttribute; } public function getName(): string diff --git a/src/Reflection/Adapter/ReflectionAttribute.php b/src/Reflection/Adapter/ReflectionAttribute.php index 514abb330..2466e7dd7 100644 --- a/src/Reflection/Adapter/ReflectionAttribute.php +++ b/src/Reflection/Adapter/ReflectionAttribute.php @@ -15,8 +15,10 @@ /** @template-extends CoreReflectionAttribute */ final class ReflectionAttribute extends CoreReflectionAttribute { - public function __construct(private BetterReflectionAttribute $betterReflectionAttribute) + private BetterReflectionAttribute $betterReflectionAttribute; + public function __construct(BetterReflectionAttribute $betterReflectionAttribute) { + $this->betterReflectionAttribute = $betterReflectionAttribute; unset($this->name); } @@ -75,7 +77,10 @@ public function __toString(): string return $this->betterReflectionAttribute->__toString(); } - public function __get(string $name): mixed + /** + * @return mixed + */ + public function __get(string $name) { if ($name === 'name') { return $this->betterReflectionAttribute->getName(); diff --git a/src/Reflection/Adapter/ReflectionAttributeFactory.php b/src/Reflection/Adapter/ReflectionAttributeFactory.php index ace0566b6..6663d4a25 100644 --- a/src/Reflection/Adapter/ReflectionAttributeFactory.php +++ b/src/Reflection/Adapter/ReflectionAttributeFactory.php @@ -10,7 +10,10 @@ final class ReflectionAttributeFactory { - public static function create(BetterReflectionAttribute $betterReflectionAttribute): ReflectionAttribute|FakeReflectionAttribute + /** + * @return \Roave\BetterReflection\Reflection\Adapter\ReflectionAttribute|\Roave\BetterReflection\Reflection\Adapter\FakeReflectionAttribute + */ + public static function create(BetterReflectionAttribute $betterReflectionAttribute) { if (PHP_VERSION_ID >= 80000 && PHP_VERSION_ID < 80012) { return new FakeReflectionAttribute($betterReflectionAttribute); diff --git a/src/Reflection/Adapter/ReflectionClass.php b/src/Reflection/Adapter/ReflectionClass.php index d56b459c4..acbf1e5d4 100644 --- a/src/Reflection/Adapter/ReflectionClass.php +++ b/src/Reflection/Adapter/ReflectionClass.php @@ -36,6 +36,10 @@ */ final class ReflectionClass extends CoreReflectionClass { + /** + * @var BetterReflectionClass|BetterReflectionEnum + */ + private $betterReflectionClass; /** * @internal * @@ -53,12 +57,19 @@ final class ReflectionClass extends CoreReflectionClass /** @internal */ public const IS_READONLY_COMPATIBILITY = 65536; - public function __construct(private BetterReflectionClass|BetterReflectionEnum $betterReflectionClass) + /** + * @param BetterReflectionClass|BetterReflectionEnum $betterReflectionClass + */ + public function __construct($betterReflectionClass) { + $this->betterReflectionClass = $betterReflectionClass; unset($this->name); } - public function getBetterReflection(): BetterReflectionClass|BetterReflectionEnum + /** + * @return BetterReflectionClass|BetterReflectionEnum + */ + public function getBetterReflection() { return $this->betterReflectionClass; } @@ -69,7 +80,10 @@ public function __toString(): string return $this->betterReflectionClass->__toString(); } - public function __get(string $name): mixed + /** + * @return mixed + */ + public function __get(string $name) { if ($name === 'name') { return $this->betterReflectionClass->getName(); @@ -276,11 +290,11 @@ public function hasConstant($name): bool * * @psalm-mutation-free */ - public function getConstants(int|null $filter = null): array + public function getConstants(?int $filter = null): array { /** @psalm-suppress ImpureFunctionCall */ return array_map( - fn (BetterReflectionClassConstant|BetterReflectionEnumCase $betterConstantOrEnumCase): mixed => $this->getConstantValue($betterConstantOrEnumCase), + fn ($betterConstantOrEnumCase) => $this->getConstantValue($betterConstantOrEnumCase), $this->filterBetterReflectionClassConstants($filter), ); } @@ -310,8 +324,10 @@ public function getConstant($name) return $betterReflectionConstant->getValue(); } - /** @psalm-pure */ - private function getConstantValue(BetterReflectionClassConstant|BetterReflectionEnumCase $betterConstantOrEnumCase): mixed + /** @psalm-pure + * @param BetterReflectionClassConstant|BetterReflectionEnumCase $betterConstantOrEnumCase + * @return mixed */ + private function getConstantValue($betterConstantOrEnumCase) { if ($betterConstantOrEnumCase instanceof BetterReflectionEnumCase) { throw new Exception\NotImplemented('Not implemented'); @@ -353,10 +369,10 @@ public function getReflectionConstant($name) * * @psalm-mutation-free */ - public function getReflectionConstants(int|null $filter = null): array + public function getReflectionConstants(?int $filter = null): array { return array_values(array_map( - static fn (BetterReflectionClassConstant|BetterReflectionEnumCase $betterConstantOrEnum): ReflectionClassConstant => new ReflectionClassConstant($betterConstantOrEnum), + static fn ($betterConstantOrEnum): ReflectionClassConstant => new ReflectionClassConstant($betterConstantOrEnum), $this->filterBetterReflectionClassConstants($filter), )); } @@ -368,7 +384,7 @@ public function getReflectionConstants(int|null $filter = null): array * * @psalm-mutation-free */ - private function filterBetterReflectionClassConstants(int|null $filter): array + private function filterBetterReflectionClassConstants(?int $filter): array { $reflectionConstants = $this->betterReflectionClass->getConstants($filter ?? 0); @@ -763,7 +779,7 @@ public function getShortName(): string * * @return list */ - public function getAttributes(string|null $name = null, int $flags = 0): array + public function getAttributes(?string $name = null, int $flags = 0): array { if ($flags !== 0 && $flags !== ReflectionAttribute::IS_INSTANCEOF) { throw new ValueError('Argument #2 ($flags) must be a valid attribute filter flag'); @@ -778,7 +794,7 @@ public function getAttributes(string|null $name = null, int $flags = 0): array } /** @psalm-suppress ImpureFunctionCall */ - return array_map(static fn (BetterReflectionAttribute $betterReflectionAttribute): ReflectionAttribute|FakeReflectionAttribute => ReflectionAttributeFactory::create($betterReflectionAttribute), $attributes); + return array_map(static fn (BetterReflectionAttribute $betterReflectionAttribute) => ReflectionAttributeFactory::create($betterReflectionAttribute), $attributes); } /** @psalm-mutation-free */ diff --git a/src/Reflection/Adapter/ReflectionClassConstant.php b/src/Reflection/Adapter/ReflectionClassConstant.php index 1a8490c0a..2093bbfa6 100644 --- a/src/Reflection/Adapter/ReflectionClassConstant.php +++ b/src/Reflection/Adapter/ReflectionClassConstant.php @@ -24,6 +24,10 @@ final class ReflectionClassConstant extends CoreReflectionClassConstant { + /** + * @var BetterReflectionClassConstant|BetterReflectionEnumCase + */ + private $betterClassConstantOrEnumCase; /** @internal */ public const IS_PUBLIC_COMPATIBILITY = 1; @@ -36,8 +40,12 @@ final class ReflectionClassConstant extends CoreReflectionClassConstant /** @internal */ public const IS_FINAL_COMPATIBILITY = 32; - public function __construct(private BetterReflectionClassConstant|BetterReflectionEnumCase $betterClassConstantOrEnumCase) + /** + * @param BetterReflectionClassConstant|BetterReflectionEnumCase $betterClassConstantOrEnumCase + */ + public function __construct($betterClassConstantOrEnumCase) { + $this->betterClassConstantOrEnumCase = $betterClassConstantOrEnumCase; unset($this->name); unset($this->class); } @@ -47,7 +55,10 @@ public function getName(): string return $this->betterClassConstantOrEnumCase->getName(); } - public function getBetterReflection(): BetterReflectionClassConstant|BetterReflectionEnumCase + /** + * @return BetterReflectionClassConstant|BetterReflectionEnumCase + */ + public function getBetterReflection() { return $this->betterClassConstantOrEnumCase; } @@ -163,7 +174,7 @@ public function __toString(): string * * @return list */ - public function getAttributes(string|null $name = null, int $flags = 0): array + public function getAttributes(?string $name = null, int $flags = 0): array { if ($flags !== 0 && $flags !== ReflectionAttribute::IS_INSTANCEOF) { throw new ValueError('Argument #2 ($flags) must be a valid attribute filter flag'); @@ -178,7 +189,7 @@ public function getAttributes(string|null $name = null, int $flags = 0): array } /** @psalm-suppress ImpureFunctionCall */ - return array_map(static fn (BetterReflectionAttribute $betterReflectionAttribute): ReflectionAttribute|FakeReflectionAttribute => ReflectionAttributeFactory::create($betterReflectionAttribute), $attributes); + return array_map(static fn (BetterReflectionAttribute $betterReflectionAttribute) => ReflectionAttributeFactory::create($betterReflectionAttribute), $attributes); } public function isFinal(): bool @@ -200,7 +211,10 @@ public function isDeprecated(): bool return $this->betterClassConstantOrEnumCase->isDeprecated(); } - public function __get(string $name): mixed + /** + * @return mixed + */ + public function __get(string $name) { if ($name === 'name') { return $this->betterClassConstantOrEnumCase->getName(); diff --git a/src/Reflection/Adapter/ReflectionFunction.php b/src/Reflection/Adapter/ReflectionFunction.php index 256cff3b3..9a22a0373 100644 --- a/src/Reflection/Adapter/ReflectionFunction.php +++ b/src/Reflection/Adapter/ReflectionFunction.php @@ -26,8 +26,10 @@ final class ReflectionFunction extends CoreReflectionFunction { - public function __construct(private BetterReflectionFunction $betterReflectionFunction) + private BetterReflectionFunction $betterReflectionFunction; + public function __construct(BetterReflectionFunction $betterReflectionFunction) { + $this->betterReflectionFunction = $betterReflectionFunction; unset($this->name); } @@ -278,7 +280,7 @@ public function isStatic(): bool * * @return list */ - public function getAttributes(string|null $name = null, int $flags = 0): array + public function getAttributes(?string $name = null, int $flags = 0): array { if ($flags !== 0 && $flags !== ReflectionAttribute::IS_INSTANCEOF) { throw new ValueError('Argument #2 ($flags) must be a valid attribute filter flag'); @@ -292,10 +294,13 @@ public function getAttributes(string|null $name = null, int $flags = 0): array $attributes = $this->betterReflectionFunction->getAttributes(); } - return array_map(static fn (BetterReflectionAttribute $betterReflectionAttribute): ReflectionAttribute|FakeReflectionAttribute => ReflectionAttributeFactory::create($betterReflectionAttribute), $attributes); + return array_map(static fn (BetterReflectionAttribute $betterReflectionAttribute) => ReflectionAttributeFactory::create($betterReflectionAttribute), $attributes); } - public function __get(string $name): mixed + /** + * @return mixed + */ + public function __get(string $name) { if ($name === 'name') { return $this->betterReflectionFunction->getName(); diff --git a/src/Reflection/Adapter/ReflectionIntersectionType.php b/src/Reflection/Adapter/ReflectionIntersectionType.php index 17cbbff1d..bad7a121c 100644 --- a/src/Reflection/Adapter/ReflectionIntersectionType.php +++ b/src/Reflection/Adapter/ReflectionIntersectionType.php @@ -14,8 +14,10 @@ /** @psalm-immutable */ class ReflectionIntersectionType extends CoreReflectionIntersectionType { - public function __construct(private BetterReflectionIntersectionType $betterReflectionType) + private BetterReflectionIntersectionType $betterReflectionType; + public function __construct(BetterReflectionIntersectionType $betterReflectionType) { + $this->betterReflectionType = $betterReflectionType; } /** @return non-empty-list */ diff --git a/src/Reflection/Adapter/ReflectionMethod.php b/src/Reflection/Adapter/ReflectionMethod.php index a6999d69b..3bfe0c08a 100644 --- a/src/Reflection/Adapter/ReflectionMethod.php +++ b/src/Reflection/Adapter/ReflectionMethod.php @@ -29,8 +29,10 @@ /** @psalm-suppress PropertyNotSetInConstructor */ final class ReflectionMethod extends CoreReflectionMethod { - public function __construct(private BetterReflectionMethod $betterReflectionMethod) + private BetterReflectionMethod $betterReflectionMethod; + public function __construct(BetterReflectionMethod $betterReflectionMethod) { + $this->betterReflectionMethod = $betterReflectionMethod; unset($this->name); unset($this->class); } @@ -102,7 +104,7 @@ public function getStartLine() { try { return $this->betterReflectionMethod->getStartLine(); - } catch (CodeLocationMissing) { + } catch (CodeLocationMissing $exception) { return false; } } @@ -115,7 +117,7 @@ public function getEndLine() { try { return $this->betterReflectionMethod->getEndLine(); - } catch (CodeLocationMissing) { + } catch (CodeLocationMissing $exception) { return false; } } @@ -285,7 +287,7 @@ public function invoke($object = null, $arg = null, ...$args) { try { return $this->betterReflectionMethod->invoke($object, $arg, ...$args); - } catch (NoObjectProvided) { + } catch (NoObjectProvided $exception) { return null; } catch (Throwable $e) { throw new CoreReflectionException($e->getMessage(), 0, $e); @@ -305,7 +307,7 @@ public function invokeArgs($object = null, array $args = []) { try { return $this->betterReflectionMethod->invokeArgs($object, $args); - } catch (NoObjectProvided) { + } catch (NoObjectProvided $exception) { return null; } catch (Throwable $e) { throw new CoreReflectionException($e->getMessage(), 0, $e); @@ -328,7 +330,7 @@ public function hasPrototype(): bool $this->betterReflectionMethod->getPrototype(); return true; - } catch (MethodPrototypeNotFound) { + } catch (MethodPrototypeNotFound $exception) { return false; } } @@ -349,7 +351,7 @@ public function setAccessible($accessible): void * * @return list */ - public function getAttributes(string|null $name = null, int $flags = 0): array + public function getAttributes(?string $name = null, int $flags = 0): array { if ($flags !== 0 && $flags !== ReflectionAttribute::IS_INSTANCEOF) { throw new ValueError('Argument #2 ($flags) must be a valid attribute filter flag'); @@ -363,7 +365,7 @@ public function getAttributes(string|null $name = null, int $flags = 0): array $attributes = $this->betterReflectionMethod->getAttributes(); } - return array_map(static fn (BetterReflectionAttribute $betterReflectionAttribute): ReflectionAttribute|FakeReflectionAttribute => ReflectionAttributeFactory::create($betterReflectionAttribute), $attributes); + return array_map(static fn (BetterReflectionAttribute $betterReflectionAttribute) => ReflectionAttributeFactory::create($betterReflectionAttribute), $attributes); } public function hasTentativeReturnType(): bool @@ -387,7 +389,10 @@ public function getClosureUsedVariables(): array throw new Exception\NotImplemented('Not implemented'); } - public function __get(string $name): mixed + /** + * @return mixed + */ + public function __get(string $name) { if ($name === 'name') { return $this->betterReflectionMethod->getName(); diff --git a/src/Reflection/Adapter/ReflectionNamedType.php b/src/Reflection/Adapter/ReflectionNamedType.php index 452d89eea..7426f0c00 100644 --- a/src/Reflection/Adapter/ReflectionNamedType.php +++ b/src/Reflection/Adapter/ReflectionNamedType.php @@ -12,6 +12,11 @@ /** @psalm-immutable */ final class ReflectionNamedType extends CoreReflectionNamedType { + /** + * @var \Roave\BetterReflection\Reflection\ReflectionNamedType|non-empty-string + */ + private $type; + private bool $allowsNull = false; /** @var non-empty-string */ private string $nameType; @@ -21,8 +26,10 @@ final class ReflectionNamedType extends CoreReflectionNamedType private string $toString; /** @param \Roave\BetterReflection\Reflection\ReflectionNamedType|non-empty-string $type */ - public function __construct(private BetterReflectionNamedType|string $type, private bool $allowsNull = false) + public function __construct($type, bool $allowsNull = false) { + $this->type = $type; + $this->allowsNull = $allowsNull; if ($type instanceof BetterReflectionNamedType) { $nameType = $type->getName(); $this->nameType = $nameType; diff --git a/src/Reflection/Adapter/ReflectionObject.php b/src/Reflection/Adapter/ReflectionObject.php index a7cfe8855..e6aa082cf 100644 --- a/src/Reflection/Adapter/ReflectionObject.php +++ b/src/Reflection/Adapter/ReflectionObject.php @@ -29,8 +29,10 @@ /** @psalm-suppress PropertyNotSetInConstructor */ final class ReflectionObject extends CoreReflectionObject { - public function __construct(private BetterReflectionObject $betterReflectionObject) + private BetterReflectionObject $betterReflectionObject; + public function __construct(BetterReflectionObject $betterReflectionObject) { + $this->betterReflectionObject = $betterReflectionObject; unset($this->name); } @@ -111,7 +113,7 @@ public function getDocComment() return $this->betterReflectionObject->getDocComment() ?? false; } - public function getConstructor(): ReflectionMethod|null + public function getConstructor(): ?\Roave\BetterReflection\Reflection\Adapter\ReflectionMethod { $constructor = $this->betterReflectionObject->getConstructor(); @@ -232,10 +234,10 @@ public function hasConstant($name): bool * * @return array */ - public function getConstants(int|null $filter = null): array + public function getConstants(?int $filter = null): array { return array_map( - static fn (BetterReflectionClassConstant $betterConstant): mixed => $betterConstant->getValue(), + static fn (BetterReflectionClassConstant $betterConstant) => $betterConstant->getValue(), $this->betterReflectionObject->getConstants($filter ?? 0), ); } @@ -283,7 +285,7 @@ public function getReflectionConstant($name) * * @return list */ - public function getReflectionConstants(int|null $filter = null): array + public function getReflectionConstants(?int $filter = null): array { return array_values(array_map( static fn (BetterReflectionClassConstant $betterConstant): ReflectionClassConstant => new ReflectionClassConstant($betterConstant), @@ -616,7 +618,7 @@ public function isAnonymous(): bool * * @return list */ - public function getAttributes(string|null $name = null, int $flags = 0): array + public function getAttributes(?string $name = null, int $flags = 0): array { if ($flags !== 0 && $flags !== ReflectionAttribute::IS_INSTANCEOF) { throw new ValueError('Argument #2 ($flags) must be a valid attribute filter flag'); @@ -630,7 +632,7 @@ public function getAttributes(string|null $name = null, int $flags = 0): array $attributes = $this->betterReflectionObject->getAttributes(); } - return array_map(static fn (BetterReflectionAttribute $betterReflectionAttribute): ReflectionAttribute|FakeReflectionAttribute => ReflectionAttributeFactory::create($betterReflectionAttribute), $attributes); + return array_map(static fn (BetterReflectionAttribute $betterReflectionAttribute) => ReflectionAttributeFactory::create($betterReflectionAttribute), $attributes); } public function isEnum(): bool @@ -638,7 +640,10 @@ public function isEnum(): bool return $this->betterReflectionObject->isEnum(); } - public function __get(string $name): mixed + /** + * @return mixed + */ + public function __get(string $name) { if ($name === 'name') { return $this->betterReflectionObject->getName(); diff --git a/src/Reflection/Adapter/ReflectionParameter.php b/src/Reflection/Adapter/ReflectionParameter.php index dda8a0d32..935de4db3 100644 --- a/src/Reflection/Adapter/ReflectionParameter.php +++ b/src/Reflection/Adapter/ReflectionParameter.php @@ -31,8 +31,10 @@ */ final class ReflectionParameter extends CoreReflectionParameter { - public function __construct(private BetterReflectionParameter $betterReflectionParameter) + private BetterReflectionParameter $betterReflectionParameter; + public function __construct(BetterReflectionParameter $betterReflectionParameter) { + $this->betterReflectionParameter = $betterReflectionParameter; unset($this->name); } @@ -131,7 +133,7 @@ public function getClass(): ?CoreReflectionClass try { /** @phpstan-ignore variable.undefined */ return new ReflectionClass($classType->getClass()); - } catch (LogicException) { + } catch (LogicException $exception) { return null; } } @@ -148,8 +150,9 @@ public function isCallable(): bool /** * For isArray() and isCallable(). + * @param BetterReflectionNamedType|BetterReflectionUnionType|BetterReflectionIntersectionType|null $typeReflection */ - private function isType(BetterReflectionNamedType|BetterReflectionUnionType|BetterReflectionIntersectionType|null $typeReflection, string $type): bool + private function isType($typeReflection, string $type): bool { if ($typeReflection === null) { return false; @@ -254,7 +257,7 @@ public function isPromoted(): bool * * @return list */ - public function getAttributes(string|null $name = null, int $flags = 0): array + public function getAttributes(?string $name = null, int $flags = 0): array { if ($flags !== 0 && $flags !== ReflectionAttribute::IS_INSTANCEOF) { throw new ValueError('Argument #2 ($flags) must be a valid attribute filter flag'); @@ -269,10 +272,13 @@ public function getAttributes(string|null $name = null, int $flags = 0): array } /** @psalm-suppress ImpureFunctionCall */ - return array_map(static fn (BetterReflectionAttribute $betterReflectionAttribute): ReflectionAttribute|FakeReflectionAttribute => ReflectionAttributeFactory::create($betterReflectionAttribute), $attributes); + return array_map(static fn (BetterReflectionAttribute $betterReflectionAttribute) => ReflectionAttributeFactory::create($betterReflectionAttribute), $attributes); } - public function __get(string $name): mixed + /** + * @return mixed + */ + public function __get(string $name) { if ($name === 'name') { return $this->betterReflectionParameter->getName(); diff --git a/src/Reflection/Adapter/ReflectionProperty.php b/src/Reflection/Adapter/ReflectionProperty.php index 119100fa0..a990944fa 100644 --- a/src/Reflection/Adapter/ReflectionProperty.php +++ b/src/Reflection/Adapter/ReflectionProperty.php @@ -30,6 +30,7 @@ /** @psalm-suppress PropertyNotSetInConstructor */ final class ReflectionProperty extends CoreReflectionProperty { + private BetterReflectionProperty $betterReflectionProperty; /** * @internal * @@ -68,8 +69,9 @@ final class ReflectionProperty extends CoreReflectionProperty /** @internal */ public const IS_READONLY_COMPATIBILITY = 128; - public function __construct(private BetterReflectionProperty $betterReflectionProperty) + public function __construct(BetterReflectionProperty $betterReflectionProperty) { + $this->betterReflectionProperty = $betterReflectionProperty; unset($this->name); unset($this->class); } @@ -87,34 +89,40 @@ public function getName(): string /** * {@inheritDoc} + * @return mixed */ #[ReturnTypeWillChange] - public function getValue($object = null): mixed + public function getValue($object = null) { try { return $this->betterReflectionProperty->getValue($object); - } catch (NoObjectProvided) { + } catch (NoObjectProvided $exception) { return null; } catch (Throwable $e) { throw new CoreReflectionException($e->getMessage(), 0, $e); } } - /** @psalm-suppress MethodSignatureMismatch */ - public function setValue(mixed $objectOrValue, mixed $value = null): void + /** @psalm-suppress MethodSignatureMismatch + * @param mixed $objectOrValue + * @param mixed $value */ + public function setValue($objectOrValue, $value = null): void { try { $this->betterReflectionProperty->setValue($objectOrValue, $value); - } catch (NoObjectProvided) { + } catch (NoObjectProvided $exception) { throw new ArgumentCountError('ReflectionProperty::setValue() expects exactly 2 arguments, 1 given'); - } catch (NotAnObject) { + } catch (NotAnObject $exception) { throw new TypeError(sprintf('ReflectionProperty::setValue(): Argument #1 ($objectOrValue) must be of type object, %s given', gettype($objectOrValue))); } catch (Throwable $e) { throw new CoreReflectionException($e->getMessage(), 0, $e); } } - public function setRawValueWithoutLazyInitialization(object $object, mixed $value): void + /** + * @param mixed $value + */ + public function setRawValueWithoutLazyInitialization(object $object, $value): void { throw Exception\NotImplementedBecauseItTriggersAutoloading::create(); } @@ -273,7 +281,7 @@ public function isPromoted(): bool * * @return list */ - public function getAttributes(string|null $name = null, int $flags = 0): array + public function getAttributes(?string $name = null, int $flags = 0): array { if ($flags !== 0 && $flags !== ReflectionAttribute::IS_INSTANCEOF) { throw new ValueError('Argument #2 ($flags) must be a valid attribute filter flag'); @@ -287,7 +295,7 @@ public function getAttributes(string|null $name = null, int $flags = 0): array $attributes = $this->betterReflectionProperty->getAttributes(); } - return array_map(static fn (BetterReflectionAttribute $betterReflectionAttribute): ReflectionAttribute|FakeReflectionAttribute => ReflectionAttributeFactory::create($betterReflectionAttribute), $attributes); + return array_map(static fn (BetterReflectionAttribute $betterReflectionAttribute) => ReflectionAttributeFactory::create($betterReflectionAttribute), $attributes); } public function isReadOnly(): bool @@ -313,7 +321,7 @@ public function hasHook(PropertyHookType $hookType): bool } /** @psalm-suppress UndefinedClass */ - public function getHook(PropertyHookType $hookType): ReflectionMethod|null + public function getHook(PropertyHookType $hookType): ?\Roave\BetterReflection\Reflection\Adapter\ReflectionMethod { $hook = $this->betterReflectionProperty->getHook(BetterReflectionPropertyHookType::fromCoreReflectionPropertyHookType($hookType)); if ($hook === null) { @@ -350,11 +358,13 @@ public function getSettableType(): ?\ReflectionType } /* @return never public function getRawValue(object $object): mixed - { - throw Exception\NotImplementedBecauseItTriggersAutoloading::create(); - }*/ - - public function setRawValue(object $object, mixed $value): void + { + throw Exception\NotImplementedBecauseItTriggersAutoloading::create(); + }*/ + /** + * @param mixed $value + */ + public function setRawValue(object $object, $value): void { if ($this->hasHooks()) { throw Exception\NotImplementedBecauseItTriggersAutoloading::create(); @@ -363,7 +373,10 @@ public function setRawValue(object $object, mixed $value): void $this->setValue($object, $value); } - public function __get(string $name): mixed + /** + * @return mixed + */ + public function __get(string $name) { if ($name === 'name') { return $this->betterReflectionProperty->getName(); diff --git a/src/Reflection/Adapter/ReflectionType.php b/src/Reflection/Adapter/ReflectionType.php index 676cfa4d0..c398fe8e6 100644 --- a/src/Reflection/Adapter/ReflectionType.php +++ b/src/Reflection/Adapter/ReflectionType.php @@ -17,8 +17,10 @@ /** @psalm-immutable */ abstract class ReflectionType extends CoreReflectionType { - /** @psalm-pure */ - public static function fromTypeOrNull(BetterReflectionUnionType|BetterReflectionNamedType|BetterReflectionIntersectionType|null $betterReflectionType): ReflectionUnionType|ReflectionNamedType|ReflectionIntersectionType|null + /** @psalm-pure + * @param BetterReflectionUnionType|BetterReflectionNamedType|BetterReflectionIntersectionType|null $betterReflectionType + * @return \Roave\BetterReflection\Reflection\Adapter\ReflectionUnionType|\Roave\BetterReflection\Reflection\Adapter\ReflectionNamedType|\Roave\BetterReflection\Reflection\Adapter\ReflectionIntersectionType|null */ + public static function fromTypeOrNull($betterReflectionType) { return $betterReflectionType !== null ? self::fromType($betterReflectionType) : null; } @@ -27,8 +29,10 @@ public static function fromTypeOrNull(BetterReflectionUnionType|BetterReflection * @internal * * @psalm-pure + * @param BetterReflectionNamedType|BetterReflectionUnionType|BetterReflectionIntersectionType $betterReflectionType + * @return \Roave\BetterReflection\Reflection\Adapter\ReflectionUnionType|\Roave\BetterReflection\Reflection\Adapter\ReflectionNamedType|\Roave\BetterReflection\Reflection\Adapter\ReflectionIntersectionType */ - public static function fromType(BetterReflectionNamedType|BetterReflectionUnionType|BetterReflectionIntersectionType $betterReflectionType): ReflectionUnionType|ReflectionNamedType|ReflectionIntersectionType + public static function fromType($betterReflectionType) { if ($betterReflectionType instanceof BetterReflectionUnionType) { // php-src has this weird behavior where a union type composed of a single type `T` diff --git a/src/Reflection/Adapter/ReflectionUnionType.php b/src/Reflection/Adapter/ReflectionUnionType.php index e933cdc18..db7745106 100644 --- a/src/Reflection/Adapter/ReflectionUnionType.php +++ b/src/Reflection/Adapter/ReflectionUnionType.php @@ -14,14 +14,16 @@ /** @psalm-immutable */ final class ReflectionUnionType extends CoreReflectionUnionType { - public function __construct(private BetterReflectionUnionType $betterReflectionType) + private BetterReflectionUnionType $betterReflectionType; + public function __construct(BetterReflectionUnionType $betterReflectionType) { + $this->betterReflectionType = $betterReflectionType; } /** @return non-empty-list */ public function getTypes(): array { - return array_map(static function (BetterReflectionType $type): ReflectionNamedType|ReflectionIntersectionType { + return array_map(static function (BetterReflectionType $type) { $adapterType = ReflectionType::fromType($type); assert($adapterType instanceof ReflectionNamedType || $adapterType instanceof ReflectionIntersectionType); diff --git a/src/Reflection/Annotation/AnnotationHelper.php b/src/Reflection/Annotation/AnnotationHelper.php index 92301ff13..66a8ba444 100644 --- a/src/Reflection/Annotation/AnnotationHelper.php +++ b/src/Reflection/Annotation/AnnotationHelper.php @@ -12,7 +12,7 @@ final class AnnotationHelper public const TENTATIVE_RETURN_TYPE_ANNOTATION = 'betterReflectionTentativeReturnType'; /** @psalm-pure */ - public static function isDeprecated(string|null $docComment): bool + public static function isDeprecated(?string $docComment): bool { if ($docComment === null) { return false; @@ -22,7 +22,7 @@ public static function isDeprecated(string|null $docComment): bool } /** @psalm-pure */ - public static function hasTentativeReturnType(string|null $docComment): bool + public static function hasTentativeReturnType(?string $docComment): bool { if ($docComment === null) { return false; diff --git a/src/Reflection/Attribute/ReflectionAttributeHelper.php b/src/Reflection/Attribute/ReflectionAttributeHelper.php index b8a3fdea1..eb5c50092 100644 --- a/src/Reflection/Attribute/ReflectionAttributeHelper.php +++ b/src/Reflection/Attribute/ReflectionAttributeHelper.php @@ -28,19 +28,16 @@ class ReflectionAttributeHelper * @return list * * @psalm-pure + * @param \Roave\BetterReflection\Reflection\ReflectionClass|\Roave\BetterReflection\Reflection\ReflectionMethod|\Roave\BetterReflection\Reflection\ReflectionFunction|\Roave\BetterReflection\Reflection\ReflectionClassConstant|\Roave\BetterReflection\Reflection\ReflectionEnumCase|\Roave\BetterReflection\Reflection\ReflectionProperty|\Roave\BetterReflection\Reflection\ReflectionParameter $reflection */ - public static function createAttributes( - Reflector $reflector, - ReflectionClass|ReflectionMethod|ReflectionFunction|ReflectionClassConstant|ReflectionEnumCase|ReflectionProperty|ReflectionParameter $reflection, - array $attrGroups, - ): array { + public static function createAttributes(Reflector $reflector, $reflection, array $attrGroups): array + { $repeated = []; foreach ($attrGroups as $attributesGroupNode) { foreach ($attributesGroupNode->attrs as $attributeNode) { $repeated[$attributeNode->name->toLowerString()][] = $attributeNode; } } - $attributes = []; foreach ($attrGroups as $attributesGroupNode) { foreach ($attributesGroupNode->attrs as $attributeNode) { @@ -52,7 +49,6 @@ public static function createAttributes( ); } } - return $attributes; } diff --git a/src/Reflection/Deprecated/DeprecatedHelper.php b/src/Reflection/Deprecated/DeprecatedHelper.php index 85e57f022..0c7f8b609 100644 --- a/src/Reflection/Deprecated/DeprecatedHelper.php +++ b/src/Reflection/Deprecated/DeprecatedHelper.php @@ -16,8 +16,9 @@ /** @internal */ final class DeprecatedHelper { - /** @psalm-pure */ - public static function isDeprecated(ReflectionClass|ReflectionMethod|ReflectionFunction|ReflectionClassConstant|ReflectionEnumCase|ReflectionProperty $reflection): bool + /** @psalm-pure + * @param \Roave\BetterReflection\Reflection\ReflectionClass|\Roave\BetterReflection\Reflection\ReflectionMethod|\Roave\BetterReflection\Reflection\ReflectionFunction|\Roave\BetterReflection\Reflection\ReflectionClassConstant|\Roave\BetterReflection\Reflection\ReflectionEnumCase|\Roave\BetterReflection\Reflection\ReflectionProperty $reflection */ + public static function isDeprecated($reflection): bool { // We don't use Deprecated::class because the class is currently missing in stubs if (ReflectionAttributeHelper::filterAttributesByName($reflection->getAttributes(), 'Deprecated') !== []) { diff --git a/src/Reflection/Exception/CodeLocationMissing.php b/src/Reflection/Exception/CodeLocationMissing.php index 9867096ca..746424c3c 100644 --- a/src/Reflection/Exception/CodeLocationMissing.php +++ b/src/Reflection/Exception/CodeLocationMissing.php @@ -8,7 +8,7 @@ class CodeLocationMissing extends RuntimeException { - public static function create(string|null $hint = null): self + public static function create(?string $hint = null): self { $message = 'Code location is missing'; if ($hint !== null) { diff --git a/src/Reflection/Exception/NotAnObject.php b/src/Reflection/Exception/NotAnObject.php index 1906329ab..e0bd833e5 100644 --- a/src/Reflection/Exception/NotAnObject.php +++ b/src/Reflection/Exception/NotAnObject.php @@ -11,7 +11,10 @@ class NotAnObject extends InvalidArgumentException { - public static function fromNonObject(mixed $nonObject): self + /** + * @param mixed $nonObject + */ + public static function fromNonObject($nonObject): self { return new self(sprintf('Provided "%s" is not an object', gettype($nonObject))); } diff --git a/src/Reflection/ReflectionAttribute.php b/src/Reflection/ReflectionAttribute.php index c71dbcba8..b5a407e2d 100644 --- a/src/Reflection/ReflectionAttribute.php +++ b/src/Reflection/ReflectionAttribute.php @@ -17,31 +17,36 @@ /** @psalm-immutable */ class ReflectionAttribute { + private Reflector $reflector; + /** + * @var \Roave\BetterReflection\Reflection\ReflectionClass|\Roave\BetterReflection\Reflection\ReflectionMethod|\Roave\BetterReflection\Reflection\ReflectionFunction|\Roave\BetterReflection\Reflection\ReflectionClassConstant|\Roave\BetterReflection\Reflection\ReflectionEnumCase|\Roave\BetterReflection\Reflection\ReflectionProperty|\Roave\BetterReflection\Reflection\ReflectionParameter + */ + private $owner; + private bool $isRepeated; /** @var non-empty-string */ private string $name; /** @var array */ private array $arguments; - /** @internal */ - public function __construct( - private Reflector $reflector, - Node\Attribute $node, - private ReflectionClass|ReflectionMethod|ReflectionFunction|ReflectionClassConstant|ReflectionEnumCase|ReflectionProperty|ReflectionParameter $owner, - private bool $isRepeated, - ) { + /** @internal + * @param \Roave\BetterReflection\Reflection\ReflectionClass|\Roave\BetterReflection\Reflection\ReflectionMethod|\Roave\BetterReflection\Reflection\ReflectionFunction|\Roave\BetterReflection\Reflection\ReflectionClassConstant|\Roave\BetterReflection\Reflection\ReflectionEnumCase|\Roave\BetterReflection\Reflection\ReflectionProperty|\Roave\BetterReflection\Reflection\ReflectionParameter $owner */ + public function __construct(Reflector $reflector, Node\Attribute $node, $owner, bool $isRepeated) + { + $this->reflector = $reflector; + $this->owner = $owner; + $this->isRepeated = $isRepeated; $this->name = $node->name->toString(); - $arguments = []; foreach ($node->args as $argNo => $arg) { - $arguments[$arg->name?->toString() ?? $argNo] = $arg->value; + $arguments[(($nullsafeVariable1 = $arg->name) ? $nullsafeVariable1->toString() : null) ?? $argNo] = $arg->value; } - $this->arguments = $arguments; } - /** @internal */ - public function withOwner(ReflectionClass|ReflectionMethod|ReflectionFunction|ReflectionClassConstant|ReflectionEnumCase|ReflectionProperty|ReflectionParameter $owner): self + /** @internal + * @param \Roave\BetterReflection\Reflection\ReflectionClass|\Roave\BetterReflection\Reflection\ReflectionMethod|\Roave\BetterReflection\Reflection\ReflectionFunction|\Roave\BetterReflection\Reflection\ReflectionClassConstant|\Roave\BetterReflection\Reflection\ReflectionEnumCase|\Roave\BetterReflection\Reflection\ReflectionProperty|\Roave\BetterReflection\Reflection\ReflectionParameter $owner */ + public function withOwner($owner): self { $clone = clone $this; $clone->owner = $owner; @@ -74,23 +79,30 @@ public function getArguments(): array $compiler = new CompileNodeToValue(); $context = new CompilerContext($this->reflector, $this->owner); - return array_map(static fn (Node\Expr $value): mixed => $compiler->__invoke($value, $context)->value, $this->arguments); + return array_map(static fn (Node\Expr $value) => $compiler->__invoke($value, $context)->value, $this->arguments); } /** @return int-mask-of */ public function getTarget(): int { - return match (true) { - $this->owner instanceof ReflectionClass => Attribute::TARGET_CLASS, - $this->owner instanceof ReflectionFunction => Attribute::TARGET_FUNCTION, - $this->owner instanceof ReflectionMethod => Attribute::TARGET_METHOD, - $this->owner instanceof ReflectionProperty => Attribute::TARGET_PROPERTY, - $this->owner instanceof ReflectionClassConstant => Attribute::TARGET_CLASS_CONSTANT, - $this->owner instanceof ReflectionEnumCase => Attribute::TARGET_CLASS_CONSTANT, - // @infection-ignore-all InstanceOf_: There's no other option - $this->owner instanceof ReflectionParameter => Attribute::TARGET_PARAMETER, - default => throw new LogicException('unknown owner'), // @phpstan-ignore-line - }; + switch (true) { + case $this->owner instanceof ReflectionClass: + return Attribute::TARGET_CLASS; + case $this->owner instanceof ReflectionFunction: + return Attribute::TARGET_FUNCTION; + case $this->owner instanceof ReflectionMethod: + return Attribute::TARGET_METHOD; + case $this->owner instanceof ReflectionProperty: + return Attribute::TARGET_PROPERTY; + case $this->owner instanceof ReflectionClassConstant: + return Attribute::TARGET_CLASS_CONSTANT; + case $this->owner instanceof ReflectionEnumCase: + return Attribute::TARGET_CLASS_CONSTANT; + case $this->owner instanceof ReflectionParameter: + return Attribute::TARGET_PARAMETER; + default: + throw new LogicException('unknown owner'); + } } public function isRepeated(): bool diff --git a/src/Reflection/ReflectionClass.php b/src/Reflection/ReflectionClass.php index 6ab9bcf4e..879803e62 100644 --- a/src/Reflection/ReflectionClass.php +++ b/src/Reflection/ReflectionClass.php @@ -61,15 +61,21 @@ /** @psalm-immutable */ class ReflectionClass implements Reflection { + private Reflector $reflector; + private LocatedSource $locatedSource; + /** + * @var non-empty-string|null + */ + private $namespace = null; public const ANONYMOUS_CLASS_NAME_PREFIX = 'class@anonymous'; public const ANONYMOUS_CLASS_NAME_PREFIX_REGEXP = '~^(?:class|[\w\\\\]+)@anonymous~'; private const ANONYMOUS_CLASS_NAME_SUFFIX = '@anonymous'; /** @var class-string|trait-string|null */ - private string|null $name; + private $name; /** @var non-empty-string|null */ - private string|null $shortName; + private $shortName; private bool $isInterface; private bool $isTrait; @@ -80,7 +86,7 @@ class ReflectionClass implements Reflection private int $modifiers; /** @var non-empty-string|null */ - private string|null $docComment; + private $docComment; /** @var list */ private array $attributes; @@ -98,7 +104,7 @@ class ReflectionClass implements Reflection private int $endColumn; /** @var class-string|null */ - private string|null $parentClassName; + private $parentClassName; /** @var list */ private array $implementsClassNames; @@ -128,53 +134,58 @@ class ReflectionClass implements Reflection * @var array|null * @psalm-allow-private-mutation */ - private array|null $cachedConstants = null; + private $cachedConstants = null; /** * @var array|null * @psalm-allow-private-mutation */ - private array|null $cachedProperties = null; + private $cachedProperties = null; /** @var array|null */ - private array|null $cachedInterfaces = null; + private $cachedInterfaces = null; /** @var list|null */ - private array|null $cachedInterfaceNames = null; + private $cachedInterfaceNames = null; /** @var list|null */ - private array|null $cachedTraits = null; + private $cachedTraits = null; - private ReflectionMethod|null $cachedConstructor = null; + /** + * @var \Roave\BetterReflection\Reflection\ReflectionMethod|null + */ + private $cachedConstructor = null; - private string|null $cachedName = null; + /** + * @var string|null + */ + private $cachedName = null; /** * @psalm-allow-private-mutation * @var array|null */ - private array|null $cachedMethods = null; + private $cachedMethods = null; /** * @var list|null * @psalm-allow-private-mutation */ - private array|null $cachedParentClasses = null; + private $cachedParentClasses = null; /** * @internal * * @param non-empty-string|null $namespace + * @param ClassNode|InterfaceNode|TraitNode|EnumNode $node */ - protected function __construct( - private Reflector $reflector, - ClassNode|InterfaceNode|TraitNode|EnumNode $node, - private LocatedSource $locatedSource, - private string|null $namespace = null, - ) { + protected function __construct(Reflector $reflector, $node, LocatedSource $locatedSource, ?string $namespace = null) + { + $this->reflector = $reflector; + $this->locatedSource = $locatedSource; + $this->namespace = $namespace; $name = null; $shortName = null; - if ($node->name instanceof Node\Identifier) { $namespacedName = $node->namespacedName; if ($namespacedName === null) { @@ -187,32 +198,26 @@ protected function __construct( $shortName = $node->name->name; } - $this->name = $name; $this->shortName = $shortName; $this->isInterface = $node instanceof InterfaceNode; $this->isTrait = $node instanceof TraitNode; $this->isEnum = $node instanceof EnumNode; $this->isBackedEnum = $node instanceof EnumNode && $node->scalarType !== null; - $this->modifiers = $this->computeModifiers($node); $this->docComment = GetLastDocComment::forNode($node); $this->attributes = ReflectionAttributeHelper::createAttributes($reflector, $this, $node->attrGroups); - $startLine = $node->getStartLine(); assert($startLine > 0); $endLine = $node->getEndLine(); assert($endLine > 0); - $this->startLine = $startLine; $this->endLine = $endLine; $this->startColumn = CalculateReflectionColumn::getStartColumn($locatedSource->getSource(), $node); $this->endColumn = CalculateReflectionColumn::getEndColumn($locatedSource->getSource(), $node); - /** @var class-string|null $parentClassName */ - $parentClassName = $node instanceof ClassNode ? $node->extends?->toString() : null; + $parentClassName = $node instanceof ClassNode ? ($nullsafeVariable1 = $node->extends) ? $nullsafeVariable1->toString() : null : null; $this->parentClassName = $parentClassName; - // @infection-ignore-all UnwrapArrayMap: It works without array_map() as well but this is less magical /** @var list $implementsClassNames */ $implementsClassNames = array_map( @@ -220,7 +225,6 @@ protected function __construct( $node instanceof TraitNode ? [] : ($node instanceof InterfaceNode ? $node->extends : $node->implements), ); $this->implementsClassNames = $implementsClassNames; - /** @var list $traitClassNames */ $traitClassNames = array_merge( [], @@ -231,11 +235,9 @@ protected function __construct( ), ); $this->traitClassNames = $traitClassNames; - $this->immediateConstants = $this->createImmediateConstants($node, $reflector); $this->immediateProperties = $this->createImmediateProperties($node, $reflector); $this->immediateMethods = $this->createImmediateMethods($node, $reflector); - $this->traitsData = $this->computeTraitsData($node); } @@ -268,12 +270,8 @@ public static function createFromInstance(object $instance): self * @param ClassNode|InterfaceNode|TraitNode|EnumNode $node Node has to be processed by the PhpParser\NodeVisitor\NameResolver * @param non-empty-string|null $namespace optional - if omitted, we assume it is global namespaced class */ - public static function createFromNode( - Reflector $reflector, - ClassNode|InterfaceNode|TraitNode|EnumNode $node, - LocatedSource $locatedSource, - string|null $namespace = null, - ): self { + public static function createFromNode(Reflector $reflector, $node, LocatedSource $locatedSource, ?string $namespace = null): self + { return new self($reflector, $node, $locatedSource, $namespace); } @@ -338,7 +336,7 @@ public function getName(): string } /** @return class-string|null */ - public function getParentClassName(): string|null + public function getParentClassName(): ?string { return $this->parentClassName; } @@ -349,7 +347,7 @@ public function getParentClassName(): string|null * * @return non-empty-string|null */ - public function getNamespaceName(): string|null + public function getNamespaceName(): ?string { return $this->namespace; } @@ -364,7 +362,7 @@ public function inNamespace(): bool } /** @return non-empty-string|null */ - public function getExtensionName(): string|null + public function getExtensionName(): ?string { return $this->locatedSource->getExtensionName(); } @@ -405,7 +403,7 @@ private function createMethodsFromTrait(ReflectionMethod $method): array } } - $createMethod = function (string|null $aliasMethodName) use ($method, $methodModifiers): ReflectionMethod { + $createMethod = function (?string $aliasMethodName) use ($method, $methodModifiers): ReflectionMethod { assert($aliasMethodName === null || $aliasMethodName !== ''); /** @phpstan-ignore argument.type */ @@ -589,8 +587,9 @@ public function getImmediateMethods(int $filter = 0): array ); } - /** @return array */ - private function createImmediateMethods(ClassNode|InterfaceNode|TraitNode|EnumNode $node, Reflector $reflector): array + /** @return array + * @param ClassNode|InterfaceNode|TraitNode|EnumNode $node */ + private function createImmediateMethods($node, Reflector $reflector): array { $methods = []; @@ -627,7 +626,7 @@ private function createImmediateMethods(ClassNode|InterfaceNode|TraitNode|EnumNo private function addEnumMethods(EnumNode $node, array $methods): array { $internalLocatedSource = new InternalLocatedSource('', $this->getName(), 'Core', $this->getFileName()); - $createMethod = function (string $name, array $params, Node\Identifier|Node\NullableType $returnType) use ($internalLocatedSource): ReflectionMethod { + $createMethod = function (string $name, array $params, $returnType) use ($internalLocatedSource): ReflectionMethod { assert($name !== ''); /** @var array{flags: int, params: Node\Param[], returnType: Node\Identifier|Node\NullableType} $classMethodSubnodes */ @@ -683,7 +682,7 @@ private function addEnumMethods(EnumNode $node, array $methods): array * * @param non-empty-string $methodName */ - public function getMethod(string $methodName): ReflectionMethod|null + public function getMethod(string $methodName): ?\Roave\BetterReflection\Reflection\ReflectionMethod { $lowercaseMethodName = strtolower($methodName); $methods = $this->getMethodsIndexedByLowercasedName(AlreadyVisitedClasses::createEmpty()); @@ -738,13 +737,14 @@ public function hasConstant(string $name): bool * * @param non-empty-string $name */ - public function getConstant(string $name): ReflectionClassConstant|null + public function getConstant(string $name): ?\Roave\BetterReflection\Reflection\ReflectionClassConstant { return $this->getConstants()[$name] ?? null; } - /** @return array */ - private function createImmediateConstants(ClassNode|InterfaceNode|TraitNode|EnumNode $node, Reflector $reflector): array + /** @return array + * @param ClassNode|InterfaceNode|TraitNode|EnumNode $node */ + private function createImmediateConstants($node, Reflector $reflector): array { $constants = []; @@ -840,7 +840,7 @@ private function getConstantsConsideringAlreadyVisitedClasses(AlreadyVisitedClas /** * Get the constructor method for this class. */ - public function getConstructor(): ReflectionMethod|null + public function getConstructor(): ?\Roave\BetterReflection\Reflection\ReflectionMethod { if ($this->cachedConstructor !== null) { return $this->cachedConstructor; @@ -873,8 +873,9 @@ public function getImmediateProperties(int $filter = 0): array ); } - /** @return array */ - private function createImmediateProperties(ClassNode|InterfaceNode|TraitNode|EnumNode $node, Reflector $reflector): array + /** @return array + * @param ClassNode|InterfaceNode|TraitNode|EnumNode $node */ + private function createImmediateProperties($node, Reflector $reflector): array { $properties = []; @@ -937,10 +938,11 @@ private function createImmediateProperties(ClassNode|InterfaceNode|TraitNode|Enu * @param array $properties * * @return array + * @param EnumNode|InterfaceNode $node */ - private function addEnumProperties(array $properties, EnumNode|InterfaceNode $node, Reflector $reflector): array + private function addEnumProperties(array $properties, $node, Reflector $reflector): array { - $createProperty = function (string $name, Node\Name|Node\Identifier|Node\UnionType $type) use ($reflector): ReflectionProperty { + $createProperty = function (string $name, $type) use ($reflector): ReflectionProperty { $propertyNode = new Node\Stmt\Property( Modifiers::PUBLIC | Modifiers::READONLY, [new Node\PropertyItem($name)], @@ -1025,7 +1027,7 @@ private function getPropertiesConsideringAlreadyVisitedClasses(AlreadyVisitedCla $properties = array_merge( array_filter( - $this->getParentClass()?->getPropertiesConsideringAlreadyVisitedClasses($alreadyVisitedClasses) ?? [], + (($nullsafeVariable2 = $this->getParentClass()) ? $nullsafeVariable2->getPropertiesConsideringAlreadyVisitedClasses($alreadyVisitedClasses) : null) ?? [], static fn (ReflectionProperty $property) => ! $property->isPrivate(), ), ...array_map( @@ -1064,7 +1066,7 @@ private function getPropertiesConsideringAlreadyVisitedClasses(AlreadyVisitedCla * * @param non-empty-string $name */ - public function getProperty(string $name): ReflectionProperty|null + public function getProperty(string $name): ?\Roave\BetterReflection\Reflection\ReflectionProperty { $properties = $this->getProperties(); @@ -1095,7 +1097,7 @@ public function getDefaultProperties(): array } /** @return non-empty-string|null */ - public function getFileName(): string|null + public function getFileName(): ?string { return $this->locatedSource->getFileName(); } @@ -1140,7 +1142,7 @@ public function getEndColumn(): int /** * Get the parent class, if it is defined. */ - public function getParentClass(): ReflectionClass|null + public function getParentClass(): ?\Roave\BetterReflection\Reflection\ReflectionClass { $parentClassName = $this->getParentClassName(); if ($parentClassName === null) { @@ -1153,7 +1155,7 @@ public function getParentClass(): ReflectionClass|null try { return $this->reflector->reflectClass($parentClassName); - } catch (IdentifierNotFound) { + } catch (IdentifierNotFound $exception) { return null; } } @@ -1178,7 +1180,7 @@ private function getParentClasses(): array while ($parentClassName !== null) { try { $parentClass = $this->reflector->reflectClass($parentClassName); - } catch (IdentifierNotFound) { + } catch (IdentifierNotFound $exception) { break; } @@ -1201,7 +1203,7 @@ private function getParentClasses(): array } /** @return non-empty-string|null */ - public function getDocComment(): string|null + public function getDocComment(): ?string { return $this->docComment; } @@ -1272,8 +1274,9 @@ public function getModifiers(): int * @return int-mask-of * * @phpstan-ignore-next-line return.unusedType + * @param ClassNode|InterfaceNode|TraitNode|EnumNode $node */ - private function computeModifiers(ClassNode|InterfaceNode|TraitNode|EnumNode $node): int + private function computeModifiers($node): int { if (! $node instanceof ClassNode) { return 0; @@ -1318,7 +1321,7 @@ public function getTraits(): array foreach ($this->traitClassNames as $traitClassName) { try { $traits[] = $this->reflector->reflectClass($traitClassName); - } catch (IdentifierNotFound) { + } catch (IdentifierNotFound $exception) { // pass } } @@ -1349,7 +1352,7 @@ private function addStringableInterface(array $interfaces): array try { $stringableInterfaceReflection = $this->reflector->reflectClass($stringableClassName); $interfaces[$stringableClassName] = $stringableInterfaceReflection; - } catch (IdentifierNotFound) { + } catch (IdentifierNotFound $exception) { // Stringable interface does not exist on target PHP version } @@ -1500,8 +1503,9 @@ public function getTraitAliases(): array * precedences: array, * hashes: array, * } + * @param ClassNode|InterfaceNode|TraitNode|EnumNode $node */ - private function computeTraitsData(ClassNode|InterfaceNode|TraitNode|EnumNode $node): array + private function computeTraitsData($node): array { $traitsData = [ 'aliases' => [], @@ -1643,7 +1647,7 @@ public function getImmediateInterfaces(): array foreach ($this->implementsClassNames as $interfaceClassName) { try { $interfaces[$interfaceClassName] = $this->reflector->reflectClass($interfaceClassName); - } catch (IdentifierNotFound) { + } catch (IdentifierNotFound $exception) { continue; } } @@ -1796,7 +1800,7 @@ private function getCurrentClassImplementedInterfacesIndexedByName(): array foreach ($interface->getInterfacesHierarchy(AlreadyVisitedClasses::createEmpty()) as $n => $i) { $interfaces[$n] = $i; } - } catch (IdentifierNotFound) { + } catch (IdentifierNotFound $exception) { continue; } } @@ -1845,8 +1849,9 @@ private function getInterfacesHierarchy(AlreadyVisitedClasses $alreadyVisitedCla * @throws NoObjectProvided * @throws NotAnObject * @throws ObjectNotInstanceOfClass + * @return mixed */ - public function getStaticPropertyValue(string $propertyName): mixed + public function getStaticPropertyValue(string $propertyName) { $property = $this->getProperty($propertyName); @@ -1866,8 +1871,9 @@ public function getStaticPropertyValue(string $propertyName): mixed * @throws NoObjectProvided * @throws NotAnObject * @throws ObjectNotInstanceOfClass + * @param mixed $value */ - public function setStaticPropertyValue(string $propertyName, mixed $value): void + public function setStaticPropertyValue(string $propertyName, $value): void { $property = $this->getProperty($propertyName); diff --git a/src/Reflection/ReflectionClassConstant.php b/src/Reflection/ReflectionClassConstant.php index b6457ab3e..551003bea 100644 --- a/src/Reflection/ReflectionClassConstant.php +++ b/src/Reflection/ReflectionClassConstant.php @@ -25,18 +25,24 @@ /** @psalm-immutable */ class ReflectionClassConstant { + private Reflector $reflector; + private ReflectionClass $declaringClass; + private ReflectionClass $implementingClass; /** @var non-empty-string */ private string $name; /** @var int-mask-of */ private int $modifiers; - private ReflectionNamedType|ReflectionUnionType|ReflectionIntersectionType|null $type; + /** + * @var \Roave\BetterReflection\Reflection\ReflectionNamedType|\Roave\BetterReflection\Reflection\ReflectionUnionType|\Roave\BetterReflection\Reflection\ReflectionIntersectionType|null + */ + private $type; private Node\Expr $value; /** @var non-empty-string|null */ - private string|null $docComment; + private $docComment; /** @var list */ private array $attributes; @@ -53,29 +59,25 @@ class ReflectionClassConstant /** @var positive-int */ private int $endColumn; - /** @psalm-allow-private-mutation */ - private CompiledValue|null $compiledValue = null; + /** @psalm-allow-private-mutation + * @var \Roave\BetterReflection\NodeCompiler\CompiledValue|null */ + private $compiledValue = null; - private function __construct( - private Reflector $reflector, - ClassConst $node, - int $positionInNode, - private ReflectionClass $declaringClass, - private ReflectionClass $implementingClass, - ) { + private function __construct(Reflector $reflector, ClassConst $node, int $positionInNode, ReflectionClass $declaringClass, ReflectionClass $implementingClass) + { + $this->reflector = $reflector; + $this->declaringClass = $declaringClass; + $this->implementingClass = $implementingClass; $this->name = $node->consts[$positionInNode]->name->name; $this->modifiers = $this->computeModifiers($node); $this->type = $this->createType($node); $this->value = $node->consts[$positionInNode]->value; - $this->docComment = GetLastDocComment::forNode($node); $this->attributes = ReflectionAttributeHelper::createAttributes($reflector, $this, $node->attrGroups); - $startLine = $node->getStartLine(); assert($startLine > 0); $endLine = $node->getEndLine(); assert($endLine > 0); - $this->startLine = $startLine; $this->endLine = $endLine; $this->startColumn = CalculateReflectionColumn::getStartColumn($declaringClass->getLocatedSource()->getSource(), $node); @@ -87,13 +89,8 @@ private function __construct( * * @internal */ - public static function createFromNode( - Reflector $reflector, - ClassConst $node, - int $positionInNode, - ReflectionClass $declaringClass, - ReflectionClass $implementingClass, - ): self { + public static function createFromNode(Reflector $reflector, ClassConst $node, int $positionInNode, ReflectionClass $declaringClass, ReflectionClass $implementingClass): self + { return new self( $reflector, $node, @@ -127,7 +124,10 @@ public function getName(): string return $this->name; } - private function createType(ClassConst $node): ReflectionNamedType|ReflectionUnionType|ReflectionIntersectionType|null + /** + * @return \Roave\BetterReflection\Reflection\ReflectionNamedType|\Roave\BetterReflection\Reflection\ReflectionUnionType|\Roave\BetterReflection\Reflection\ReflectionIntersectionType|null + */ + private function createType(ClassConst $node) { $type = $node->type; @@ -140,7 +140,10 @@ private function createType(ClassConst $node): ReflectionNamedType|ReflectionUni return ReflectionType::createFromNode($this->reflector, $this, $type); } - public function getType(): ReflectionNamedType|ReflectionUnionType|ReflectionIntersectionType|null + /** + * @return \Roave\BetterReflection\Reflection\ReflectionNamedType|\Roave\BetterReflection\Reflection\ReflectionUnionType|\Roave\BetterReflection\Reflection\ReflectionIntersectionType|null + */ + public function getType() { return $this->type; } @@ -157,8 +160,9 @@ public function getValueExpression(): Node\Expr /** * Returns constant value + * @return mixed */ - public function getValue(): mixed + public function getValue() { if ($this->compiledValue === null) { $this->compiledValue = (new CompileNodeToValue())->__invoke( @@ -268,7 +272,7 @@ public function getImplementingClass(): ReflectionClass } /** @return non-empty-string|null */ - public function getDocComment(): string|null + public function getDocComment(): ?string { return $this->docComment; } diff --git a/src/Reflection/ReflectionConstant.php b/src/Reflection/ReflectionConstant.php index badd5e043..c2b2746c4 100644 --- a/src/Reflection/ReflectionConstant.php +++ b/src/Reflection/ReflectionConstant.php @@ -29,6 +29,12 @@ /** @psalm-immutable */ class ReflectionConstant implements Reflection { + private Reflector $reflector; + private LocatedSource $locatedSource; + /** + * @var non-empty-string|null + */ + private $namespace = null; /** * @var non-empty-string * @psalm-allow-private-mutation @@ -44,7 +50,7 @@ class ReflectionConstant implements Reflection private Node\Expr $value; /** @var non-empty-string|null */ - private string|null $docComment; + private $docComment; /** @var positive-int */ private int $startLine; @@ -58,20 +64,19 @@ class ReflectionConstant implements Reflection /** @var positive-int */ private int $endColumn; - /** @psalm-allow-private-mutation */ - private CompiledValue|null $compiledValue = null; + /** @psalm-allow-private-mutation + * @var \Roave\BetterReflection\NodeCompiler\CompiledValue|null */ + private $compiledValue = null; - /** @param non-empty-string|null $namespace */ - private function __construct( - private Reflector $reflector, - Node\Stmt\Const_|Node\Expr\FuncCall $node, - private LocatedSource $locatedSource, + /** @param non-empty-string|null $namespace + * @param \PhpParser\Node\Stmt\Const_|\PhpParser\Node\Expr\FuncCall $node */ + private function __construct(Reflector $reflector, $node, LocatedSource $locatedSource, ?string $namespace = null, ?int $positionInNode = null) + { + $this->reflector = $reflector; + $this->locatedSource = $locatedSource; /** @psalm-allow-private-mutation */ - private string|null $namespace = null, - int|null $positionInNode = null, - ) { + $this->namespace = $namespace; $this->setNamesFromNode($node, $positionInNode); - if ($node instanceof Node\Expr\FuncCall) { $argumentValueNode = $node->args[1]; assert($argumentValueNode instanceof Node\Arg); @@ -80,14 +85,11 @@ private function __construct( /** @psalm-suppress PossiblyNullArrayOffset */ $this->value = $node->consts[$positionInNode]->value; } - $this->docComment = GetLastDocComment::forNode($node); - $startLine = $node->getStartLine(); assert($startLine > 0); $endLine = $node->getEndLine(); assert($endLine > 0); - $this->startLine = $startLine; $this->endLine = $endLine; $this->startColumn = CalculateReflectionColumn::getStartColumn($this->locatedSource->getSource(), $node); @@ -102,30 +104,19 @@ private function __construct( * @param Node\Stmt\Const_|Node\Expr\FuncCall $node Node has to be processed by the PhpParser\NodeVisitor\NameResolver * @param non-empty-string|null $namespace */ - public static function createFromNode( - Reflector $reflector, - Node $node, - LocatedSource $locatedSource, - string|null $namespace = null, - int|null $positionInNode = null, - ): self { + public static function createFromNode(Reflector $reflector, Node $node, LocatedSource $locatedSource, ?string $namespace = null, ?int $positionInNode = null): self + { if ($node instanceof Node\Stmt\Const_) { assert(is_int($positionInNode)); return self::createFromConstKeyword($reflector, $node, $locatedSource, $namespace, $positionInNode); } - return self::createFromDefineFunctionCall($reflector, $node, $locatedSource); } /** @param non-empty-string|null $namespace */ - private static function createFromConstKeyword( - Reflector $reflector, - Node\Stmt\Const_ $node, - LocatedSource $locatedSource, - string|null $namespace, - int $positionInNode, - ): self { + private static function createFromConstKeyword(Reflector $reflector, Node\Stmt\Const_ $node, LocatedSource $locatedSource, ?string $namespace, int $positionInNode): self + { return new self( $reflector, $node, @@ -136,13 +127,9 @@ private static function createFromConstKeyword( } /** @throws InvalidConstantNode */ - private static function createFromDefineFunctionCall( - Reflector $reflector, - Node\Expr\FuncCall $node, - LocatedSource $locatedSource, - ): self { + private static function createFromDefineFunctionCall(Reflector $reflector, Node\Expr\FuncCall $node, LocatedSource $locatedSource): self + { ConstantNodeChecker::assertValidDefineFunctionCall($node); - return new self( $reflector, $node, @@ -178,7 +165,7 @@ public function getName(): string * * @return non-empty-string|null */ - public function getNamespaceName(): string|null + public function getNamespaceName(): ?string { return $this->namespace; } @@ -193,7 +180,7 @@ public function inNamespace(): bool } /** @return non-empty-string|null */ - public function getExtensionName(): string|null + public function getExtensionName(): ?string { return $this->locatedSource->getExtensionName(); } @@ -228,7 +215,7 @@ public function getValueExpression(): Node\Expr /** * @return mixed */ - public function getValue(): mixed + public function getValue() { if ($this->compiledValue === null) { $this->compiledValue = (new CompileNodeToValue())->__invoke( @@ -241,7 +228,7 @@ public function getValue(): mixed } /** @return non-empty-string|null */ - public function getFileName(): string|null + public function getFileName(): ?string { return $this->locatedSource->getFileName(); } @@ -284,7 +271,7 @@ public function getEndColumn(): int } /** @return non-empty-string|null */ - public function getDocComment(): string|null + public function getDocComment(): ?string { return $this->docComment; } @@ -295,7 +282,10 @@ public function __toString(): string return ReflectionConstantStringCast::toString($this); } - private function setNamesFromNode(Node\Stmt\Const_|Node\Expr\FuncCall $node, int|null $positionInNode): void + /** + * @param \PhpParser\Node\Stmt\Const_|\PhpParser\Node\Expr\FuncCall $node + */ + private function setNamesFromNode($node, ?int $positionInNode): void { if ($node instanceof Node\Expr\FuncCall) { $name = $this->getNameFromDefineFunctionCall($node); diff --git a/src/Reflection/ReflectionEnum.php b/src/Reflection/ReflectionEnum.php index eace5f5b7..ff9e7f59a 100644 --- a/src/Reflection/ReflectionEnum.php +++ b/src/Reflection/ReflectionEnum.php @@ -22,7 +22,11 @@ /** @psalm-immutable */ class ReflectionEnum extends ReflectionClass { - private ReflectionNamedType|null $backingType; + private Reflector $reflector; + /** + * @var \Roave\BetterReflection\Reflection\ReflectionNamedType|null + */ + private $backingType; /** @var array */ private array $cases; @@ -32,14 +36,10 @@ class ReflectionEnum extends ReflectionClass * * @phpcs:disable Generic.CodeAnalysis.UselessOverridingMethod.Found */ - private function __construct( - private Reflector $reflector, - EnumNode $node, - LocatedSource $locatedSource, - string|null $namespace = null, - ) { + private function __construct(Reflector $reflector, EnumNode $node, LocatedSource $locatedSource, ?string $namespace = null) + { + $this->reflector = $reflector; parent::__construct($reflector, $node, $locatedSource, $namespace); - $this->backingType = $this->createBackingType($node); $this->cases = $this->createCases($node); } @@ -52,15 +52,10 @@ private function __construct( * * @psalm-suppress MoreSpecificImplementedParamType */ - public static function createFromNode( - Reflector $reflector, - ClassNode|InterfaceNode|TraitNode|EnumNode $node, - LocatedSource $locatedSource, - string|null $namespace = null, - ): self { + public static function createFromNode(Reflector $reflector, $node, LocatedSource $locatedSource, ?string $namespace = null): self + { $node = $node; assert($node instanceof EnumNode); - return new self($reflector, $node, $locatedSource, $namespace); } @@ -71,7 +66,7 @@ public function hasCase(string $name): bool } /** @param non-empty-string $name */ - public function getCase(string $name): ReflectionEnumCase|null + public function getCase(string $name): ?\Roave\BetterReflection\Reflection\ReflectionEnumCase { return $this->cases[$name] ?? null; } @@ -107,7 +102,7 @@ public function getBackingType(): ReflectionNamedType return $this->backingType; } - private function createBackingType(EnumNode $node): ReflectionNamedType|null + private function createBackingType(EnumNode $node): ?\Roave\BetterReflection\Reflection\ReflectionNamedType { if ($node->scalarType === null) { return null; diff --git a/src/Reflection/ReflectionEnumCase.php b/src/Reflection/ReflectionEnumCase.php index 9bd1ac361..39cab71d6 100644 --- a/src/Reflection/ReflectionEnumCase.php +++ b/src/Reflection/ReflectionEnumCase.php @@ -24,16 +24,21 @@ /** @psalm-immutable */ class ReflectionEnumCase { + private Reflector $reflector; + private ReflectionEnum $enum; /** @var non-empty-string */ private string $name; - private Node\Expr|null $value; + /** + * @var \PhpParser\Node\Expr|null + */ + private $value; /** @var list */ private array $attributes; /** @var non-empty-string|null */ - private string|null $docComment; + private $docComment; /** @var positive-int */ private int $startLine; @@ -47,25 +52,22 @@ class ReflectionEnumCase /** @var positive-int */ private int $endColumn; - /** @psalm-allow-private-mutation */ - private CompiledValue|null $compiledValue = null; + /** @psalm-allow-private-mutation + * @var \Roave\BetterReflection\NodeCompiler\CompiledValue|null */ + private $compiledValue = null; - private function __construct( - private Reflector $reflector, - EnumCase $node, - private ReflectionEnum $enum, - ) { + private function __construct(Reflector $reflector, EnumCase $node, ReflectionEnum $enum) + { + $this->reflector = $reflector; + $this->enum = $enum; $this->name = $node->name->toString(); - $this->value = $node->expr; $this->attributes = ReflectionAttributeHelper::createAttributes($reflector, $this, $node->attrGroups); $this->docComment = GetLastDocComment::forNode($node); - $startLine = $node->getStartLine(); assert($startLine > 0); $endLine = $node->getEndLine(); assert($endLine > 0); - $this->startLine = $startLine; $this->endLine = $endLine; $this->startColumn = CalculateReflectionColumn::getStartColumn($this->enum->getLocatedSource()->getSource(), $node); @@ -73,11 +75,8 @@ private function __construct( } /** @internal */ - public static function createFromNode( - Reflector $reflector, - EnumCase $node, - ReflectionEnum $enum, - ): self { + public static function createFromNode(Reflector $reflector, EnumCase $node, ReflectionEnum $enum): self + { return new self($reflector, $node, $enum); } @@ -101,7 +100,10 @@ public function getValueExpression(): Node\Expr return $this->value; } - public function getValue(): string|int + /** + * @return int|string + */ + public function getValue() { $value = $this->getCompiledValue()->value; assert(is_string($value) || is_int($value)); @@ -165,7 +167,7 @@ public function getDeclaringClass(): ReflectionClass } /** @return non-empty-string|null */ - public function getDocComment(): string|null + public function getDocComment(): ?string { return $this->docComment; } diff --git a/src/Reflection/ReflectionFunction.php b/src/Reflection/ReflectionFunction.php index 0b9adcb7c..8bbbff73d 100644 --- a/src/Reflection/ReflectionFunction.php +++ b/src/Reflection/ReflectionFunction.php @@ -23,29 +23,31 @@ /** @psalm-immutable */ class ReflectionFunction implements Reflection { + private Reflector $reflector; + private LocatedSource $locatedSource; + /** + * @var non-empty-string|null + */ + private $namespace = null; use ReflectionFunctionAbstract; public const CLOSURE_NAME = '{closure}'; private bool $isStatic; - /** @param non-empty-string|null $namespace */ - private function __construct( - private Reflector $reflector, - Node\Stmt\ClassMethod|Node\Stmt\Function_|Node\Expr\Closure|Node\Expr\ArrowFunction $node, - private LocatedSource $locatedSource, - private string|null $namespace = null, - ) { + /** @param non-empty-string|null $namespace + * @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\Closure|\PhpParser\Node\Expr\ArrowFunction $node */ + private function __construct(Reflector $reflector, $node, LocatedSource $locatedSource, ?string $namespace = null) + { + $this->reflector = $reflector; + $this->locatedSource = $locatedSource; + $this->namespace = $namespace; assert($node instanceof Node\Stmt\Function_ || $node instanceof Node\Expr\Closure || $node instanceof Node\Expr\ArrowFunction); - $this->name = $node instanceof Node\Expr\Closure || $node instanceof Node\Expr\ArrowFunction ? self::CLOSURE_NAME : $node->name->name; - $this->fillFromNode($node); - $isClosure = $node instanceof Node\Expr\Closure || $node instanceof Node\Expr\ArrowFunction; - $this->isStatic = $isClosure && $node->static; $this->isClosure = $isClosure; $this->isGenerator = $this->nodeIsOrContainsYield($node); @@ -72,13 +74,10 @@ public function __toString(): string * @internal * * @param non-empty-string|null $namespace + * @param \PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\Closure|\PhpParser\Node\Expr\ArrowFunction $node */ - public static function createFromNode( - Reflector $reflector, - Node\Stmt\Function_|Node\Expr\Closure|Node\Expr\ArrowFunction $node, - LocatedSource $locatedSource, - string|null $namespace = null, - ): self { + public static function createFromNode(Reflector $reflector, $node, LocatedSource $locatedSource, ?string $namespace = null): self + { return new self($reflector, $node, $locatedSource, $namespace); } @@ -127,14 +126,16 @@ public function getClosure(): Closure $this->assertFunctionExist($functionName); - return static fn (mixed ...$args): mixed => $functionName(...$args); + return static fn (...$args) => $functionName(...$args); } /** * @throws NotImplemented * @throws FunctionDoesNotExist + * @param mixed ...$args + * @return mixed */ - public function invoke(mixed ...$args): mixed + public function invoke(...$args) { return $this->invokeArgs($args); } @@ -144,8 +145,9 @@ public function invoke(mixed ...$args): mixed * * @throws NotImplemented * @throws FunctionDoesNotExist + * @return mixed */ - public function invokeArgs(array $args = []): mixed + public function invokeArgs(array $args = []) { $this->assertIsNoClosure(); diff --git a/src/Reflection/ReflectionFunctionAbstract.php b/src/Reflection/ReflectionFunctionAbstract.php index 7d7f77052..3af22717a 100644 --- a/src/Reflection/ReflectionFunctionAbstract.php +++ b/src/Reflection/ReflectionFunctionAbstract.php @@ -44,8 +44,9 @@ trait ReflectionFunctionAbstract /** @psalm-allow-private-mutation */ private bool $returnsReference; - /** @psalm-allow-private-mutation */ - protected ReflectionNamedType|ReflectionUnionType|ReflectionIntersectionType|null $returnType; + /** @psalm-allow-private-mutation + * @var \Roave\BetterReflection\Reflection\ReflectionNamedType|\Roave\BetterReflection\Reflection\ReflectionUnionType|\Roave\BetterReflection\Reflection\ReflectionIntersectionType|null */ + protected $returnType; /** * @var list @@ -57,31 +58,31 @@ trait ReflectionFunctionAbstract * @var non-empty-string|null * @psalm-allow-private-mutation */ - private string|null $docComment; + private $docComment; /** * @var positive-int|null * @psalm-allow-private-mutation */ - private int|null $startLine; + private $startLine; /** * @var positive-int|null * @psalm-allow-private-mutation */ - private int|null $endLine; + private $endLine; /** * @var positive-int|null * @psalm-allow-private-mutation */ - private int|null $startColumn; + private $startColumn; /** * @var positive-int|null * @psalm-allow-private-mutation */ - private int|null $endColumn; + private $endColumn; /** @psalm-allow-private-mutation */ private bool $couldThrow = false; @@ -97,8 +98,9 @@ abstract public function __toString(): string; /** @return non-empty-string */ abstract public function getShortName(): string; - /** @psalm-external-mutation-free */ - private function fillFromNode(MethodNode|Node\PropertyHook|Node\Stmt\Function_|Node\Expr\Closure|Node\Expr\ArrowFunction $node): void + /** @psalm-external-mutation-free + * @param MethodNode|\PhpParser\Node\PropertyHook|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\Closure|\PhpParser\Node\Expr\ArrowFunction $node */ + private function fillFromNode($node): void { $this->parameters = $this->createParameters($node); $this->returnsReference = $node->returnsByRef(); @@ -124,19 +126,20 @@ private function fillFromNode(MethodNode|Node\PropertyHook|Node\Stmt\Function_|N try { $this->startColumn = CalculateReflectionColumn::getStartColumn($this->getLocatedSource()->getSource(), $node); - } catch (NoNodePosition) { + } catch (NoNodePosition $exception) { $this->startColumn = null; } try { $this->endColumn = CalculateReflectionColumn::getEndColumn($this->getLocatedSource()->getSource(), $node); - } catch (NoNodePosition) { + } catch (NoNodePosition $exception) { $this->endColumn = null; } } - /** @return array */ - private function createParameters(Node\Stmt\ClassMethod|Node\PropertyHook|Node\Stmt\Function_|Node\Expr\Closure|Node\Expr\ArrowFunction $node): array + /** @return array + * @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\PropertyHook|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\Closure|\PhpParser\Node\Expr\ArrowFunction $node */ + private function createParameters($node): array { $parameters = []; @@ -180,7 +183,7 @@ public function getName(): string * * @return non-empty-string|null */ - public function getNamespaceName(): string|null + public function getNamespaceName(): ?string { return $this->namespace; } @@ -252,19 +255,19 @@ private function isParameterOptional(array $parameterNodes, int $parameterIndex) * * @param non-empty-string $parameterName */ - public function getParameter(string $parameterName): ReflectionParameter|null + public function getParameter(string $parameterName): ?\Roave\BetterReflection\Reflection\ReflectionParameter { return $this->parameters[$parameterName] ?? null; } /** @return non-empty-string|null */ - public function getDocComment(): string|null + public function getDocComment(): ?string { return $this->docComment; } /** @return non-empty-string|null */ - public function getFileName(): string|null + public function getFileName(): ?string { return $this->locatedSource->getFileName(); } @@ -302,7 +305,7 @@ public function isUserDefined(): bool } /** @return non-empty-string|null */ - public function getExtensionName(): string|null + public function getExtensionName(): ?string { return $this->locatedSource->getExtensionName(); } @@ -327,7 +330,10 @@ public function couldThrow(): bool return $this->couldThrow; } - private function computeCouldThrow(MethodNode|Node\PropertyHook|Node\Stmt\Function_|Node\Expr\Closure|Node\Expr\ArrowFunction $node): bool + /** + * @param MethodNode|\PhpParser\Node\PropertyHook|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\Closure|\PhpParser\Node\Expr\ArrowFunction $node + */ + private function computeCouldThrow($node): bool { $statements = $node->getStmts(); @@ -458,8 +464,9 @@ public function returnsReference(): bool /** * Get the return type declaration + * @return \Roave\BetterReflection\Reflection\ReflectionNamedType|\Roave\BetterReflection\Reflection\ReflectionUnionType|\Roave\BetterReflection\Reflection\ReflectionIntersectionType|null */ - public function getReturnType(): ReflectionNamedType|ReflectionUnionType|ReflectionIntersectionType|null + public function getReturnType() { if ($this->hasTentativeReturnType()) { return null; @@ -489,7 +496,10 @@ public function hasTentativeReturnType(): bool return AnnotationHelper::hasTentativeReturnType($this->docComment); } - public function getTentativeReturnType(): ReflectionNamedType|ReflectionUnionType|ReflectionIntersectionType|null + /** + * @return \Roave\BetterReflection\Reflection\ReflectionNamedType|\Roave\BetterReflection\Reflection\ReflectionUnionType|\Roave\BetterReflection\Reflection\ReflectionIntersectionType|null + */ + public function getTentativeReturnType() { if (! $this->hasTentativeReturnType()) { return null; @@ -498,7 +508,11 @@ public function getTentativeReturnType(): ReflectionNamedType|ReflectionUnionTyp return $this->returnType; } - private function createReturnType(MethodNode|Node\PropertyHook|Node\Stmt\Function_|Node\Expr\Closure|Node\Expr\ArrowFunction $node): ReflectionNamedType|ReflectionUnionType|ReflectionIntersectionType|null + /** + * @param MethodNode|\PhpParser\Node\PropertyHook|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\Closure|\PhpParser\Node\Expr\ArrowFunction $node + * @return \Roave\BetterReflection\Reflection\ReflectionNamedType|\Roave\BetterReflection\Reflection\ReflectionUnionType|\Roave\BetterReflection\Reflection\ReflectionIntersectionType|null + */ + private function createReturnType($node) { $returnType = $node->getReturnType(); diff --git a/src/Reflection/ReflectionIntersectionType.php b/src/Reflection/ReflectionIntersectionType.php index cd17fa3dd..c9c6dd8b9 100644 --- a/src/Reflection/ReflectionIntersectionType.php +++ b/src/Reflection/ReflectionIntersectionType.php @@ -18,25 +18,24 @@ class ReflectionIntersectionType extends ReflectionType /** @var non-empty-list */ private array $types; - /** @internal */ - public function __construct( - Reflector $reflector, - ReflectionParameter|ReflectionMethod|ReflectionFunction|ReflectionEnum|ReflectionProperty|ReflectionClassConstant $owner, - IntersectionType $type, - ) { + /** @internal + * @param \Roave\BetterReflection\Reflection\ReflectionParameter|\Roave\BetterReflection\Reflection\ReflectionMethod|\Roave\BetterReflection\Reflection\ReflectionFunction|\Roave\BetterReflection\Reflection\ReflectionEnum|\Roave\BetterReflection\Reflection\ReflectionProperty|\Roave\BetterReflection\Reflection\ReflectionClassConstant $owner */ + public function __construct(Reflector $reflector, $owner, IntersectionType $type) + { /** @var non-empty-list $types */ - $types = array_map(static function (Node\Identifier|Node\Name $type) use ($reflector, $owner): ReflectionNamedType { + $types = array_map(static function ($type) use ($reflector, $owner): ReflectionNamedType { $type = ReflectionType::createFromNode($reflector, $owner, $type); assert($type instanceof ReflectionNamedType); return $type; }, $type->types); - $this->types = $types; } - /** @internal */ - public function withOwner(ReflectionParameter|ReflectionMethod|ReflectionFunction|ReflectionEnum|ReflectionProperty|ReflectionClassConstant $owner): static + /** @internal + * @param \Roave\BetterReflection\Reflection\ReflectionParameter|\Roave\BetterReflection\Reflection\ReflectionMethod|\Roave\BetterReflection\Reflection\ReflectionFunction|\Roave\BetterReflection\Reflection\ReflectionEnum|\Roave\BetterReflection\Reflection\ReflectionProperty|\Roave\BetterReflection\Reflection\ReflectionClassConstant $owner + * @return static */ + public function withOwner($owner) { $clone = clone $this; @@ -53,7 +52,10 @@ public function getTypes(): array return $this->types; } - public function allowsNull(): false + /** + * @return false + */ + public function allowsNull(): bool { return false; } diff --git a/src/Reflection/ReflectionMethod.php b/src/Reflection/ReflectionMethod.php index abff38cca..2e2d002dd 100644 --- a/src/Reflection/ReflectionMethod.php +++ b/src/Reflection/ReflectionMethod.php @@ -28,6 +28,23 @@ /** @psalm-immutable */ class ReflectionMethod { + private Reflector $reflector; + private LocatedSource $locatedSource; + /** + * @var non-empty-string|null + */ + private $namespace; + private ReflectionClass $declaringClass; + private ReflectionClass $implementingClass; + private ReflectionClass $currentClass; + /** + * @var non-empty-string|null + */ + private $aliasName; + /** + * @var \Roave\BetterReflection\Reflection\ReflectionProperty|null + */ + private $hookProperty = null; use ReflectionFunctionAbstract; /** @var int-mask-of */ @@ -37,24 +54,21 @@ class ReflectionMethod * @param non-empty-string $name * @param non-empty-string|null $aliasName * @param non-empty-string|null $namespace + * @param MethodNode|\PhpParser\Node\PropertyHook|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\Closure|\PhpParser\Node\Expr\ArrowFunction $node */ - private function __construct( - private Reflector $reflector, - MethodNode|Node\PropertyHook|Node\Stmt\Function_|Node\Expr\Closure|Node\Expr\ArrowFunction $node, - private LocatedSource $locatedSource, - string $name, - private string|null $namespace, - private ReflectionClass $declaringClass, - private ReflectionClass $implementingClass, - private ReflectionClass $currentClass, - private string|null $aliasName, - private ReflectionProperty|null $hookProperty = null, - ) { + private function __construct(Reflector $reflector, $node, LocatedSource $locatedSource, string $name, ?string $namespace, ReflectionClass $declaringClass, ReflectionClass $implementingClass, ReflectionClass $currentClass, ?string $aliasName, ?\Roave\BetterReflection\Reflection\ReflectionProperty $hookProperty = null) + { + $this->reflector = $reflector; + $this->locatedSource = $locatedSource; + $this->namespace = $namespace; + $this->declaringClass = $declaringClass; + $this->implementingClass = $implementingClass; + $this->currentClass = $currentClass; + $this->aliasName = $aliasName; + $this->hookProperty = $hookProperty; assert($node instanceof MethodNode || $node instanceof Node\PropertyHook); - $this->name = $name; $this->modifiers = $node instanceof MethodNode ? $this->computeModifiers($node) : 0; - $this->fillFromNode($node); } @@ -64,16 +78,8 @@ private function __construct( * @param non-empty-string|null $aliasName * @param non-empty-string|null $namespace */ - public static function createFromMethodNode( - Reflector $reflector, - MethodNode $node, - LocatedSource $locatedSource, - string|null $namespace, - ReflectionClass $declaringClass, - ReflectionClass $implementingClass, - ReflectionClass $currentClass, - string|null $aliasName = null, - ): self { + public static function createFromMethodNode(Reflector $reflector, MethodNode $node, LocatedSource $locatedSource, ?string $namespace, ReflectionClass $declaringClass, ReflectionClass $implementingClass, ReflectionClass $currentClass, ?string $aliasName = null): self + { return new self( $reflector, $node, @@ -91,18 +97,10 @@ public static function createFromMethodNode( * @internal * * @param non-empty-string $name + * @param \PhpParser\Node\Identifier|\PhpParser\Node\Name|\PhpParser\Node\NullableType|\PhpParser\Node\UnionType|\PhpParser\Node\IntersectionType|null $type */ - public static function createFromPropertyHook( - Reflector $reflector, - Node\PropertyHook $node, - LocatedSource $locatedSource, - string $name, - Node\Identifier|Node\Name|Node\NullableType|Node\UnionType|Node\IntersectionType|null $type, - ReflectionClass $declaringClass, - ReflectionClass $implementingClass, - ReflectionClass $currentClass, - ReflectionProperty $hookProperty, - ): self { + public static function createFromPropertyHook(Reflector $reflector, Node\PropertyHook $node, LocatedSource $locatedSource, string $name, $type, ReflectionClass $declaringClass, ReflectionClass $implementingClass, ReflectionClass $currentClass, ReflectionProperty $hookProperty): self + { $method = new self( $reflector, $node, @@ -115,14 +113,13 @@ public static function createFromPropertyHook( null, $hookProperty, ); - if ($node->name->name === 'set') { $method->returnType = ReflectionType::createFromNode($reflector, $method, new Node\Identifier('void')); if ($method->parameters === []) { $parameter = ReflectionParameter::createFromNode( $reflector, - new Node\Param(new Node\Expr\Variable('value'), type: $type), + new Node\Param(new Node\Expr\Variable('value'), null, $type), $method, 0, false, @@ -135,7 +132,6 @@ public static function createFromPropertyHook( ? ReflectionType::createFromNode($reflector, $method, $type) : null; } - return $method; } @@ -165,7 +161,7 @@ public static function createFromInstance(object $instance, string $methodName): * @param non-empty-string|null $aliasName * @param int-mask-of $modifiers */ - public function withImplementingClass(ReflectionClass $implementingClass, string|null $aliasName, int $modifiers): self + public function withImplementingClass(ReflectionClass $implementingClass, ?string $aliasName, int $modifiers): self { $clone = clone $this; @@ -212,7 +208,7 @@ public function getShortName(): string } /** @return non-empty-string|null */ - public function getAliasName(): string|null + public function getAliasName(): ?string { return $this->aliasName; } @@ -238,7 +234,7 @@ public function getPrototype(): self $currentClass = $currentClass->getParentClass(); if ($currentClass !== null) { - $prototype = $currentClass->getMethod($this->getName())?->findPrototype(); + $prototype = ($nullsafeVariable1 = $currentClass->getMethod($this->getName())) ? $nullsafeVariable1->findPrototype() : null; if ( $prototype !== null @@ -258,7 +254,7 @@ public function getPrototype(): self )); } - private function findPrototype(): self|null + private function findPrototype(): ?self { if ($this->isAbstract()) { return $this; @@ -270,7 +266,7 @@ private function findPrototype(): self|null try { return $this->getPrototype(); - } catch (Exception\MethodPrototypeNotFound) { + } catch (Exception\MethodPrototypeNotFound $exception) { return $this; } } @@ -309,7 +305,7 @@ public function inNamespace(): bool return false; } - public function getNamespaceName(): string|null + public function getNamespaceName(): ?string { return null; } @@ -424,19 +420,19 @@ public function getCurrentClass(): ReflectionClass * @throws NoObjectProvided * @throws ObjectNotInstanceOfClass */ - public function getClosure(object|null $object = null): Closure + public function getClosure(?object $object = null): Closure { $declaringClassName = $this->getDeclaringClass()->getName(); if ($this->isStatic()) { $this->assertClassExist($declaringClassName); - return fn (mixed ...$args): mixed => $this->callStaticMethod($args); + return fn (...$args) => $this->callStaticMethod($args); } $instance = $this->assertObject($object); - return fn (mixed ...$args): mixed => $this->callObjectMethod($instance, $args); + return fn (...$args) => $this->callObjectMethod($instance, $args); } /** @psalm-assert-if-true !null $this->getHookProperty() */ @@ -445,7 +441,7 @@ public function isHook(): bool return $this->hookProperty !== null; } - public function getHookProperty(): ReflectionProperty|null + public function getHookProperty(): ?\Roave\BetterReflection\Reflection\ReflectionProperty { return $this->hookProperty; } @@ -454,8 +450,10 @@ public function getHookProperty(): ReflectionProperty|null * @throws ClassDoesNotExist * @throws NoObjectProvided * @throws ObjectNotInstanceOfClass + * @param mixed ...$args + * @return mixed */ - public function invoke(object|null $object = null, mixed ...$args): mixed + public function invoke(?object $object = null, ...$args) { return $this->invokeArgs($object, $args); } @@ -466,8 +464,9 @@ public function invoke(object|null $object = null, mixed ...$args): mixed * @throws ClassDoesNotExist * @throws NoObjectProvided * @throws ObjectNotInstanceOfClass + * @return mixed */ - public function invokeArgs(object|null $object = null, array $args = []): mixed + public function invokeArgs(?object $object = null, array $args = []) { $implementingClassName = $this->getImplementingClass()->getName(); @@ -480,13 +479,14 @@ public function invokeArgs(object|null $object = null, array $args = []): mixed return $this->callObjectMethod($this->assertObject($object), $args); } - /** @param array $args */ - private function callStaticMethod(array $args): mixed + /** @param array $args + * @return mixed */ + private function callStaticMethod(array $args) { $implementingClassName = $this->getImplementingClass()->getName(); /** @psalm-suppress InvalidStringClass */ - $closure = Closure::bind(fn (string $implementingClassName, string $_methodName, array $methodArgs): mixed => $implementingClassName::{$_methodName}(...$methodArgs), null, $implementingClassName); + $closure = Closure::bind(fn (string $implementingClassName, string $_methodName, array $methodArgs) => $implementingClassName::{$_methodName}(...$methodArgs), null, $implementingClassName); /** @phpstan-ignore function.alreadyNarrowedType, instanceof.alwaysTrue */ assert($closure instanceof Closure); @@ -494,11 +494,12 @@ private function callStaticMethod(array $args): mixed return $closure->__invoke($implementingClassName, $this->getName(), $args); } - /** @param array $args */ - private function callObjectMethod(object $object, array $args): mixed + /** @param array $args + * @return mixed */ + private function callObjectMethod(object $object, array $args) { /** @psalm-suppress MixedMethodCall */ - $closure = Closure::bind(fn (object $object, string $methodName, array $methodArgs): mixed => $object->{$methodName}(...$methodArgs), $object, $this->getImplementingClass()->getName()); + $closure = Closure::bind(fn (object $object, string $methodName, array $methodArgs) => $object->{$methodName}(...$methodArgs), $object, $this->getImplementingClass()->getName()); /** @phpstan-ignore function.alreadyNarrowedType, instanceof.alwaysTrue */ assert($closure instanceof Closure); @@ -518,7 +519,7 @@ private function assertClassExist(string $className): void * @throws NoObjectProvided * @throws ObjectNotInstanceOfClass */ - private function assertObject(object|null $object): object + private function assertObject(?object $object): object { if ($object === null) { throw NoObjectProvided::create(); @@ -526,7 +527,7 @@ private function assertObject(object|null $object): object $implementingClassName = $this->getImplementingClass()->getName(); - if ($object::class !== $implementingClassName) { + if (get_class($object) !== $implementingClassName) { throw ObjectNotInstanceOfClass::fromClassName($implementingClassName); } diff --git a/src/Reflection/ReflectionNamedType.php b/src/Reflection/ReflectionNamedType.php index e5336d76f..b6c0670da 100644 --- a/src/Reflection/ReflectionNamedType.php +++ b/src/Reflection/ReflectionNamedType.php @@ -17,6 +17,15 @@ /** @psalm-immutable */ class ReflectionNamedType extends ReflectionType { + private Reflector $reflector; + /** + * @var \Roave\BetterReflection\Reflection\ReflectionParameter|\Roave\BetterReflection\Reflection\ReflectionMethod|\Roave\BetterReflection\Reflection\ReflectionFunction|\Roave\BetterReflection\Reflection\ReflectionEnum|\Roave\BetterReflection\Reflection\ReflectionProperty|\Roave\BetterReflection\Reflection\ReflectionClassConstant + */ + private $owner; + /** + * @var \PhpParser\Node\Identifier|\PhpParser\Node\Name + */ + private $type; private const BUILT_IN_TYPES = [ 'int' => null, 'float' => null, @@ -40,17 +49,21 @@ class ReflectionNamedType extends ReflectionType /** @var non-empty-string */ private string $name; - /** @internal */ - public function __construct( - private Reflector $reflector, - private ReflectionParameter|ReflectionMethod|ReflectionFunction|ReflectionEnum|ReflectionProperty|ReflectionClassConstant $owner, - private Identifier|Name $type, - ) { + /** @internal + * @param \Roave\BetterReflection\Reflection\ReflectionParameter|\Roave\BetterReflection\Reflection\ReflectionMethod|\Roave\BetterReflection\Reflection\ReflectionFunction|\Roave\BetterReflection\Reflection\ReflectionEnum|\Roave\BetterReflection\Reflection\ReflectionProperty|\Roave\BetterReflection\Reflection\ReflectionClassConstant $owner + * @param \PhpParser\Node\Identifier|\PhpParser\Node\Name $type */ + public function __construct(Reflector $reflector, $owner, $type) + { + $this->reflector = $reflector; + $this->owner = $owner; + $this->type = $type; $this->name = $type->toString(); } - /** @internal */ - public function withOwner(ReflectionParameter|ReflectionMethod|ReflectionFunction|ReflectionEnum|ReflectionProperty|ReflectionClassConstant $owner): static + /** @internal + * @param \Roave\BetterReflection\Reflection\ReflectionParameter|\Roave\BetterReflection\Reflection\ReflectionMethod|\Roave\BetterReflection\Reflection\ReflectionFunction|\Roave\BetterReflection\Reflection\ReflectionEnum|\Roave\BetterReflection\Reflection\ReflectionProperty|\Roave\BetterReflection\Reflection\ReflectionClassConstant $owner + * @return static */ + public function withOwner($owner) { $clone = clone $this; $clone->owner = $owner; @@ -118,11 +131,14 @@ public function getClass(): ReflectionClass public function allowsNull(): bool { - return match (strtolower($this->name)) { - 'mixed' => true, - 'null' => true, - default => false, - }; + switch (strtolower($this->name)) { + case 'mixed': + return true; + case 'null': + return true; + default: + return false; + } } public function isIdentifier(): bool diff --git a/src/Reflection/ReflectionObject.php b/src/Reflection/ReflectionObject.php index 9e5168e49..6f33e33aa 100644 --- a/src/Reflection/ReflectionObject.php +++ b/src/Reflection/ReflectionObject.php @@ -27,8 +27,14 @@ /** @psalm-immutable */ class ReflectionObject extends ReflectionClass { - protected function __construct(private Reflector $reflector, private ReflectionClass $reflectionClass, private object $object) + private Reflector $reflector; + private ReflectionClass $reflectionClass; + private object $object; + protected function __construct(Reflector $reflector, ReflectionClass $reflectionClass, object $object) { + $this->reflector = $reflector; + $this->reflectionClass = $reflectionClass; + $this->object = $object; } /** @@ -39,7 +45,7 @@ protected function __construct(private Reflector $reflector, private ReflectionC */ public static function createFromInstance(object $instance): ReflectionClass { - $className = $instance::class; + $className = get_class($instance); $betterReflection = new BetterReflection(); @@ -100,7 +106,8 @@ private function getRuntimeProperties(int $filter = 0): array $propertyNode->props[0], $this, $this, - declaredAtCompileTime: false, + false, + false, ); } @@ -132,7 +139,7 @@ public function getName(): string return $this->reflectionClass->getName(); } - public function getNamespaceName(): string|null + public function getNamespaceName(): ?string { return $this->reflectionClass->getNamespaceName(); } @@ -143,7 +150,7 @@ public function inNamespace(): bool } /** @return non-empty-string|null */ - public function getExtensionName(): string|null + public function getExtensionName(): ?string { return $this->reflectionClass->getExtensionName(); } @@ -165,7 +172,7 @@ public function getImmediateMethods(int $filter = 0): array } /** @param non-empty-string $methodName */ - public function getMethod(string $methodName): ReflectionMethod|null + public function getMethod(string $methodName): ?\Roave\BetterReflection\Reflection\ReflectionMethod { return $this->reflectionClass->getMethod($methodName); } @@ -197,12 +204,12 @@ public function hasConstant(string $name): bool return $this->reflectionClass->hasConstant($name); } - public function getConstant(string $name): ReflectionClassConstant|null + public function getConstant(string $name): ?\Roave\BetterReflection\Reflection\ReflectionClassConstant { return $this->reflectionClass->getConstant($name); } - public function getConstructor(): ReflectionMethod|null + public function getConstructor(): ?\Roave\BetterReflection\Reflection\ReflectionMethod { return $this->reflectionClass->getConstructor(); } @@ -229,7 +236,7 @@ public function getImmediateProperties(int $filter = 0): array ); } - public function getProperty(string $name): ReflectionProperty|null + public function getProperty(string $name): ?\Roave\BetterReflection\Reflection\ReflectionProperty { $runtimeProperties = $this->getRuntimeProperties(); @@ -259,7 +266,7 @@ public function getDefaultProperties(): array } /** @return non-empty-string|null */ - public function getFileName(): string|null + public function getFileName(): ?string { return $this->reflectionClass->getFileName(); } @@ -289,13 +296,13 @@ public function getEndColumn(): int return $this->reflectionClass->getEndColumn(); } - public function getParentClass(): ReflectionClass|null + public function getParentClass(): ?\Roave\BetterReflection\Reflection\ReflectionClass { return $this->reflectionClass->getParentClass(); } /** @return class-string|null */ - public function getParentClassName(): string|null + public function getParentClassName(): ?string { return $this->reflectionClass->getParentClassName(); } @@ -309,7 +316,7 @@ public function getParentClassNames(): array } /** @return non-empty-string|null */ - public function getDocComment(): string|null + public function getDocComment(): ?string { return $this->reflectionClass->getDocComment(); } @@ -471,12 +478,18 @@ public function getStaticProperties(): array return $this->reflectionClass->getStaticProperties(); } - public function setStaticPropertyValue(string $propertyName, mixed $value): void + /** + * @param mixed $value + */ + public function setStaticPropertyValue(string $propertyName, $value): void { $this->reflectionClass->setStaticPropertyValue($propertyName, $value); } - public function getStaticPropertyValue(string $propertyName): mixed + /** + * @return mixed + */ + public function getStaticPropertyValue(string $propertyName) { return $this->reflectionClass->getStaticPropertyValue($propertyName); } diff --git a/src/Reflection/ReflectionParameter.php b/src/Reflection/ReflectionParameter.php index 24b7f8e16..b814829a8 100644 --- a/src/Reflection/ReflectionParameter.php +++ b/src/Reflection/ReflectionParameter.php @@ -33,12 +33,25 @@ /** @psalm-immutable */ class ReflectionParameter { + private Reflector $reflector; + /** + * @var \Roave\BetterReflection\Reflection\ReflectionMethod|\Roave\BetterReflection\Reflection\ReflectionFunction + */ + private $function; + private int $parameterIndex; + private bool $isOptional; /** @var non-empty-string */ private string $name; - private Node\Expr|null $default; + /** + * @var \PhpParser\Node\Expr|null + */ + private $default; - private ReflectionNamedType|ReflectionUnionType|ReflectionIntersectionType|null $type; + /** + * @var \Roave\BetterReflection\Reflection\ReflectionNamedType|\Roave\BetterReflection\Reflection\ReflectionUnionType|\Roave\BetterReflection\Reflection\ReflectionIntersectionType|null + */ + private $type; private bool $isVariadic; @@ -50,33 +63,34 @@ class ReflectionParameter private array $attributes; /** @var positive-int|null */ - private int|null $startLine; + private $startLine; /** @var positive-int|null */ - private int|null $endLine; + private $endLine; /** @var positive-int|null */ - private int|null $startColumn; + private $startColumn; /** @var positive-int|null */ - private int|null $endColumn; - - /** @psalm-allow-private-mutation */ - private CompiledValue|null $compiledDefaultValue = null; - - private function __construct( - private Reflector $reflector, - ParamNode $node, - private ReflectionMethod|ReflectionFunction $function, - private int $parameterIndex, - private bool $isOptional, - ) { + private $endColumn; + + /** @psalm-allow-private-mutation + * @var \Roave\BetterReflection\NodeCompiler\CompiledValue|null */ + private $compiledDefaultValue = null; + + /** + * @param \Roave\BetterReflection\Reflection\ReflectionMethod|\Roave\BetterReflection\Reflection\ReflectionFunction $function + */ + private function __construct(Reflector $reflector, ParamNode $node, $function, int $parameterIndex, bool $isOptional) + { + $this->reflector = $reflector; + $this->function = $function; + $this->parameterIndex = $parameterIndex; + $this->isOptional = $isOptional; assert($node->var instanceof Node\Expr\Variable); assert(is_string($node->var->name)); - $name = $node->var->name; assert($name !== ''); - $this->name = $name; $this->default = $node->default; $this->isPromoted = $node->flags !== 0; @@ -84,31 +98,26 @@ private function __construct( $this->isVariadic = $node->variadic; $this->byRef = $node->byRef; $this->attributes = ReflectionAttributeHelper::createAttributes($reflector, $this, $node->attrGroups); - $startLine = $node->getStartLine(); if ($startLine === -1) { $startLine = null; } - $endLine = $node->getEndLine(); if ($endLine === -1) { $endLine = null; } - /** @psalm-suppress InvalidPropertyAssignmentValue */ $this->startLine = $startLine; /** @psalm-suppress InvalidPropertyAssignmentValue */ $this->endLine = $endLine; - try { $this->startColumn = CalculateReflectionColumn::getStartColumn($function->getLocatedSource()->getSource(), $node); - } catch (NoNodePosition) { + } catch (NoNodePosition $exception) { $this->startColumn = null; } - try { $this->endColumn = CalculateReflectionColumn::getEndColumn($function->getLocatedSource()->getSource(), $node); - } catch (NoNodePosition) { + } catch (NoNodePosition $exception) { $this->endColumn = null; } } @@ -121,19 +130,13 @@ private function __construct( * * @throws OutOfBoundsException */ - public static function createFromClassInstanceAndMethod( - object $instance, - string $methodName, - string $parameterName, - ): self { - $parameter = ReflectionClass::createFromInstance($instance) - ->getMethod($methodName) - ?->getParameter($parameterName); - + public static function createFromClassInstanceAndMethod(object $instance, string $methodName, string $parameterName): self + { + $parameter = ($nullsafeVariable1 = ReflectionClass::createFromInstance($instance) + ->getMethod($methodName)) ? $nullsafeVariable1->getParameter($parameterName) : null; if ($parameter === null) { throw new OutOfBoundsException(sprintf('Could not find parameter: %s', $parameterName)); } - return $parameter; } @@ -166,14 +169,10 @@ public function __toString(): string * @internal * * @param ParamNode $node Node has to be processed by the PhpParser\NodeVisitor\NameResolver + * @param \Roave\BetterReflection\Reflection\ReflectionMethod|\Roave\BetterReflection\Reflection\ReflectionFunction $function */ - public static function createFromNode( - Reflector $reflector, - ParamNode $node, - ReflectionMethod|ReflectionFunction $function, - int $parameterIndex, - bool $isOptional, - ): self { + public static function createFromNode(Reflector $reflector, ParamNode $node, $function, int $parameterIndex, bool $isOptional): self + { return new self( $reflector, $node, @@ -183,8 +182,9 @@ public static function createFromNode( ); } - /** @internal */ - public function withFunction(ReflectionMethod|ReflectionFunction $function): self + /** @internal + * @param \Roave\BetterReflection\Reflection\ReflectionMethod|\Roave\BetterReflection\Reflection\ReflectionFunction $function */ + public function withFunction($function): self { $clone = clone $this; $clone->function = $function; @@ -229,8 +229,9 @@ public function getName(): string /** * Get the function (or method) that declared this parameter. + * @return \Roave\BetterReflection\Reflection\ReflectionMethod|\Roave\BetterReflection\Reflection\ReflectionFunction */ - public function getDeclaringFunction(): ReflectionMethod|ReflectionFunction + public function getDeclaringFunction() { return $this->function; } @@ -241,7 +242,7 @@ public function getDeclaringFunction(): ReflectionMethod|ReflectionFunction * * This will return null if the declaring function is not a method. */ - public function getDeclaringClass(): ReflectionClass|null + public function getDeclaringClass(): ?\Roave\BetterReflection\Reflection\ReflectionClass { if ($this->function instanceof ReflectionMethod) { return $this->function->getDeclaringClass(); @@ -250,7 +251,7 @@ public function getDeclaringClass(): ReflectionClass|null return null; } - public function getImplementingClass(): ReflectionClass|null + public function getImplementingClass(): ?\Roave\BetterReflection\Reflection\ReflectionClass { if ($this->function instanceof ReflectionMethod) { return $this->function->getImplementingClass(); @@ -288,7 +289,7 @@ public function isDefaultValueAvailable(): bool return $this->default !== null; } - public function getDefaultValueExpression(): Node\Expr|null + public function getDefaultValueExpression(): ?\PhpParser\Node\Expr { return $this->default; } @@ -298,8 +299,9 @@ public function getDefaultValueExpression(): Node\Expr|null * * @throws LogicException * @throws UnableToCompileNode + * @return mixed */ - public function getDefaultValue(): mixed + public function getDefaultValue() { /** @psalm-var scalar|array|null $value */ $value = $this->getCompiledDefaultValue()->value; @@ -334,13 +336,17 @@ public function getPosition(): int * this parameter * * (note: this has nothing to do with DocBlocks). + * @return \Roave\BetterReflection\Reflection\ReflectionNamedType|\Roave\BetterReflection\Reflection\ReflectionUnionType|\Roave\BetterReflection\Reflection\ReflectionIntersectionType|null */ - public function getType(): ReflectionNamedType|ReflectionUnionType|ReflectionIntersectionType|null + public function getType() { return $this->type; } - private function createType(ParamNode $node): ReflectionNamedType|ReflectionUnionType|ReflectionIntersectionType|null + /** + * @return \Roave\BetterReflection\Reflection\ReflectionNamedType|\Roave\BetterReflection\Reflection\ReflectionUnionType|\Roave\BetterReflection\Reflection\ReflectionIntersectionType|null + */ + private function createType(ParamNode $node) { $type = $node->type; diff --git a/src/Reflection/ReflectionProperty.php b/src/Reflection/ReflectionProperty.php index 5ab5763ac..491b847d3 100644 --- a/src/Reflection/ReflectionProperty.php +++ b/src/Reflection/ReflectionProperty.php @@ -44,33 +44,44 @@ /** @psalm-immutable */ class ReflectionProperty { + private Reflector $reflector; + private ReflectionClass $declaringClass; + private ReflectionClass $implementingClass; + private bool $isPromoted; + private bool $declaredAtCompileTime; /** @var non-empty-string */ private string $name; /** @var int-mask-of */ private int $modifiers; - private ReflectionNamedType|ReflectionUnionType|ReflectionIntersectionType|null $type; + /** + * @var \Roave\BetterReflection\Reflection\ReflectionNamedType|\Roave\BetterReflection\Reflection\ReflectionUnionType|\Roave\BetterReflection\Reflection\ReflectionIntersectionType|null + */ + private $type; - private Node\Expr|null $default; + /** + * @var \PhpParser\Node\Expr|null + */ + private $default; /** @var non-empty-string|null */ - private string|null $docComment; + private $docComment; /** @var list */ private array $attributes; /** @var positive-int|null */ - private int|null $startLine; + private $startLine; /** @var positive-int|null */ - private int|null $endLine; + private $endLine; /** @var positive-int|null */ - private int|null $startColumn; + private $startColumn; /** @var positive-int|null */ - private int|null $endColumn; + private $endColumn; private bool $immediateVirtual; @@ -81,23 +92,23 @@ class ReflectionProperty * @var array{get?: ReflectionMethod, set?: ReflectionMethod}|null * @psalm-allow-private-mutation */ - private array|null $cachedHooks = null; - - /** @psalm-allow-private-mutation */ - private bool|null $cachedVirtual = null; - - /** @psalm-allow-private-mutation */ - private CompiledValue|null $compiledDefaultValue = null; - - private function __construct( - private Reflector $reflector, - PropertyNode $node, - Node\PropertyItem $propertyNode, - private ReflectionClass $declaringClass, - private ReflectionClass $implementingClass, - private bool $isPromoted, - private bool $declaredAtCompileTime, - ) { + private $cachedHooks = null; + + /** @psalm-allow-private-mutation + * @var bool|null */ + private $cachedVirtual = null; + + /** @psalm-allow-private-mutation + * @var \Roave\BetterReflection\NodeCompiler\CompiledValue|null */ + private $compiledDefaultValue = null; + + private function __construct(Reflector $reflector, PropertyNode $node, Node\PropertyItem $propertyNode, ReflectionClass $declaringClass, ReflectionClass $implementingClass, bool $isPromoted, bool $declaredAtCompileTime) + { + $this->reflector = $reflector; + $this->declaringClass = $declaringClass; + $this->implementingClass = $implementingClass; + $this->isPromoted = $isPromoted; + $this->declaredAtCompileTime = $declaredAtCompileTime; $this->name = $propertyNode->name->name; $this->modifiers = $this->computeModifiers($node); $this->type = $this->createType($node); @@ -106,31 +117,26 @@ private function __construct( $this->attributes = ReflectionAttributeHelper::createAttributes($reflector, $this, $node->attrGroups); $this->immediateVirtual = $this->computeImmediateVirtual($node); $this->immediateHooks = $this->createImmediateHooks($node); - $startLine = $node->getStartLine(); if ($startLine === -1) { $startLine = null; } - $endLine = $node->getEndLine(); if ($endLine === -1) { $endLine = null; } - /** @psalm-suppress InvalidPropertyAssignmentValue */ $this->startLine = $startLine; /** @psalm-suppress InvalidPropertyAssignmentValue */ $this->endLine = $endLine; - try { $this->startColumn = CalculateReflectionColumn::getStartColumn($declaringClass->getLocatedSource()->getSource(), $node); - } catch (NoNodePosition) { + } catch (NoNodePosition $exception) { $this->startColumn = null; } - try { $this->endColumn = CalculateReflectionColumn::getEndColumn($declaringClass->getLocatedSource()->getSource(), $node); - } catch (NoNodePosition) { + } catch (NoNodePosition $exception) { $this->endColumn = null; } } @@ -183,15 +189,8 @@ public function __toString(): string * * @param PropertyNode $node Node has to be processed by the PhpParser\NodeVisitor\NameResolver */ - public static function createFromNode( - Reflector $reflector, - PropertyNode $node, - Node\PropertyItem $propertyProperty, - ReflectionClass $declaringClass, - ReflectionClass $implementingClass, - bool $isPromoted = false, - bool $declaredAtCompileTime = true, - ): self { + public static function createFromNode(Reflector $reflector, PropertyNode $node, Node\PropertyItem $propertyProperty, ReflectionClass $declaringClass, ReflectionClass $implementingClass, bool $isPromoted = false, bool $declaredAtCompileTime = true): self + { return new self( $reflector, $node, @@ -301,7 +300,7 @@ public function isPromoted(): bool return $this->isPromoted; } - public function isInitialized(object|null $object = null): bool + public function isInitialized(?object $object = null): bool { if ($object === null && $this->isStatic()) { return ! $this->hasType() || $this->hasDefaultValue(); @@ -314,7 +313,7 @@ public function isInitialized(object|null $object = null): bool /** @phpstan-ignore catch.neverThrown */ } catch (Error $e) { - if (str_contains($e->getMessage(), 'must not be accessed before initialization')) { + if (strpos($e->getMessage(), 'must not be accessed before initialization') !== false) { return false; } @@ -339,7 +338,7 @@ public function getImplementingClass(): ReflectionClass } /** @return non-empty-string|null */ - public function getDocComment(): string|null + public function getDocComment(): ?string { return $this->docComment; } @@ -349,7 +348,7 @@ public function hasDefaultValue(): bool return ! $this->hasType() || $this->default !== null; } - public function getDefaultValueExpression(): Node\Expr|null + public function getDefaultValueExpression(): ?\PhpParser\Node\Expr { return $this->default; } @@ -357,8 +356,9 @@ public function getDefaultValueExpression(): Node\Expr|null /** * Get the default value of the property (as defined before constructor is * called, when the property is defined) + * @return mixed */ - public function getDefaultValue(): mixed + public function getDefaultValue() { if ($this->default === null) { return null; @@ -471,15 +471,16 @@ public function getAttributesByInstance(string $className): array * @throws ClassDoesNotExist * @throws NoObjectProvided * @throws ObjectNotInstanceOfClass + * @return mixed */ - public function getValue(object|null $object = null): mixed + public function getValue(?object $object = null) { $implementingClassName = $this->getImplementingClass()->getName(); if ($this->isStatic()) { $this->assertClassExist($implementingClassName); - $closure = Closure::bind(fn (string $implementingClassName, string $propertyName): mixed => $implementingClassName::${$propertyName}, null, $implementingClassName); + $closure = Closure::bind(fn (string $implementingClassName, string $propertyName) => $implementingClassName::${$propertyName}, null, $implementingClassName); /** @phpstan-ignore function.alreadyNarrowedType, instanceof.alwaysTrue */ assert($closure instanceof Closure); @@ -489,7 +490,7 @@ public function getValue(object|null $object = null): mixed $instance = $this->assertObject($object); - $closure = Closure::bind(fn (object $instance, string $propertyName): mixed => $instance->{$propertyName}, $instance, $implementingClassName); + $closure = Closure::bind(fn (object $instance, string $propertyName) => $instance->{$propertyName}, $instance, $implementingClassName); /** @phpstan-ignore function.alreadyNarrowedType, instanceof.alwaysTrue */ assert($closure instanceof Closure); @@ -502,15 +503,17 @@ public function getValue(object|null $object = null): mixed * @throws NoObjectProvided * @throws NotAnObject * @throws ObjectNotInstanceOfClass + * @param mixed $object + * @param mixed $value */ - public function setValue(mixed $object, mixed $value = null): void + public function setValue($object, $value = null): void { $implementingClassName = $this->getImplementingClass()->getName(); if ($this->isStatic()) { $this->assertClassExist($implementingClassName); - $closure = Closure::bind(function (string $_implementingClassName, string $_propertyName, mixed $value): void { + $closure = Closure::bind(function (string $_implementingClassName, string $_propertyName, $value): void { /** @psalm-suppress MixedAssignment */ $_implementingClassName::${$_propertyName} = $value; }, null, $implementingClassName); @@ -525,7 +528,7 @@ public function setValue(mixed $object, mixed $value = null): void $instance = $this->assertObject($object); - $closure = Closure::bind(function (object $instance, string $propertyName, mixed $value): void { + $closure = Closure::bind(function (object $instance, string $propertyName, $value): void { $instance->{$propertyName} = $value; }, $instance, $implementingClassName); @@ -543,7 +546,10 @@ public function allowsNull(): bool return $this->type === null || $this->type->allowsNull(); } - private function createType(PropertyNode $node): ReflectionNamedType|ReflectionUnionType|ReflectionIntersectionType|null + /** + * @return \Roave\BetterReflection\Reflection\ReflectionNamedType|\Roave\BetterReflection\Reflection\ReflectionUnionType|\Roave\BetterReflection\Reflection\ReflectionIntersectionType|null + */ + private function createType(PropertyNode $node) { $type = $node->type; @@ -561,8 +567,9 @@ private function createType(PropertyNode $node): ReflectionNamedType|ReflectionU * this property * * (note: this has nothing to do with DocBlocks). + * @return \Roave\BetterReflection\Reflection\ReflectionNamedType|\Roave\BetterReflection\Reflection\ReflectionUnionType|\Roave\BetterReflection\Reflection\ReflectionIntersectionType|null */ - public function getType(): ReflectionNamedType|ReflectionUnionType|ReflectionIntersectionType|null + public function getType() { return $this->type; } @@ -600,7 +607,7 @@ public function hasHook(string $hookType): bool /** * @param @param ReflectionPropertyHookType::* $hookType */ - public function getHook(string $hookType): ReflectionMethod|null + public function getHook(string $hookType): ?\Roave\BetterReflection\Reflection\ReflectionMethod { return $this->getHooks()[$hookType] ?? null; } @@ -631,8 +638,9 @@ private function assertClassExist(string $className): void * @throws ObjectNotInstanceOfClass * * @psalm-assert object $object + * @param mixed $object */ - private function assertObject(mixed $object): object + private function assertObject($object): object { if ($object === null) { throw NoObjectProvided::create(); @@ -644,7 +652,7 @@ private function assertObject(mixed $object): object $implementingClassName = $this->getImplementingClass()->getName(); - if ($object::class !== $implementingClassName) { + if (get_class($object) !== $implementingClassName) { throw ObjectNotInstanceOfClass::fromClassName($implementingClassName); } @@ -781,7 +789,7 @@ private function createCachedVirtual(): bool return false; } - return $this->getParentProperty()?->isVirtual() ?? true; + return (($nullsafeVariable1 = $this->getParentProperty()) ? $nullsafeVariable1->isVirtual() : null) ?? true; } /** @return array{get?: ReflectionMethod, set?: ReflectionMethod} */ @@ -794,7 +802,7 @@ private function createCachedHooks(): array return $hooks; } - $parentHooks = $this->getParentProperty()?->getHooks() ?? []; + $parentHooks = (($nullsafeVariable2 = $this->getParentProperty()) ? $nullsafeVariable2->getHooks() : null) ?? []; foreach ($parentHooks as $hookName => $parentHook) { if (isset($hooks[$hookName])) { @@ -807,8 +815,8 @@ private function createCachedHooks(): array return $hooks; } - private function getParentProperty(): ReflectionProperty|null + private function getParentProperty(): ?\Roave\BetterReflection\Reflection\ReflectionProperty { - return $this->getDeclaringClass()->getParentClass()?->getProperty($this->name); + return ($nullsafeVariable3 = $this->getDeclaringClass()->getParentClass()) ? $nullsafeVariable3->getProperty($this->name) : null; } } diff --git a/src/Reflection/ReflectionType.php b/src/Reflection/ReflectionType.php index 8a615523d..83ca81905 100644 --- a/src/Reflection/ReflectionType.php +++ b/src/Reflection/ReflectionType.php @@ -18,18 +18,16 @@ abstract class ReflectionType * @internal * * @psalm-pure + * @param \Roave\BetterReflection\Reflection\ReflectionParameter|\Roave\BetterReflection\Reflection\ReflectionMethod|\Roave\BetterReflection\Reflection\ReflectionFunction|\Roave\BetterReflection\Reflection\ReflectionEnum|\Roave\BetterReflection\Reflection\ReflectionProperty|\Roave\BetterReflection\Reflection\ReflectionClassConstant $owner + * @param \PhpParser\Node\Identifier|\PhpParser\Node\Name|\PhpParser\Node\NullableType|\PhpParser\Node\UnionType|\PhpParser\Node\IntersectionType $type + * @return \Roave\BetterReflection\Reflection\ReflectionNamedType|\Roave\BetterReflection\Reflection\ReflectionUnionType|\Roave\BetterReflection\Reflection\ReflectionIntersectionType */ - public static function createFromNode( - Reflector $reflector, - ReflectionParameter|ReflectionMethod|ReflectionFunction|ReflectionEnum|ReflectionProperty|ReflectionClassConstant $owner, - Identifier|Name|NullableType|UnionType|IntersectionType $type, - bool $allowsNull = false, - ): ReflectionNamedType|ReflectionUnionType|ReflectionIntersectionType { + public static function createFromNode(Reflector $reflector, $owner, $type, bool $allowsNull = false) + { if ($type instanceof NullableType) { $type = $type->type; $allowsNull = true; } - if ($type instanceof Identifier || $type instanceof Name) { if ( $type->toLowerString() === 'null' @@ -45,15 +43,12 @@ public static function createFromNode( new UnionType([$type, new Identifier('null')]), ); } - if ($type instanceof IntersectionType) { return new ReflectionIntersectionType($reflector, $owner, $type); } - if (! $allowsNull) { return new ReflectionUnionType($reflector, $owner, $type); } - foreach ($type->types as $innerUnionType) { if ( ($innerUnionType instanceof Identifier || $innerUnionType instanceof Name) @@ -62,10 +57,8 @@ public static function createFromNode( return new ReflectionUnionType($reflector, $owner, $type); } } - $types = $type->types; $types[] = new Identifier('null'); - return new ReflectionUnionType($reflector, $owner, new UnionType($types)); } diff --git a/src/Reflection/ReflectionUnionType.php b/src/Reflection/ReflectionUnionType.php index c830538bd..b28fa6a94 100644 --- a/src/Reflection/ReflectionUnionType.php +++ b/src/Reflection/ReflectionUnionType.php @@ -21,25 +21,24 @@ class ReflectionUnionType extends ReflectionType /** @var non-empty-list */ private array $types; - /** @internal */ - public function __construct( - Reflector $reflector, - ReflectionParameter|ReflectionMethod|ReflectionFunction|ReflectionEnum|ReflectionProperty|ReflectionClassConstant $owner, - UnionType $type, - ) { + /** @internal + * @param \Roave\BetterReflection\Reflection\ReflectionParameter|\Roave\BetterReflection\Reflection\ReflectionMethod|\Roave\BetterReflection\Reflection\ReflectionFunction|\Roave\BetterReflection\Reflection\ReflectionEnum|\Roave\BetterReflection\Reflection\ReflectionProperty|\Roave\BetterReflection\Reflection\ReflectionClassConstant $owner */ + public function __construct(Reflector $reflector, $owner, UnionType $type) + { /** @var non-empty-list $types */ - $types = array_map(static function (Identifier|Name|IntersectionType $type) use ($reflector, $owner): ReflectionNamedType|ReflectionIntersectionType { + $types = array_map(static function ($type) use ($reflector, $owner) { $type = ReflectionType::createFromNode($reflector, $owner, $type); assert($type instanceof ReflectionNamedType || $type instanceof ReflectionIntersectionType); return $type; }, $type->types); - $this->types = $types; } - /** @internal */ - public function withOwner(ReflectionParameter|ReflectionMethod|ReflectionFunction|ReflectionEnum|ReflectionProperty|ReflectionClassConstant $owner): static + /** @internal + * @param \Roave\BetterReflection\Reflection\ReflectionParameter|\Roave\BetterReflection\Reflection\ReflectionMethod|\Roave\BetterReflection\Reflection\ReflectionFunction|\Roave\BetterReflection\Reflection\ReflectionEnum|\Roave\BetterReflection\Reflection\ReflectionProperty|\Roave\BetterReflection\Reflection\ReflectionClassConstant $owner + * @return static */ + public function withOwner($owner) { $clone = clone $this; diff --git a/src/Reflection/StringCast/ReflectionAttributeStringCast.php b/src/Reflection/StringCast/ReflectionAttributeStringCast.php index 7aea7fb74..b28384f6a 100644 --- a/src/Reflection/StringCast/ReflectionAttributeStringCast.php +++ b/src/Reflection/StringCast/ReflectionAttributeStringCast.php @@ -61,8 +61,9 @@ private static function argumentsToString(array $arguments): string return $string; } - /** @psalm-pure */ - private static function argumentValueToString(mixed $value): string + /** @psalm-pure + * @param mixed $value */ + private static function argumentValueToString($value): string { if (is_array($value)) { return 'Array'; diff --git a/src/Reflection/StringCast/ReflectionClassStringCast.php b/src/Reflection/StringCast/ReflectionClassStringCast.php index 01b53184b..37fd97c01 100644 --- a/src/Reflection/StringCast/ReflectionClassStringCast.php +++ b/src/Reflection/StringCast/ReflectionClassStringCast.php @@ -160,8 +160,8 @@ private static function constantsToString(array $constants, array $enumCases): s return ''; } - $items = array_map(static fn (ReflectionEnumCase $enumCaseReflection): string => trim(ReflectionEnumCaseStringCast::toString($enumCaseReflection, indentDocComment: false)), $enumCases) - + array_map(static fn (ReflectionClassConstant $constantReflection): string => trim(ReflectionClassConstantStringCast::toString($constantReflection, indentDocComment: false)), $constants); + $items = array_map(static fn (ReflectionEnumCase $enumCaseReflection): string => trim(ReflectionEnumCaseStringCast::toString($enumCaseReflection, false)), $enumCases) + + array_map(static fn (ReflectionClassConstant $constantReflection): string => trim(ReflectionClassConstantStringCast::toString($constantReflection, false)), $constants); return self::itemsToString($items); } @@ -177,7 +177,7 @@ private static function propertiesToString(array $properties): string return ''; } - return self::itemsToString(array_map(static fn (ReflectionProperty $propertyReflection): string => ReflectionPropertyStringCast::toString($propertyReflection, indentDocComment: false), $properties)); + return self::itemsToString(array_map(static fn (ReflectionProperty $propertyReflection): string => ReflectionPropertyStringCast::toString($propertyReflection, false), $properties)); } /** diff --git a/src/Reflection/StringCast/ReflectionMethodStringCast.php b/src/Reflection/StringCast/ReflectionMethodStringCast.php index c30460338..1e60ddc83 100644 --- a/src/Reflection/StringCast/ReflectionMethodStringCast.php +++ b/src/Reflection/StringCast/ReflectionMethodStringCast.php @@ -96,7 +96,7 @@ private static function prototypeToString(ReflectionMethod $methodReflection): s { try { return sprintf(', prototype %s', $methodReflection->getPrototype()->getDeclaringClass()->getName()); - } catch (MethodPrototypeNotFound) { + } catch (MethodPrototypeNotFound $exception) { return ''; } } diff --git a/src/Reflection/StringCast/ReflectionStringCastHelper.php b/src/Reflection/StringCast/ReflectionStringCastHelper.php index e441d71d8..6fef8587a 100644 --- a/src/Reflection/StringCast/ReflectionStringCastHelper.php +++ b/src/Reflection/StringCast/ReflectionStringCastHelper.php @@ -13,8 +13,9 @@ /** @internal */ final class ReflectionStringCastHelper { - /** @psalm-pure */ - public static function docCommentToString(ReflectionProperty|ReflectionClassConstant|ReflectionEnumCase $reflection, bool $indent): string + /** @psalm-pure + * @param \Roave\BetterReflection\Reflection\ReflectionProperty|\Roave\BetterReflection\Reflection\ReflectionClassConstant|\Roave\BetterReflection\Reflection\ReflectionEnumCase $reflection */ + public static function docCommentToString($reflection, bool $indent): string { $docComment = $reflection->getDocComment(); diff --git a/src/Reflection/StringCast/ReflectionTypeStringCast.php b/src/Reflection/StringCast/ReflectionTypeStringCast.php index cf240b4a5..9b2f78cb8 100644 --- a/src/Reflection/StringCast/ReflectionTypeStringCast.php +++ b/src/Reflection/StringCast/ReflectionTypeStringCast.php @@ -20,10 +20,10 @@ final class ReflectionTypeStringCast * @return non-empty-string * * @psalm-pure + * @param \Roave\BetterReflection\Reflection\ReflectionNamedType|\Roave\BetterReflection\Reflection\ReflectionUnionType|\Roave\BetterReflection\Reflection\ReflectionIntersectionType $type */ - public static function toString( - ReflectionNamedType|ReflectionUnionType|ReflectionIntersectionType $type, - ): string { + public static function toString($type): string + { if ($type instanceof ReflectionUnionType) { // php-src has this weird behavior where a union type composed of a single type `T` // together with `null` means that a `ReflectionNamedType` for `?T` is produced, @@ -44,7 +44,6 @@ public static function toString( return '?' . $nonNullTypes[0]->__toString(); } } - return $type->__toString(); } } diff --git a/src/Reflection/Support/AlreadyVisitedClasses.php b/src/Reflection/Support/AlreadyVisitedClasses.php index 089eb795d..77301f23a 100644 --- a/src/Reflection/Support/AlreadyVisitedClasses.php +++ b/src/Reflection/Support/AlreadyVisitedClasses.php @@ -11,9 +11,14 @@ /** @internal */ final class AlreadyVisitedClasses { + /** + * @var array + */ + private array $classNames; /** @param array $classNames */ - private function __construct(private array $classNames) + private function __construct(array $classNames) { + $this->classNames = $classNames; } public static function createEmpty(): self diff --git a/src/Reflector/DefaultReflector.php b/src/Reflector/DefaultReflector.php index 8fb250047..0126e4f14 100644 --- a/src/Reflector/DefaultReflector.php +++ b/src/Reflector/DefaultReflector.php @@ -16,8 +16,10 @@ final class DefaultReflector implements Reflector { - public function __construct(private SourceLocator $sourceLocator) + private SourceLocator $sourceLocator; + public function __construct(SourceLocator $sourceLocator) { + $this->sourceLocator = $sourceLocator; } /** diff --git a/src/Reflector/Exception/IdentifierNotFound.php b/src/Reflector/Exception/IdentifierNotFound.php index 5492f5aa2..cb732adca 100644 --- a/src/Reflector/Exception/IdentifierNotFound.php +++ b/src/Reflector/Exception/IdentifierNotFound.php @@ -11,8 +11,10 @@ class IdentifierNotFound extends RuntimeException { - public function __construct(string $message, private Identifier $identifier) + private Identifier $identifier; + public function __construct(string $message, Identifier $identifier) { + $this->identifier = $identifier; parent::__construct($message); } diff --git a/src/SourceLocator/Ast/FindReflectionsInTree.php b/src/SourceLocator/Ast/FindReflectionsInTree.php index 145d0279d..a6f97b95b 100644 --- a/src/SourceLocator/Ast/FindReflectionsInTree.php +++ b/src/SourceLocator/Ast/FindReflectionsInTree.php @@ -27,8 +27,10 @@ /** @internal */ final class FindReflectionsInTree { - public function __construct(private AstConversionStrategy $astConversionStrategy) + private AstConversionStrategy $astConversionStrategy; + public function __construct(AstConversionStrategy $astConversionStrategy) { + $this->astConversionStrategy = $astConversionStrategy; } /** @@ -38,25 +40,28 @@ public function __construct(private AstConversionStrategy $astConversionStrategy * * @return list */ - public function __invoke( - Reflector $reflector, - array $ast, - IdentifierType $identifierType, - LocatedSource $locatedSource, - ): array { + public function __invoke(Reflector $reflector, array $ast, IdentifierType $identifierType, LocatedSource $locatedSource): array + { $nodeVisitor = new class ($reflector, $identifierType, $locatedSource, $this->astConversionStrategy) extends NodeVisitorAbstract { + private Reflector $reflector; + private IdentifierType $identifierType; + private LocatedSource $locatedSource; + private AstConversionStrategy $astConversionStrategy; /** @var list */ private array $reflections = []; - private Namespace_|null $currentNamespace = null; + /** + * @var \PhpParser\Node\Stmt\Namespace_|null + */ + private $currentNamespace = null; - public function __construct( - private Reflector $reflector, - private IdentifierType $identifierType, - private LocatedSource $locatedSource, - private AstConversionStrategy $astConversionStrategy, - ) { + public function __construct(Reflector $reflector, IdentifierType $identifierType, LocatedSource $locatedSource, AstConversionStrategy $astConversionStrategy) + { + $this->reflector = $reflector; + $this->identifierType = $identifierType; + $this->locatedSource = $locatedSource; + $this->astConversionStrategy = $astConversionStrategy; } /** @@ -106,7 +111,7 @@ public function leaveNode(Node $node) try { ConstantNodeChecker::assertValidDefineFunctionCall($functionCall); - } catch (InvalidConstantNode) { + } catch (InvalidConstantNode $exception) { return null; } @@ -118,7 +123,7 @@ public function leaveNode(Node $node) $this->reflector->reflectFunction($namespacedName->toString()); return null; - } catch (IdentifierNotFound) { + } catch (IdentifierNotFound $exception) { // Global define() } } @@ -151,10 +156,8 @@ public function getReflections(): array return $this->reflections; } }; - $nodeTraverser = new NodeTraverser(new NameResolver(), $nodeVisitor); $nodeTraverser->traverse($ast); - return $nodeVisitor->getReflections(); } } diff --git a/src/SourceLocator/Ast/Locator.php b/src/SourceLocator/Ast/Locator.php index 0a19004be..648564e36 100644 --- a/src/SourceLocator/Ast/Locator.php +++ b/src/SourceLocator/Ast/Locator.php @@ -20,10 +20,12 @@ /** @internal */ class Locator { + private Parser $parser; private FindReflectionsInTree $findReflectionsInTree; - public function __construct(private Parser $parser) + public function __construct(Parser $parser) { + $this->parser = $parser; $this->findReflectionsInTree = new FindReflectionsInTree(new NodeToReflection()); } @@ -31,11 +33,8 @@ public function __construct(private Parser $parser) * @throws IdentifierNotFound * @throws Exception\ParseToAstFailure */ - public function findReflection( - Reflector $reflector, - LocatedSource $locatedSource, - Identifier $identifier, - ): Reflection { + public function findReflection(Reflector $reflector, LocatedSource $locatedSource, Identifier $identifier): Reflection + { return $this->findInArray( $this->findReflectionsOfType( $reflector, @@ -54,11 +53,8 @@ public function findReflection( * * @throws Exception\ParseToAstFailure */ - public function findReflectionsOfType( - Reflector $reflector, - LocatedSource $locatedSource, - IdentifierType $identifierType, - ): array { + public function findReflectionsOfType(Reflector $reflector, LocatedSource $locatedSource, IdentifierType $identifierType): array + { try { /** @var list $ast */ $ast = $this->parser->parse($locatedSource->getSource()); @@ -81,7 +77,7 @@ public function findReflectionsOfType( * * @throws IdentifierNotFound */ - private function findInArray(array $reflections, Identifier $identifier, string|null $name): Reflection + private function findInArray(array $reflections, Identifier $identifier, ?string $name): Reflection { if ($name === null) { throw IdentifierNotFound::fromIdentifier($identifier); diff --git a/src/SourceLocator/Ast/Parser/MemoizingParser.php b/src/SourceLocator/Ast/Parser/MemoizingParser.php index 1c75056d8..cd34a81b7 100644 --- a/src/SourceLocator/Ast/Parser/MemoizingParser.php +++ b/src/SourceLocator/Ast/Parser/MemoizingParser.php @@ -19,17 +19,19 @@ /** @internal */ final class MemoizingParser implements Parser { + private Parser $wrappedParser; /** @var array indexed by source hash */ private array $sourceHashToAst = []; /** @var Token[] */ private array $lastTokens = []; - public function __construct(private Parser $wrappedParser) + public function __construct(Parser $wrappedParser) { + $this->wrappedParser = $wrappedParser; } - public function parse(string $code, ErrorHandler|null $errorHandler = null): array|null + public function parse(string $code, ?\PhpParser\ErrorHandler $errorHandler = null): ?array { // note: this code is mathematically buggy by default, as we are using a hash to identify // cache entries. The string length is added to further reduce likeliness (although diff --git a/src/SourceLocator/Ast/Strategy/AstConversionStrategy.php b/src/SourceLocator/Ast/Strategy/AstConversionStrategy.php index db22e2335..48c5555ad 100644 --- a/src/SourceLocator/Ast/Strategy/AstConversionStrategy.php +++ b/src/SourceLocator/Ast/Strategy/AstConversionStrategy.php @@ -17,12 +17,8 @@ interface AstConversionStrategy /** * Take an AST node in some located source (potentially in a namespace) and * convert it to something (concrete implementation decides) + * @param \PhpParser\Node\Stmt\Class_|\PhpParser\Node\Stmt\Interface_|\PhpParser\Node\Stmt\Trait_|\PhpParser\Node\Stmt\Enum_|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\Closure|\PhpParser\Node\Expr\ArrowFunction|\PhpParser\Node\Stmt\Const_|\PhpParser\Node\Expr\FuncCall $node + * @return \Roave\BetterReflection\Reflection\ReflectionClass|\Roave\BetterReflection\Reflection\ReflectionConstant|\Roave\BetterReflection\Reflection\ReflectionFunction */ - public function __invoke( - Reflector $reflector, - Node\Stmt\Class_|Node\Stmt\Interface_|Node\Stmt\Trait_|Node\Stmt\Enum_|Node\Stmt\Function_|Node\Expr\Closure|Node\Expr\ArrowFunction|Node\Stmt\Const_|Node\Expr\FuncCall $node, - LocatedSource $locatedSource, - Node\Stmt\Namespace_|null $namespace, - int|null $positionInNode = null, - ): ReflectionClass|ReflectionConstant|ReflectionFunction; + public function __invoke(Reflector $reflector, $node, LocatedSource $locatedSource, ?\PhpParser\Node\Stmt\Namespace_ $namespace, ?int $positionInNode = null); } diff --git a/src/SourceLocator/Ast/Strategy/NodeToReflection.php b/src/SourceLocator/Ast/Strategy/NodeToReflection.php index 48bea5f3b..b283a4284 100644 --- a/src/SourceLocator/Ast/Strategy/NodeToReflection.php +++ b/src/SourceLocator/Ast/Strategy/NodeToReflection.php @@ -18,16 +18,12 @@ class NodeToReflection implements AstConversionStrategy /** * Take an AST node in some located source (potentially in a namespace) and * convert it to a Reflection + * @param \PhpParser\Node\Stmt\Class_|\PhpParser\Node\Stmt\Interface_|\PhpParser\Node\Stmt\Trait_|\PhpParser\Node\Stmt\Enum_|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\Closure|\PhpParser\Node\Expr\ArrowFunction|\PhpParser\Node\Stmt\Const_|\PhpParser\Node\Expr\FuncCall $node + * @return \Roave\BetterReflection\Reflection\ReflectionClass|\Roave\BetterReflection\Reflection\ReflectionConstant|\Roave\BetterReflection\Reflection\ReflectionFunction */ - public function __invoke( - Reflector $reflector, - Node\Stmt\Class_|Node\Stmt\Interface_|Node\Stmt\Trait_|Node\Stmt\Enum_|Node\Stmt\Function_|Node\Expr\Closure|Node\Expr\ArrowFunction|Node\Stmt\Const_|Node\Expr\FuncCall $node, - LocatedSource $locatedSource, - Node\Stmt\Namespace_|null $namespace, - int|null $positionInNode = null, - ): ReflectionClass|ReflectionConstant|ReflectionFunction { - $namespaceName = $namespace?->name?->name; - + public function __invoke(Reflector $reflector, $node, LocatedSource $locatedSource, ?\PhpParser\Node\Stmt\Namespace_ $namespace, ?int $positionInNode = null) + { + $namespaceName = ($nullsafeVariable1 = ($nullsafeVariable2 = $namespace) ? $nullsafeVariable2->name : null) ? $nullsafeVariable1->name : null; if ($node instanceof Node\Stmt\Enum_) { return ReflectionEnum::createFromNode( $reflector, @@ -36,7 +32,6 @@ public function __invoke( $namespaceName, ); } - if ($node instanceof Node\Stmt\ClassLike) { return ReflectionClass::createFromNode( $reflector, @@ -45,15 +40,12 @@ public function __invoke( $namespaceName, ); } - if ($node instanceof Node\Stmt\Const_) { return ReflectionConstant::createFromNode($reflector, $node, $locatedSource, $namespaceName, $positionInNode); } - if ($node instanceof Node\Expr\FuncCall) { return ReflectionConstant::createFromNode($reflector, $node, $locatedSource); } - return ReflectionFunction::createFromNode( $reflector, $node, diff --git a/src/SourceLocator/Exception/InvalidFileInfo.php b/src/SourceLocator/Exception/InvalidFileInfo.php index 34dde197b..5bc1c5439 100644 --- a/src/SourceLocator/Exception/InvalidFileInfo.php +++ b/src/SourceLocator/Exception/InvalidFileInfo.php @@ -12,11 +12,14 @@ class InvalidFileInfo extends RuntimeException { - public static function fromNonSplFileInfo(mixed $nonSplFileInfo): self + /** + * @param mixed $nonSplFileInfo + */ + public static function fromNonSplFileInfo($nonSplFileInfo): self { return new self(sprintf( 'Expected an iterator of SplFileInfo instances, %s given instead', - is_object($nonSplFileInfo) ? $nonSplFileInfo::class : gettype($nonSplFileInfo), + is_object($nonSplFileInfo) ? get_class($nonSplFileInfo) : gettype($nonSplFileInfo), )); } } diff --git a/src/SourceLocator/Located/AliasLocatedSource.php b/src/SourceLocator/Located/AliasLocatedSource.php index d2dee459e..ef4f64220 100644 --- a/src/SourceLocator/Located/AliasLocatedSource.php +++ b/src/SourceLocator/Located/AliasLocatedSource.php @@ -11,12 +11,14 @@ */ class AliasLocatedSource extends LocatedSource { - public function __construct(string $source, string $name, string|null $filename, private string $aliasName) + private string $aliasName; + public function __construct(string $source, string $name, ?string $filename, string $aliasName) { + $this->aliasName = $aliasName; parent::__construct($source, $name, $filename); } - public function getAliasName(): string|null + public function getAliasName(): ?string { return $this->aliasName; } diff --git a/src/SourceLocator/Located/InternalLocatedSource.php b/src/SourceLocator/Located/InternalLocatedSource.php index c3bf7607b..62339f129 100644 --- a/src/SourceLocator/Located/InternalLocatedSource.php +++ b/src/SourceLocator/Located/InternalLocatedSource.php @@ -11,9 +11,16 @@ */ class InternalLocatedSource extends LocatedSource { + /** + * @var non-empty-string + */ + private string $extensionName; + private ?string $aliasName = null; /** @param non-empty-string $extensionName */ - public function __construct(string $source, string $name, private string $extensionName, ?string $fileName = null, private ?string $aliasName = null) + public function __construct(string $source, string $name, string $extensionName, ?string $fileName = null, ?string $aliasName = null) { + $this->extensionName = $extensionName; + $this->aliasName = $aliasName; parent::__construct($source, $name, $fileName); } @@ -23,12 +30,12 @@ public function isInternal(): bool } /** @return non-empty-string|null */ - public function getExtensionName(): string|null + public function getExtensionName(): ?string { return $this->extensionName; } - public function getAliasName(): string|null + public function getAliasName(): ?string { return $this->aliasName; } diff --git a/src/SourceLocator/Located/LocatedSource.php b/src/SourceLocator/Located/LocatedSource.php index c49110f47..20df9fbd4 100644 --- a/src/SourceLocator/Located/LocatedSource.php +++ b/src/SourceLocator/Located/LocatedSource.php @@ -19,15 +19,22 @@ */ class LocatedSource { + private string $source; + /** + * @var string|null + */ + private $name; /** @var non-empty-string|null */ - private string|null $filename; + private $filename; /** * @throws InvalidArgumentException * @throws InvalidFileLocation */ - public function __construct(private string $source, private string|null $name, string|null $filename = null) + public function __construct(string $source, ?string $name, ?string $filename = null) { + $this->source = $source; + $this->name = $name; if ($filename !== null) { assert($filename !== ''); @@ -42,13 +49,13 @@ public function getSource(): string return $this->source; } - public function getName(): string|null + public function getName(): ?string { return $this->name; } /** @return non-empty-string|null */ - public function getFileName(): string|null + public function getFileName(): ?string { return $this->filename; } @@ -62,7 +69,7 @@ public function isInternal(): bool } /** @return non-empty-string|null */ - public function getExtensionName(): string|null + public function getExtensionName(): ?string { return null; } @@ -75,7 +82,7 @@ public function isEvaled(): bool return false; } - public function getAliasName(): string|null + public function getAliasName(): ?string { return null; } diff --git a/src/SourceLocator/SourceStubber/AggregateSourceStubber.php b/src/SourceLocator/SourceStubber/AggregateSourceStubber.php index 9e65e2ce6..ee53a8a12 100644 --- a/src/SourceLocator/SourceStubber/AggregateSourceStubber.php +++ b/src/SourceLocator/SourceStubber/AggregateSourceStubber.php @@ -19,7 +19,7 @@ public function __construct(SourceStubber $sourceStubber, SourceStubber ...$othe } /** @param class-string|trait-string $className */ - public function generateClassStub(string $className): StubData|null + public function generateClassStub(string $className): ?\Roave\BetterReflection\SourceLocator\SourceStubber\StubData { foreach ($this->sourceStubbers as $sourceStubber) { $stubData = $sourceStubber->generateClassStub($className); @@ -32,7 +32,7 @@ public function generateClassStub(string $className): StubData|null return null; } - public function generateFunctionStub(string $functionName): StubData|null + public function generateFunctionStub(string $functionName): ?\Roave\BetterReflection\SourceLocator\SourceStubber\StubData { foreach ($this->sourceStubbers as $sourceStubber) { $stubData = $sourceStubber->generateFunctionStub($functionName); @@ -45,8 +45,8 @@ public function generateFunctionStub(string $functionName): StubData|null return null; } - public function generateConstantStub(string $constantName): StubData|null + public function generateConstantStub(string $constantName): ?\Roave\BetterReflection\SourceLocator\SourceStubber\StubData { - return array_reduce($this->sourceStubbers, static fn (StubData|null $stubData, SourceStubber $sourceStubber): StubData|null => $stubData ?? $sourceStubber->generateConstantStub($constantName), null); + return array_reduce($this->sourceStubbers, static fn (?\Roave\BetterReflection\SourceLocator\SourceStubber\StubData $stubData, SourceStubber $sourceStubber): ?\Roave\BetterReflection\SourceLocator\SourceStubber\StubData => $stubData ?? $sourceStubber->generateConstantStub($constantName), null); } } diff --git a/src/SourceLocator/SourceStubber/PhpStormStubs/CachingVisitor.php b/src/SourceLocator/SourceStubber/PhpStormStubs/CachingVisitor.php index 3f5888ed2..db6dc2a16 100644 --- a/src/SourceLocator/SourceStubber/PhpStormStubs/CachingVisitor.php +++ b/src/SourceLocator/SourceStubber/PhpStormStubs/CachingVisitor.php @@ -27,9 +27,13 @@ /** @internal */ class CachingVisitor extends NodeVisitorAbstract { + private BuilderFactory $builderFactory; private const TRUE_FALSE_NULL = ['true', 'false', 'null']; - private Node\Stmt\Namespace_|null $currentNamespace = null; + /** + * @var \PhpParser\Node\Stmt\Namespace_|null + */ + private $currentNamespace = null; /** @var array */ private array $classNodes = []; @@ -40,11 +44,12 @@ class CachingVisitor extends NodeVisitorAbstract /** @var array */ private array $constantNodes = []; - public function __construct(private BuilderFactory $builderFactory) + public function __construct(BuilderFactory $builderFactory) { + $this->builderFactory = $builderFactory; } - public function enterNode(Node $node): int|null + public function enterNode(Node $node): ?int { if ($node instanceof Node\Stmt\Namespace_) { $this->currentNamespace = $node; @@ -121,7 +126,7 @@ public function enterNode(Node $node): int|null // No invalid definition in PhpStorm stubs try { ConstantNodeChecker::assertValidDefineFunctionCall($node->expr); - } catch (InvalidConstantNode) { + } catch (InvalidConstantNode $exception) { return null; } @@ -195,8 +200,9 @@ public function clearNodes(): void /** * Some constants have different values on different systems, some are not actual in stubs. + * @param \PhpParser\Node\Expr\FuncCall|\PhpParser\Node\Const_ $node */ - private function updateConstantValue(Node\Expr\FuncCall|Node\Const_ $node, string $constantName): void + private function updateConstantValue($node, string $constantName): void { // prevent autoloading while discovering class constants $parts = explode('::', $constantName, 2); diff --git a/src/SourceLocator/SourceStubber/PhpStormStubsSourceStubber.php b/src/SourceLocator/SourceStubber/PhpStormStubsSourceStubber.php index e83a2cab0..b26872bd3 100644 --- a/src/SourceLocator/SourceStubber/PhpStormStubsSourceStubber.php +++ b/src/SourceLocator/SourceStubber/PhpStormStubsSourceStubber.php @@ -56,6 +56,8 @@ /** @internal */ final class PhpStormStubsSourceStubber implements SourceStubber { + private Parser $phpParser; + private int $phpVersion = PHP_VERSION_ID; private const SEARCH_DIRECTORIES = [ __DIR__ . '/../../../../../jetbrains/phpstorm-stubs', __DIR__ . '/../../../vendor/jetbrains/phpstorm-stubs', @@ -146,7 +148,10 @@ final class PhpStormStubsSourceStubber implements SourceStubber private NodeTraverser $nodeTraverser; - private string|null $stubsDirectory = null; + /** + * @var string|null + */ + private $stubsDirectory = null; private CachingVisitor $cachingVisitor; @@ -182,8 +187,10 @@ final class PhpStormStubsSourceStubber implements SourceStubber /** @var array */ private static array $constantMap; - public function __construct(private Parser $phpParser, Standard $prettyPrinter, private int $phpVersion = PHP_VERSION_ID) + public function __construct(Parser $phpParser, Standard $prettyPrinter, int $phpVersion = PHP_VERSION_ID) { + $this->phpParser = $phpParser; + $this->phpVersion = $phpVersion; $this->builderFactory = new BuilderFactory(); $this->prettyPrinter = $prettyPrinter; @@ -237,7 +244,7 @@ public function isPresentFunction(string $functionName): ?bool } /** @param class-string|trait-string $className */ - public function generateClassStub(string $className): StubData|null + public function generateClassStub(string $className): ?\Roave\BetterReflection\SourceLocator\SourceStubber\StubData { if (strtolower($className) === 'iterable') { return null; @@ -277,7 +284,7 @@ public function generateClassStub(string $className): StubData|null } /** @return array{0: Node\Stmt\ClassLike, 1: Node\Stmt\Namespace_|null}|null */ - private function getClassNodeData(string $className): array|null + private function getClassNodeData(string $className) { $lowercaseClassName = strtolower($className); @@ -326,7 +333,7 @@ private function getFunctionNodeData(string $functionName): ?array return $this->functionNodes[$lowercaseFunctionName]; } - public function generateFunctionStub(string $functionName): StubData|null + public function generateFunctionStub(string $functionName): ?\Roave\BetterReflection\SourceLocator\SourceStubber\StubData { $functionNodeData = $this->getFunctionNodeData($functionName); @@ -340,7 +347,7 @@ public function generateFunctionStub(string $functionName): StubData|null return new StubData($this->createStub($functionNodeData[0], $functionNodeData[1]), $extension, $this->getAbsoluteFilePath($filePath)); } - public function generateConstantStub(string $constantName): StubData|null + public function generateConstantStub(string $constantName): ?\Roave\BetterReflection\SourceLocator\SourceStubber\StubData { $lowercaseConstantName = strtolower($constantName); @@ -448,13 +455,16 @@ private function parseFile(string $filePath): void } } - private function createStub(Node\Stmt\ClassLike|Node\Stmt\Function_|Node\Stmt\Const_|Node\Expr\FuncCall $node, Node\Stmt\Namespace_|null $namespaceNode): string + /** + * @param \PhpParser\Node\Stmt\ClassLike|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Stmt\Const_|\PhpParser\Node\Expr\FuncCall $node + */ + private function createStub($node, ?\PhpParser\Node\Stmt\Namespace_ $namespaceNode): string { if ($node instanceof Node\Expr\FuncCall) { try { ConstantNodeChecker::assertValidDefineFunctionCall($node); $this->addDeprecatedDocComment($node); - } catch (InvalidConstantNode) { + } catch (InvalidConstantNode $exception) { // just keep going } } @@ -593,7 +603,10 @@ private function modifyStmtsByPhpVersion(array $stmts): array return $newStmts; } - private function modifyStmtTypeByPhpVersion(Node\Stmt\Property|Node\Param $stmt): void + /** + * @param \PhpParser\Node\Stmt\Property|\PhpParser\Node\Param $stmt + */ + private function modifyStmtTypeByPhpVersion($stmt): void { $type = $this->getStmtType($stmt); @@ -604,7 +617,10 @@ private function modifyStmtTypeByPhpVersion(Node\Stmt\Property|Node\Param $stmt) $stmt->type = $type; } - private function modifyFunctionReturnTypeByPhpVersion(Node\Stmt\ClassMethod|Node\Stmt\Function_ $function): void + /** + * @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_ $function + */ + private function modifyFunctionReturnTypeByPhpVersion($function): void { $isTentativeReturnType = $this->getNodeAttribute($function, 'JetBrains\PhpStorm\Internal\TentativeType') !== null; @@ -630,7 +646,10 @@ private function modifyFunctionReturnTypeByPhpVersion(Node\Stmt\ClassMethod|Node $function->returnType = $type; } - private function modifyFunctionParametersByPhpVersion(Node\Stmt\ClassMethod|Node\Stmt\Function_ $function): void + /** + * @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_ $function + */ + private function modifyFunctionParametersByPhpVersion($function): void { $parameters = []; @@ -647,7 +666,11 @@ private function modifyFunctionParametersByPhpVersion(Node\Stmt\ClassMethod|Node $function->params = $parameters; } - private function getStmtType(Node\Stmt\Function_|Node\Stmt\ClassMethod|Node\Stmt\Property|Node\Param $node): Node\Name|Node\Identifier|Node\ComplexType|null + /** + * @param \PhpParser\Node\Stmt\Function_|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Param $node + * @return \PhpParser\Node\Name|\PhpParser\Node\Identifier|\PhpParser\Node\ComplexType|null + */ + private function getStmtType($node) { $languageLevelTypeAwareAttribute = $this->getNodeAttribute($node, 'JetBrains\PhpStorm\Internal\LanguageLevelTypeAware'); @@ -680,7 +703,10 @@ private function getStmtType(Node\Stmt\Function_|Node\Stmt\ClassMethod|Node\Stmt : null; } - private function addDeprecatedDocComment(Node\Stmt\ClassLike|Node\Stmt\ClassConst|Node\Stmt\Property|Node\Stmt\ClassMethod|Node\Stmt\Function_|Node\Expr\FuncCall|Node\Stmt\Const_|Node\Stmt\EnumCase $node): void + /** + * @param \PhpParser\Node\Stmt\ClassLike|\PhpParser\Node\Stmt\ClassConst|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\FuncCall|\PhpParser\Node\Stmt\Const_|\PhpParser\Node\Stmt\EnumCase $node + */ + private function addDeprecatedDocComment($node): void { if ($node instanceof Node\Expr\FuncCall) { if (! $this->isDeprecatedByPhpDocInPhpVersion($node)) { @@ -703,30 +729,29 @@ private function addDeprecatedDocComment(Node\Stmt\ClassLike|Node\Stmt\ClassCons $this->addAnnotationToDocComment($node, 'deprecated'); } - private function addAnnotationToDocComment( - Node\Stmt\ClassLike|Node\Stmt\ClassConst|Node\Stmt\Property|Node\Stmt\ClassMethod|Node\Stmt\Function_|Node\Stmt\Const_|Node\Stmt\EnumCase $node, - string $annotationName, - ): void { + /** + * @param \PhpParser\Node\Stmt\ClassLike|\PhpParser\Node\Stmt\ClassConst|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Stmt\Const_|\PhpParser\Node\Stmt\EnumCase $node + */ + private function addAnnotationToDocComment($node, string $annotationName): void + { $docComment = $node->getDocComment(); - if ($docComment === null) { $docCommentText = sprintf('/** @%s */', $annotationName); } else { $docCommentText = preg_replace('~(\r?\n\s*)\*/~', sprintf('\1* @%s\1*/', $annotationName), $docComment->getText()); } - $node->setDocComment(new Doc($docCommentText)); } - private function removeAnnotationFromDocComment( - Node\Stmt\ClassLike|Node\Stmt\ClassConst|Node\Stmt\Property|Node\Stmt\ClassMethod|Node\Stmt\Function_|Node\Expr\FuncCall|Node\Stmt\Const_|Node\Stmt\EnumCase $node, - string $annotationName, - ): void { + /** + * @param \PhpParser\Node\Stmt\ClassLike|\PhpParser\Node\Stmt\ClassConst|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\FuncCall|\PhpParser\Node\Stmt\Const_|\PhpParser\Node\Stmt\EnumCase $node + */ + private function removeAnnotationFromDocComment($node, string $annotationName): void + { $docComment = $node->getDocComment(); if ($docComment === null) { return; } - $docCommentText = preg_replace('~@' . $annotationName . '.*$~m', '', $docComment->getText()); $node->setDocComment(new Doc($docCommentText)); } @@ -755,7 +780,10 @@ private function isDeprecatedByPhpDocInPhpVersion(Node\Expr\FuncCall $node): boo return true; } - private function isDeprecatedInPhpVersion(Node\Stmt\ClassLike|Node\Stmt\ClassConst|Node\Stmt\Property|Node\Stmt\ClassMethod|Node\Stmt\Function_|Node\Stmt\EnumCase $node): bool + /** + * @param \PhpParser\Node\Stmt\ClassLike|\PhpParser\Node\Stmt\ClassConst|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Stmt\EnumCase $node + */ + private function isDeprecatedInPhpVersion($node): bool { $deprecatedAttribute = $this->getNodeAttribute($node, 'JetBrains\PhpStorm\Deprecated'); if ($deprecatedAttribute === null) { @@ -773,25 +801,24 @@ private function isDeprecatedInPhpVersion(Node\Stmt\ClassLike|Node\Stmt\ClassCon return true; } - private function isSupportedInPhpVersion( - Node\Stmt\ClassLike|Node\Stmt\Function_|Node\Stmt\Const_|Node\Expr\FuncCall|Node\Stmt\ClassConst|Node\Stmt\Property|Node\Stmt\ClassMethod|Node\Param|Node\Stmt\EnumCase $node, - ): bool { + /** + * @param \PhpParser\Node\Stmt\ClassLike|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Stmt\Const_|\PhpParser\Node\Expr\FuncCall|\PhpParser\Node\Stmt\ClassConst|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Param|\PhpParser\Node\Stmt\EnumCase $node + */ + private function isSupportedInPhpVersion($node): bool + { [$fromVersion, $toVersion] = $this->getSupportedPhpVersions($node); - if ($fromVersion !== null && $fromVersion > $this->phpVersion) { return false; } - return $toVersion === null || $toVersion >= $this->phpVersion; } - /** @return array{0: int|null, 1: int|null} */ - private function getSupportedPhpVersions( - Node\Stmt\ClassLike|Node\Stmt\Function_|Node\Stmt\Const_|Node\Expr\FuncCall|Node\Stmt\ClassConst|Node\Stmt\Property|Node\Stmt\ClassMethod|Node\Param|Node\Stmt\EnumCase $node, - ): array { + /** @return array{0: int|null, 1: int|null} + * @param \PhpParser\Node\Stmt\ClassLike|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Stmt\Const_|\PhpParser\Node\Expr\FuncCall|\PhpParser\Node\Stmt\ClassConst|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Param|\PhpParser\Node\Stmt\EnumCase $node */ + private function getSupportedPhpVersions($node): array + { $fromVersion = null; $toVersion = null; - $docComment = $node->getDocComment(); if ($docComment !== null) { if (preg_match('~@since\s+(?P\d+\.\d+(?:\.\d+)?)\s+~', $docComment->getText(), $sinceMatches) === 1) { @@ -802,7 +829,6 @@ private function getSupportedPhpVersions( $toVersion = $this->parsePhpVersion($removedMatches['version']) - 1; } } - $elementsAvailable = $this->getNodeAttribute($node, 'JetBrains\PhpStorm\Internal\PhpStormStubsElementAvailable'); if ($elementsAvailable !== null) { foreach ($elementsAvailable->args as $i => $attributeArg) { @@ -839,18 +865,17 @@ private function getSupportedPhpVersions( $toVersion = $this->parsePhpVersion($attributeArg->value->value, 99); } } - return [$fromVersion, $toVersion]; } - private function getNodeAttribute( - Node\Stmt\ClassLike|Node\Stmt\Function_|Node\Stmt\Const_|Node\Expr\FuncCall|Node\Stmt\ClassConst|Node\Stmt\Property|Node\Stmt\ClassMethod|Node\Param|Node\Stmt\EnumCase $node, - string $attributeName, - ): Node\Attribute|null { + /** + * @param \PhpParser\Node\Stmt\ClassLike|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Stmt\Const_|\PhpParser\Node\Expr\FuncCall|\PhpParser\Node\Stmt\ClassConst|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Param|\PhpParser\Node\Stmt\EnumCase $node + */ + private function getNodeAttribute($node, string $attributeName): ?\PhpParser\Node\Attribute + { if ($node instanceof Node\Expr\FuncCall || $node instanceof Node\Stmt\Const_) { return null; } - foreach ($node->attrGroups as $attributesGroupNode) { foreach ($attributesGroupNode->attrs as $attributeNode) { if ($attributeNode->name->toString() === $attributeName) { @@ -858,7 +883,6 @@ private function getNodeAttribute( } } } - return null; } @@ -869,10 +893,13 @@ private function parsePhpVersion(string $version, int $defaultPatch = 0): int return $parts[0] * 10000 + $parts[1] * 100 + ($parts[2] ?? $defaultPatch); } - private function normalizeType(string $type): Node\Name|Node\Identifier|Node\ComplexType|null + /** + * @return \PhpParser\Node\Name|\PhpParser\Node\Identifier|\PhpParser\Node\ComplexType|null + */ + private function normalizeType(string $type) { // There are some invalid types in stubs, eg. `string[]|string|null` - if (str_contains($type, '[')) { + if (strpos($type, '[') !== false) { return null; } diff --git a/src/SourceLocator/SourceStubber/ReflectionSourceStubber.php b/src/SourceLocator/SourceStubber/ReflectionSourceStubber.php index cab729ced..5cfc993b2 100644 --- a/src/SourceLocator/SourceStubber/ReflectionSourceStubber.php +++ b/src/SourceLocator/SourceStubber/ReflectionSourceStubber.php @@ -71,18 +71,20 @@ */ final class ReflectionSourceStubber implements SourceStubber { + private int $phpVersion = PHP_VERSION_ID; private BuilderFactory $builderFactory; private Standard $prettyPrinter; - public function __construct(Standard $prettyPrinter, private int $phpVersion = PHP_VERSION_ID) + public function __construct(Standard $prettyPrinter, int $phpVersion = PHP_VERSION_ID) { + $this->phpVersion = $phpVersion; $this->builderFactory = new BuilderFactory(); $this->prettyPrinter = $prettyPrinter; } /** @param class-string|trait-string $className */ - public function generateClassStub(string $className): StubData|null + public function generateClassStub(string $className): ?\Roave\BetterReflection\SourceLocator\SourceStubber\StubData { /** @phpstan-ignore staticMethod.alreadyNarrowedType */ if (! ClassExistenceChecker::exists($className, false)) { @@ -128,13 +130,13 @@ public function generateClassStub(string $className): StubData|null ? $this->generateStubInNamespace($node, $classReflection->getNamespaceName()) : $this->generateStub($node); - $extensionName = $classReflection->getExtension()?->getName(); + $extensionName = ($nullsafeVariable1 = $classReflection->getExtension()) ? $nullsafeVariable1->getName() : null; assert((is_string($extensionName) && $extensionName !== '') || $extensionName === null); return $this->createStubData($stub, $extensionName, $classReflection->getFileName() !== false ? $classReflection->getFileName() : null); } - public function generateFunctionStub(string $functionName): StubData|null + public function generateFunctionStub(string $functionName): ?\Roave\BetterReflection\SourceLocator\SourceStubber\StubData { if (! function_exists($functionName)) { return null; @@ -165,7 +167,7 @@ public function generateFunctionStubFromReflection(CoreReflectionFunction $funct $functionNode->setReturnType($this->formatType($returnType)); } - $extensionName = $functionReflection->getExtension()?->getName(); + $extensionName = ($nullsafeVariable2 = $functionReflection->getExtension()) ? $nullsafeVariable2->getName() : null; assert((is_string($extensionName) && $extensionName !== '') || $extensionName === null); if (! $functionReflection->inNamespace() || $functionReflection->isClosure()) { @@ -175,7 +177,7 @@ public function generateFunctionStubFromReflection(CoreReflectionFunction $funct return $this->createStubData($this->generateStubInNamespace($functionNode->getNode(), $functionReflection->getNamespaceName()), $extensionName, $functionReflection->getFileName() !== false ? $functionReflection->getFileName() : null); } - public function generateConstantStub(string $constantName): StubData|null + public function generateConstantStub(string $constantName): ?\Roave\BetterReflection\SourceLocator\SourceStubber\StubData { $constantData = $this->findConstantData($constantName); @@ -198,7 +200,7 @@ public function generateConstantStub(string $constantName): StubData|null } /** @return array{0: scalar|list|resource|null, 1: non-empty-string|null}|null */ - private function findConstantData(string $constantName): array|null + private function findConstantData(string $constantName) { /** @var array|resource|null>> $constants */ $constants = get_defined_constants(true); @@ -215,7 +217,10 @@ private function findConstantData(string $constantName): array|null return null; } - private function createClass(CoreReflectionClass $classReflection): Class_|Interface_|Trait_|Enum_ + /** + * @return \PhpParser\Builder\Class_|\PhpParser\Builder\Interface_|\PhpParser\Builder\Trait_|\PhpParser\Builder\Enum_ + */ + private function createClass(CoreReflectionClass $classReflection) { if ($classReflection instanceof CoreReflectionEnum) { return $this->builderFactory->enum($classReflection->getShortName()); @@ -232,32 +237,32 @@ private function createClass(CoreReflectionClass $classReflection): Class_|Inter return $this->builderFactory->class($classReflection->getShortName()); } - private function addAttributes( - Class_|Interface_|Trait_|Enum_|ClassConst|EnumCase|Method|Property|Function_|Param $node, - CoreReflectionClass|CoreReflectionClassConstant|CoreReflectionEnumUnitCase|CoreReflectionMethod|CoreReflectionProperty|CoreReflectionFunction|CoreReflectionParameter $reflection, - ): void { + /** + * @param \PhpParser\Builder\Class_|\PhpParser\Builder\Interface_|\PhpParser\Builder\Trait_|\PhpParser\Builder\Enum_|\PhpParser\Builder\ClassConst|\PhpParser\Builder\EnumCase|\PhpParser\Builder\Method|\PhpParser\Builder\Property|\PhpParser\Builder\Function_|\PhpParser\Builder\Param $node + * @param CoreReflectionClass|CoreReflectionClassConstant|CoreReflectionEnumUnitCase|CoreReflectionMethod|CoreReflectionProperty|CoreReflectionFunction|CoreReflectionParameter $reflection + */ + private function addAttributes($node, $reflection): void + { if (!method_exists($reflection, 'getAttributes')) { return; } - - $attributeReflections = $reflection->getAttributes(); - + $attributeReflections = method_exists($reflection, 'getAttributes') ? $reflection->getAttributes() : []; if ($attributeReflections === []) { return; } - foreach ($attributeReflections as $attributeReflection) { $node->addAttribute($this->builderFactory->attribute(new FullyQualified($attributeReflection->getName()), $attributeReflection->getArguments())); } } - private function addDocComment( - Class_|Interface_|Trait_|Enum_|Method|Property|Function_ $node, - CoreReflectionClass|CoreReflectionMethod|CoreReflectionProperty|CoreReflectionFunction $reflection, - ): void { + /** + * @param \PhpParser\Builder\Class_|\PhpParser\Builder\Interface_|\PhpParser\Builder\Trait_|\PhpParser\Builder\Enum_|\PhpParser\Builder\Method|\PhpParser\Builder\Property|\PhpParser\Builder\Function_ $node + * @param CoreReflectionClass|CoreReflectionMethod|CoreReflectionProperty|CoreReflectionFunction $reflection + */ + private function addDocComment($node, $reflection): void + { $docComment = $reflection->getDocComment() !== false ? $reflection->getDocComment() : ''; $annotations = []; - if ( ($reflection instanceof CoreReflectionMethod || $reflection instanceof CoreReflectionFunction) && $reflection->isInternal() @@ -270,17 +275,14 @@ private function addDocComment( $annotations[] = sprintf('@%s', AnnotationHelper::TENTATIVE_RETURN_TYPE_ANNOTATION); } } - if ($docComment === '' && $annotations === []) { return; } - if ($docComment === '') { $docComment = sprintf("/**\n* %s\n*/", implode("\n *", $annotations)); } elseif ($annotations !== []) { $docComment = preg_replace('~\s+\*/$~', sprintf("\n* %s\n*/", implode("\n *", $annotations)), $docComment); } - $node->setDocComment(new Doc($docComment)); } @@ -311,7 +313,10 @@ private function addClassModifiers(Class_ $classNode, CoreReflectionClass $class $classNode->makeFinal(); } - private function addExtendsAndImplements(Class_|Interface_|Enum_ $classNode, CoreReflectionClass $classReflection): void + /** + * @param \PhpParser\Builder\Class_|\PhpParser\Builder\Interface_|\PhpParser\Builder\Enum_ $classNode + */ + private function addExtendsAndImplements($classNode, CoreReflectionClass $classReflection): void { $interfaces = $classReflection->getInterfaceNames(); @@ -331,7 +336,7 @@ private function addExtendsAndImplements(Class_|Interface_|Enum_ $classNode, Cor foreach ($interfaces as $interfaceName) { if ( method_exists($classReflection, 'isEnum') - && $classReflection->isEnum() + && (method_exists($classReflection, 'isEnum') ? $classReflection->isEnum() : false) && in_array($interfaceName, [BackedEnum::class, UnitEnum::class], true) ) { continue; @@ -347,7 +352,10 @@ private function addExtendsAndImplements(Class_|Interface_|Enum_ $classNode, Cor } } - private function addTraitUse(Class_|Trait_|Enum_ $classNode, CoreReflectionClass $classReflection): void + /** + * @param \PhpParser\Builder\Class_|\PhpParser\Builder\Trait_|\PhpParser\Builder\Enum_ $classNode + */ + private function addTraitUse($classNode, CoreReflectionClass $classReflection): void { /** @var array $traitAliases */ $traitAliases = $classReflection->getTraitAliases(); @@ -373,7 +381,10 @@ private function addTraitUse(Class_|Trait_|Enum_ $classNode, CoreReflectionClass } } - private function addProperties(Class_|Trait_ $classNode, CoreReflectionClass $classReflection): void + /** + * @param \PhpParser\Builder\Class_|\PhpParser\Builder\Trait_ $classNode + */ + private function addProperties($classNode, CoreReflectionClass $classReflection): void { foreach ($classReflection->getProperties() as $propertyReflection) { if (! $this->isPropertyDeclaredInClass($propertyReflection, $classReflection)) { @@ -388,8 +399,8 @@ private function addProperties(Class_|Trait_ $classNode, CoreReflectionClass $cl if (method_exists($propertyReflection, 'hasDefaultValue') && $propertyReflection->hasDefaultValue()) { try { - $propertyNode->setDefault($propertyReflection->getDefaultValue()); - } catch (LogicException) { + $propertyNode->setDefault($propertyReflection->getDeclaringClass()->getDefaultProperties()[$propertyReflection->getName()] ?? null); + } catch (LogicException $exception) { // Nothing } } @@ -458,7 +469,10 @@ private function addEnumCases(Enum_ $enumNode, CoreReflectionEnum $enumReflectio } } - private function addClassConstants(Class_|Interface_|Trait_|Enum_ $classNode, CoreReflectionClass $classReflection): void + /** + * @param \PhpParser\Builder\Class_|\PhpParser\Builder\Interface_|\PhpParser\Builder\Trait_|\PhpParser\Builder\Enum_ $classNode + */ + private function addClassConstants($classNode, CoreReflectionClass $classReflection): void { foreach ($classReflection->getReflectionConstants() as $constantReflection) { if (method_exists($constantReflection, 'isEnumCase') && $constantReflection->isEnumCase()) { @@ -507,7 +521,10 @@ private function addClassConstantModifiers(ClassConst $classConstantNode, CoreRe } } - private function addMethods(Class_|Interface_|Trait_|Enum_ $classNode, CoreReflectionClass $classReflection): void + /** + * @param \PhpParser\Builder\Class_|\PhpParser\Builder\Interface_|\PhpParser\Builder\Trait_|\PhpParser\Builder\Enum_ $classNode + */ + private function addMethods($classNode, CoreReflectionClass $classReflection): void { foreach ($classReflection->getMethods() as $methodReflection) { if (! $this->isMethodDeclaredInClass($methodReflection, $classReflection)) { @@ -681,7 +698,10 @@ private function setParameterDefaultValue(CoreReflectionParameter $parameterRefl $parameterNode->setDefault($defaultValue); } - private function formatType(CoreReflectionType $type): Name|NullableType|UnionType|IntersectionType + /** + * @return \PhpParser\Node\Name|\PhpParser\Node\NullableType|\PhpParser\Node\UnionType|\PhpParser\Node\IntersectionType + */ + private function formatType(CoreReflectionType $type) { if ($type instanceof CoreReflectionIntersectionType) { /** @var list $types */ @@ -752,7 +772,7 @@ private function formatType(CoreReflectionType $type): Name|NullableType|UnionTy */ private function formatTypes(array $types): array { - return array_map(function (CoreReflectionType $type): Name|UnionType|IntersectionType { + return array_map(function (CoreReflectionType $type) { $formattedType = $this->formatType($type); assert($formattedType instanceof Name || $formattedType instanceof UnionType || $formattedType instanceof IntersectionType); @@ -785,7 +805,7 @@ private function generateStub(Node $node): string } /** @param non-empty-string|null $extensionName */ - private function createStubData(string $stub, string|null $extensionName, string|null $fileName): StubData + private function createStubData(string $stub, ?string $extensionName, ?string $fileName): StubData { return new StubData($stub, $extensionName, $fileName); } diff --git a/src/SourceLocator/SourceStubber/SourceStubber.php b/src/SourceLocator/SourceStubber/SourceStubber.php index a9a27344a..704e08b0b 100644 --- a/src/SourceLocator/SourceStubber/SourceStubber.php +++ b/src/SourceLocator/SourceStubber/SourceStubber.php @@ -12,15 +12,15 @@ interface SourceStubber * * @param class-string|trait-string $className */ - public function generateClassStub(string $className): StubData|null; + public function generateClassStub(string $className): ?\Roave\BetterReflection\SourceLocator\SourceStubber\StubData; /** * Generates stub for given function. Returns null when it cannot generate the stub. */ - public function generateFunctionStub(string $functionName): StubData|null; + public function generateFunctionStub(string $functionName): ?\Roave\BetterReflection\SourceLocator\SourceStubber\StubData; /** * Generates stub for given constant. Returns null when it cannot generate the stub. */ - public function generateConstantStub(string $constantName): StubData|null; + public function generateConstantStub(string $constantName): ?\Roave\BetterReflection\SourceLocator\SourceStubber\StubData; } diff --git a/src/SourceLocator/SourceStubber/StubData.php b/src/SourceLocator/SourceStubber/StubData.php index 04878b111..e212b4c39 100644 --- a/src/SourceLocator/SourceStubber/StubData.php +++ b/src/SourceLocator/SourceStubber/StubData.php @@ -7,9 +7,18 @@ /** @internal */ class StubData { + private string $stub; + /** + * @var non-empty-string|null + */ + private $extensionName; + private ?string $fileName; /** @param non-empty-string|null $extensionName */ - public function __construct(private string $stub, private string|null $extensionName, private ?string $fileName) + public function __construct(string $stub, ?string $extensionName, ?string $fileName) { + $this->stub = $stub; + $this->extensionName = $extensionName; + $this->fileName = $fileName; } public function getStub(): string @@ -18,7 +27,7 @@ public function getStub(): string } /** @return non-empty-string|null */ - public function getExtensionName(): string|null + public function getExtensionName(): ?string { return $this->extensionName; } diff --git a/src/SourceLocator/Type/AbstractSourceLocator.php b/src/SourceLocator/Type/AbstractSourceLocator.php index cfc2aadda..c5743ed64 100644 --- a/src/SourceLocator/Type/AbstractSourceLocator.php +++ b/src/SourceLocator/Type/AbstractSourceLocator.php @@ -15,6 +15,7 @@ abstract class AbstractSourceLocator implements SourceLocator { + private AstLocator $astLocator; /** * Children should implement this method and return a LocatedSource object * which contains the source and the file from which it was located. @@ -23,10 +24,11 @@ abstract class AbstractSourceLocator implements SourceLocator * return new LocatedSource(['astLocator = $astLocator; } /** @@ -34,7 +36,7 @@ public function __construct(private AstLocator $astLocator) * * @throws ParseToAstFailure */ - public function locateIdentifier(Reflector $reflector, Identifier $identifier): Reflection|null + public function locateIdentifier(Reflector $reflector, Identifier $identifier): ?\Roave\BetterReflection\Reflection\Reflection { $locatedSource = $this->createLocatedSource($identifier); @@ -44,7 +46,7 @@ public function locateIdentifier(Reflector $reflector, Identifier $identifier): try { return $this->astLocator->findReflection($reflector, $locatedSource, $identifier); - } catch (IdentifierNotFound) { + } catch (IdentifierNotFound $exception) { return null; } } diff --git a/src/SourceLocator/Type/AggregateSourceLocator.php b/src/SourceLocator/Type/AggregateSourceLocator.php index a5a760093..296ff0f1d 100644 --- a/src/SourceLocator/Type/AggregateSourceLocator.php +++ b/src/SourceLocator/Type/AggregateSourceLocator.php @@ -14,12 +14,17 @@ class AggregateSourceLocator implements SourceLocator { + /** + * @var list + */ + private array $sourceLocators = []; /** @param list $sourceLocators */ - public function __construct(private array $sourceLocators = []) + public function __construct(array $sourceLocators = []) { + $this->sourceLocators = $sourceLocators; } - public function locateIdentifier(Reflector $reflector, Identifier $identifier): Reflection|null + public function locateIdentifier(Reflector $reflector, Identifier $identifier): ?\Roave\BetterReflection\Reflection\Reflection { foreach ($this->sourceLocators as $sourceLocator) { $located = $sourceLocator->locateIdentifier($reflector, $identifier); diff --git a/src/SourceLocator/Type/AnonymousClassObjectSourceLocator.php b/src/SourceLocator/Type/AnonymousClassObjectSourceLocator.php index 23734964b..3c723202e 100644 --- a/src/SourceLocator/Type/AnonymousClassObjectSourceLocator.php +++ b/src/SourceLocator/Type/AnonymousClassObjectSourceLocator.php @@ -33,10 +33,12 @@ /** @internal */ final class AnonymousClassObjectSourceLocator implements SourceLocator { + private Parser $parser; private CoreReflectionClass $coreClassReflection; - public function __construct(object $anonymousClassObject, private Parser $parser) + public function __construct(object $anonymousClassObject, Parser $parser) { + $this->parser = $parser; $this->coreClassReflection = new CoreReflectionClass($anonymousClassObject); } @@ -45,7 +47,7 @@ public function __construct(object $anonymousClassObject, private Parser $parser * * @throws ParseToAstFailure */ - public function locateIdentifier(Reflector $reflector, Identifier $identifier): Reflection|null + public function locateIdentifier(Reflector $reflector, Identifier $identifier): ?\Roave\BetterReflection\Reflection\Reflection { return $this->getReflectionClass($reflector, $identifier->getType()); } @@ -60,7 +62,7 @@ public function locateIdentifiersByType(Reflector $reflector, IdentifierType $id return array_filter([$this->getReflectionClass($reflector, $identifierType)]); } - private function getReflectionClass(Reflector $reflector, IdentifierType $identifierType): ReflectionClass|null + private function getReflectionClass(Reflector $reflector, IdentifierType $identifierType): ?\Roave\BetterReflection\Reflection\ReflectionClass { if (! $identifierType->isClass()) { return null; @@ -73,7 +75,7 @@ private function getReflectionClass(Reflector $reflector, IdentifierType $identi /** @phpstan-var non-empty-string $fileName */ $fileName = $this->coreClassReflection->getFileName(); - if (str_contains($fileName, 'eval()\'d code')) { + if (strpos($fileName, 'eval()\'d code') !== false) { throw EvaledAnonymousClassCannotBeLocated::create(); } @@ -83,11 +85,15 @@ private function getReflectionClass(Reflector $reflector, IdentifierType $identi $nodeVisitor = new class ($fileName, $this->coreClassReflection->getStartLine()) extends NodeVisitorAbstract { + private string $fileName; + private int $startLine; /** @var list */ private array $anonymousClassNodes = []; - public function __construct(private string $fileName, private int $startLine) + public function __construct(string $fileName, int $startLine) { + $this->fileName = $fileName; + $this->startLine = $startLine; } /** diff --git a/src/SourceLocator/Type/AutoloadSourceLocator.php b/src/SourceLocator/Type/AutoloadSourceLocator.php index e8f99799b..5b21e8cba 100644 --- a/src/SourceLocator/Type/AutoloadSourceLocator.php +++ b/src/SourceLocator/Type/AutoloadSourceLocator.php @@ -56,7 +56,7 @@ class AutoloadSourceLocator extends AbstractSourceLocator private NodeVisitorAbstract $constantVisitor; - public function __construct(AstLocator|null $astLocator = null, Parser|null $phpParser = null) + public function __construct($astLocator = null, ?\PhpParser\Parser $phpParser = null) { $betterReflection = new BetterReflection(); @@ -74,7 +74,7 @@ public function __construct(AstLocator|null $astLocator = null, Parser|null $php * @throws InvalidArgumentException * @throws InvalidFileLocation */ - protected function createLocatedSource(Identifier $identifier): LocatedSource|null + protected function createLocatedSource(Identifier $identifier): ?\Roave\BetterReflection\SourceLocator\Located\LocatedSource { $locatedData = $this->attemptAutoloadForIdentifier($identifier); @@ -109,7 +109,7 @@ protected function createLocatedSource(Identifier $identifier): LocatedSource|nu * * @throws ReflectionException */ - private function attemptAutoloadForIdentifier(Identifier $identifier): array|null + private function attemptAutoloadForIdentifier(Identifier $identifier): ?array { if ($identifier->isClass()) { return $this->locateClassByName($identifier->getName()); @@ -149,7 +149,7 @@ private function attemptAutoloadForIdentifier(Identifier $identifier): array|nul * * @throws ReflectionException */ - private function locateClassByName(string $className): array|null + private function locateClassByName(string $className): ?array { if (ClassExistenceChecker::exists($className, false)) { $classReflection = new ReflectionClass($className); @@ -167,7 +167,7 @@ private function locateClassByName(string $className): array|null try { $locatedFile = FileReadTrapStreamWrapper::withStreamWrapperOverride( - static function () use ($className): string|null { + static function () use ($className): ?string { foreach (spl_autoload_functions() as $preExistingAutoloader) { $preExistingAutoloader($className); @@ -211,7 +211,7 @@ private function silenceErrors(): void * * @throws ReflectionException */ - private function locateFunctionByName(string $functionName): array|null + private function locateFunctionByName(string $functionName): ?array { if (! function_exists($functionName)) { return null; @@ -233,7 +233,7 @@ private function locateFunctionByName(string $functionName): array|null * * @return array{fileName: string, name: string}|null */ - private function locateConstantByName(string $constantName): array|null + private function locateConstantByName(string $constantName): ?array { if (! defined($constantName)) { return null; @@ -262,7 +262,7 @@ private function locateConstantByName(string $constantName): array|null foreach (array_reverse(get_included_files()) as $includedFileName) { try { FileChecker::assertReadableFile($includedFileName); - } catch (InvalidFileLocation) { + } catch (InvalidFileLocation $exception) { continue; } @@ -292,15 +292,21 @@ private function createConstantVisitor(): NodeVisitorAbstract { return new class () extends NodeVisitorAbstract { - private string|null $constantName = null; + /** + * @var string|null + */ + private $constantName = null; - private Node\Stmt\Const_|Node\Expr\FuncCall|null $node = null; + /** + * @var \PhpParser\Node\Stmt\Const_|\PhpParser\Node\Expr\FuncCall|null + */ + private $node = null; - public function enterNode(Node $node): int|null + public function enterNode(Node $node): ?int { if ($node instanceof Node\Stmt\Const_) { foreach ($node->consts as $constNode) { - if ($constNode->namespacedName?->toString() === $this->constantName) { + if ((($nullsafeVariable1 = $constNode->namespacedName) ? $nullsafeVariable1->toString() : null) === $this->constantName) { $this->node = $node; return NodeVisitor::STOP_TRAVERSAL; @@ -315,7 +321,7 @@ public function enterNode(Node $node): int|null try { ConstantNodeChecker::assertValidDefineFunctionCall($functionCall); - } catch (InvalidConstantNode) { + } catch (InvalidConstantNode $exception) { return null; } @@ -340,7 +346,7 @@ public function setConstantName(string $constantName): void } /** @return Node\Stmt\Const_|Node\Expr\FuncCall|null */ - public function getNode(): Node|null + public function getNode() { return $this->node; } diff --git a/src/SourceLocator/Type/AutoloadSourceLocator/FileReadTrapStreamWrapper.php b/src/SourceLocator/Type/AutoloadSourceLocator/FileReadTrapStreamWrapper.php index fa198eaa9..b404491af 100644 --- a/src/SourceLocator/Type/AutoloadSourceLocator/FileReadTrapStreamWrapper.php +++ b/src/SourceLocator/Type/AutoloadSourceLocator/FileReadTrapStreamWrapper.php @@ -35,15 +35,16 @@ final class FileReadTrapStreamWrapper ]; /** @var list|null */ - private static array|null $registeredStreamWrapperProtocols = null; + private static $registeredStreamWrapperProtocols = null; /** * Read this property to determine the last file on which reads were attempted * * @psalm-readonly * @psalm-allow-private-mutation + * @var string|null */ - public static string|null $autoloadLocatedFile = null; + public static $autoloadLocatedFile = null; /** @var resource */ public $context; @@ -55,14 +56,12 @@ final class FileReadTrapStreamWrapper * @psalm-return ExecutedMethodReturnType * * @psalm-template ExecutedMethodReturnType of mixed + * @return mixed */ - public static function withStreamWrapperOverride( - callable $executeMeWithinStreamWrapperOverride, - array $streamWrapperProtocols = self::DEFAULT_STREAM_WRAPPER_PROTOCOLS, - ): mixed { + public static function withStreamWrapperOverride(callable $executeMeWithinStreamWrapperOverride, array $streamWrapperProtocols = self::DEFAULT_STREAM_WRAPPER_PROTOCOLS) + { self::$registeredStreamWrapperProtocols = $streamWrapperProtocols; self::$autoloadLocatedFile = null; - try { foreach ($streamWrapperProtocols as $protocol) { stream_wrapper_unregister($protocol); @@ -78,7 +77,6 @@ public static function withStreamWrapperOverride( self::$registeredStreamWrapperProtocols = null; self::$autoloadLocatedFile = null; } - return $result; } @@ -121,7 +119,7 @@ public function stream_open($path, $mode, $options, &$opened_path): bool * * @return mixed[]|bool */ - public function url_stat($path, $flags): array|bool + public function url_stat($path, $flags) { if (self::$registeredStreamWrapperProtocols === null) { throw new LogicException(sprintf('%s not registered: cannot operate. Do not call this method directly.', self::class)); diff --git a/src/SourceLocator/Type/ClosureSourceLocator.php b/src/SourceLocator/Type/ClosureSourceLocator.php index 74cc006f1..9e0e69b03 100644 --- a/src/SourceLocator/Type/ClosureSourceLocator.php +++ b/src/SourceLocator/Type/ClosureSourceLocator.php @@ -34,10 +34,12 @@ /** @internal */ final class ClosureSourceLocator implements SourceLocator { + private Parser $parser; private CoreFunctionReflection $coreFunctionReflection; - public function __construct(Closure $closure, private Parser $parser) + public function __construct(Closure $closure, Parser $parser) { + $this->parser = $parser; $this->coreFunctionReflection = new CoreFunctionReflection($closure); } @@ -46,7 +48,7 @@ public function __construct(Closure $closure, private Parser $parser) * * @throws ParseToAstFailure */ - public function locateIdentifier(Reflector $reflector, Identifier $identifier): Reflection|null + public function locateIdentifier(Reflector $reflector, Identifier $identifier): ?\Roave\BetterReflection\Reflection\Reflection { return $this->getReflectionFunction($reflector, $identifier->getType()); } @@ -61,7 +63,7 @@ public function locateIdentifiersByType(Reflector $reflector, IdentifierType $id return array_filter([$this->getReflectionFunction($reflector, $identifierType)]); } - private function getReflectionFunction(Reflector $reflector, IdentifierType $identifierType): ReflectionFunction|null + private function getReflectionFunction(Reflector $reflector, IdentifierType $identifierType): ?\Roave\BetterReflection\Reflection\ReflectionFunction { if (! $identifierType->isFunction()) { return null; @@ -70,7 +72,7 @@ private function getReflectionFunction(Reflector $reflector, IdentifierType $ide /** @phpstan-var non-empty-string $fileName */ $fileName = $this->coreFunctionReflection->getFileName(); - if (str_contains($fileName, 'eval()\'d code')) { + if (strpos($fileName, 'eval()\'d code') !== false) { throw EvaledClosureCannotBeLocated::create(); } @@ -80,13 +82,20 @@ private function getReflectionFunction(Reflector $reflector, IdentifierType $ide $nodeVisitor = new class ($fileName, $this->coreFunctionReflection->getStartLine()) extends NodeVisitorAbstract { + private string $fileName; + private int $startLine; /** @var list */ private array $closureNodes = []; - private Namespace_|null $currentNamespace = null; + /** + * @var \PhpParser\Node\Stmt\Namespace_|null + */ + private $currentNamespace = null; - public function __construct(private string $fileName, private int $startLine) + public function __construct(string $fileName, int $startLine) { + $this->fileName = $fileName; + $this->startLine = $startLine; } /** diff --git a/src/SourceLocator/Type/Composer/Factory/MakeLocatorForComposerJson.php b/src/SourceLocator/Type/Composer/Factory/MakeLocatorForComposerJson.php index 06d2c6162..4432698ea 100644 --- a/src/SourceLocator/Type/Composer/Factory/MakeLocatorForComposerJson.php +++ b/src/SourceLocator/Type/Composer/Factory/MakeLocatorForComposerJson.php @@ -66,7 +66,7 @@ public function __invoke(string $installationPath, Locator $astLocator): SourceL assert(is_string($composerJsonContent)); /** @psalm-var array{autoload: ComposerAutoload} $composer */ - $composer = json_decode($composerJsonContent, true, flags: JSON_THROW_ON_ERROR); + $composer = json_decode($composerJsonContent, true, 512, JSON_THROW_ON_ERROR); $pathPrefix = $realInstallationPath . '/'; $classMapPaths = $this->prefixPaths($this->packageToClassMapPaths($composer), $pathPrefix); @@ -108,7 +108,7 @@ static function (string $file) use ($astLocator): array { */ private function packageToPsr4AutoloadNamespaces(array $package): array { - return array_map(static fn (string|array $namespacePaths): array => (array) $namespacePaths, $package['autoload']['psr-4'] ?? []); + return array_map(static fn ($namespacePaths): array => (array) $namespacePaths, $package['autoload']['psr-4'] ?? []); } /** @@ -118,7 +118,7 @@ private function packageToPsr4AutoloadNamespaces(array $package): array */ private function packageToPsr0AutoloadNamespaces(array $package): array { - return array_map(static fn (string|array $namespacePaths): array => (array) $namespacePaths, $package['autoload']['psr-0'] ?? []); + return array_map(static fn ($namespacePaths): array => (array) $namespacePaths, $package['autoload']['psr-0'] ?? []); } /** diff --git a/src/SourceLocator/Type/Composer/Factory/MakeLocatorForComposerJsonAndInstalledJson.php b/src/SourceLocator/Type/Composer/Factory/MakeLocatorForComposerJsonAndInstalledJson.php index b3cb7a228..9f525c5e8 100644 --- a/src/SourceLocator/Type/Composer/Factory/MakeLocatorForComposerJsonAndInstalledJson.php +++ b/src/SourceLocator/Type/Composer/Factory/MakeLocatorForComposerJsonAndInstalledJson.php @@ -57,7 +57,7 @@ public function __invoke(string $installationPath, Locator $astLocator): SourceL assert(is_string($composerJsonContent)); /** @psalm-var Composer $composer */ - $composer = json_decode($composerJsonContent, true, flags: JSON_THROW_ON_ERROR); + $composer = json_decode($composerJsonContent, true, 512, JSON_THROW_ON_ERROR); $vendorDir = rtrim($composer['config']['vendor-dir'] ?? 'vendor', '/'); $installedJsonPath = $realInstallationPath . '/' . $vendorDir . '/composer/installed.json'; @@ -70,7 +70,7 @@ public function __invoke(string $installationPath, Locator $astLocator): SourceL assert(is_string($jsonContent)); /** @psalm-var array{packages?: list}|list $installedJson */ - $installedJson = json_decode($jsonContent, true, flags: JSON_THROW_ON_ERROR); + $installedJson = json_decode($jsonContent, true, 512, JSON_THROW_ON_ERROR); /** @psalm-var list $installed */ $installed = $installedJson['packages'] ?? $installedJson; @@ -138,7 +138,7 @@ static function (string $file) use ($astLocator): array { */ private function packageToPsr4AutoloadNamespaces(array $package): array { - return array_map(static fn (string|array $namespacePaths): array => (array) $namespacePaths, $package['autoload']['psr-4'] ?? []); + return array_map(static fn ($namespacePaths): array => (array) $namespacePaths, $package['autoload']['psr-4'] ?? []); } /** @@ -148,7 +148,7 @@ private function packageToPsr4AutoloadNamespaces(array $package): array */ private function packageToPsr0AutoloadNamespaces(array $package): array { - return array_map(static fn (string|array $namespacePaths): array => (array) $namespacePaths, $package['autoload']['psr-0'] ?? []); + return array_map(static fn ($namespacePaths): array => (array) $namespacePaths, $package['autoload']['psr-0'] ?? []); } /** diff --git a/src/SourceLocator/Type/Composer/Factory/MakeLocatorForInstalledJson.php b/src/SourceLocator/Type/Composer/Factory/MakeLocatorForInstalledJson.php index 4182cdd94..fcb04c250 100644 --- a/src/SourceLocator/Type/Composer/Factory/MakeLocatorForInstalledJson.php +++ b/src/SourceLocator/Type/Composer/Factory/MakeLocatorForInstalledJson.php @@ -57,7 +57,7 @@ public function __invoke(string $installationPath, Locator $astLocator): SourceL assert(is_string($composerJsonContent)); /** @psalm-var Composer $composer */ - $composer = json_decode($composerJsonContent, true, flags: JSON_THROW_ON_ERROR); + $composer = json_decode($composerJsonContent, true, 512, JSON_THROW_ON_ERROR); $vendorDir = rtrim($composer['config']['vendor-dir'] ?? 'vendor', '/'); $installedJsonPath = $realInstallationPath . '/' . $vendorDir . '/composer/installed.json'; @@ -70,7 +70,7 @@ public function __invoke(string $installationPath, Locator $astLocator): SourceL assert(is_string($jsonContent)); /** @var array{packages: list}|list $installedJson */ - $installedJson = json_decode($jsonContent, true, flags: JSON_THROW_ON_ERROR); + $installedJson = json_decode($jsonContent, true, 512, JSON_THROW_ON_ERROR); /** @psalm-var list $installed */ $installed = $installedJson['packages'] ?? $installedJson; @@ -138,7 +138,7 @@ static function (string $file) use ($astLocator): array { */ private function packageToPsr4AutoloadNamespaces(array $package): array { - return array_map(static fn (string|array $namespacePaths): array => (array) $namespacePaths, $package['autoload']['psr-4'] ?? []); + return array_map(static fn ($namespacePaths): array => (array) $namespacePaths, $package['autoload']['psr-4'] ?? []); } /** @@ -148,7 +148,7 @@ private function packageToPsr4AutoloadNamespaces(array $package): array */ private function packageToPsr0AutoloadNamespaces(array $package): array { - return array_map(static fn (string|array $namespacePaths): array => (array) $namespacePaths, $package['autoload']['psr-0'] ?? []); + return array_map(static fn ($namespacePaths): array => (array) $namespacePaths, $package['autoload']['psr-0'] ?? []); } /** diff --git a/src/SourceLocator/Type/Composer/PsrAutoloaderLocator.php b/src/SourceLocator/Type/Composer/PsrAutoloaderLocator.php index ec6b97ca7..43de46973 100644 --- a/src/SourceLocator/Type/Composer/PsrAutoloaderLocator.php +++ b/src/SourceLocator/Type/Composer/PsrAutoloaderLocator.php @@ -21,11 +21,15 @@ final class PsrAutoloaderLocator implements SourceLocator { - public function __construct(private PsrAutoloaderMapping $mapping, private Locator $astLocator) + private PsrAutoloaderMapping $mapping; + private Locator $astLocator; + public function __construct(PsrAutoloaderMapping $mapping, Locator $astLocator) { + $this->mapping = $mapping; + $this->astLocator = $astLocator; } - public function locateIdentifier(Reflector $reflector, Identifier $identifier): Reflection|null + public function locateIdentifier(Reflector $reflector, Identifier $identifier): ?\Roave\BetterReflection\Reflection\Reflection { /** @phpstan-var non-empty-string $file */ foreach ($this->mapping->resolvePossibleFilePaths($identifier) as $file) { @@ -41,9 +45,9 @@ public function locateIdentifier(Reflector $reflector, Identifier $identifier): ), $identifier, ); - } catch (InvalidFileLocation) { + } catch (InvalidFileLocation $exception) { // Ignore - } catch (IdentifierNotFound) { + } catch (IdentifierNotFound $exception) { // on purpose - autoloading is allowed to fail, and silently-failing autoloaders are normal/endorsed } } diff --git a/src/SourceLocator/Type/ComposerSourceLocator.php b/src/SourceLocator/Type/ComposerSourceLocator.php index faa1f2dd7..bf1671542 100644 --- a/src/SourceLocator/Type/ComposerSourceLocator.php +++ b/src/SourceLocator/Type/ComposerSourceLocator.php @@ -23,8 +23,10 @@ */ class ComposerSourceLocator extends AbstractSourceLocator { - public function __construct(private ClassLoader $classLoader, Locator $astLocator) + private ClassLoader $classLoader; + public function __construct(ClassLoader $classLoader, Locator $astLocator) { + $this->classLoader = $classLoader; parent::__construct($astLocator); } @@ -34,7 +36,7 @@ public function __construct(private ClassLoader $classLoader, Locator $astLocato * @throws InvalidArgumentException * @throws InvalidFileLocation */ - protected function createLocatedSource(Identifier $identifier): LocatedSource|null + protected function createLocatedSource(Identifier $identifier): ?\Roave\BetterReflection\SourceLocator\Located\LocatedSource { if ($identifier->getType()->getName() !== IdentifierType::IDENTIFIER_CLASS) { return null; diff --git a/src/SourceLocator/Type/DirectoriesSourceLocator.php b/src/SourceLocator/Type/DirectoriesSourceLocator.php index ff3256b26..8bc2eb32e 100644 --- a/src/SourceLocator/Type/DirectoriesSourceLocator.php +++ b/src/SourceLocator/Type/DirectoriesSourceLocator.php @@ -50,7 +50,7 @@ static function (string $directory) use ($astLocator): FileIteratorSourceLocator )); } - public function locateIdentifier(Reflector $reflector, Identifier $identifier): Reflection|null + public function locateIdentifier(Reflector $reflector, Identifier $identifier): ?\Roave\BetterReflection\Reflection\Reflection { return $this->aggregateSourceLocator->locateIdentifier($reflector, $identifier); } diff --git a/src/SourceLocator/Type/EvaledCodeSourceLocator.php b/src/SourceLocator/Type/EvaledCodeSourceLocator.php index 3b2f8e887..3b144a812 100644 --- a/src/SourceLocator/Type/EvaledCodeSourceLocator.php +++ b/src/SourceLocator/Type/EvaledCodeSourceLocator.php @@ -18,8 +18,10 @@ final class EvaledCodeSourceLocator extends AbstractSourceLocator { - public function __construct(Locator $astLocator, private SourceStubber $stubber) + private SourceStubber $stubber; + public function __construct(Locator $astLocator, SourceStubber $stubber) { + $this->stubber = $stubber; parent::__construct($astLocator); } @@ -29,7 +31,7 @@ public function __construct(Locator $astLocator, private SourceStubber $stubber) * @throws InvalidArgumentException * @throws InvalidFileLocation */ - protected function createLocatedSource(Identifier $identifier): LocatedSource|null + protected function createLocatedSource(Identifier $identifier): ?\Roave\BetterReflection\SourceLocator\Located\LocatedSource { $classReflection = $this->getInternalReflectionClass($identifier); @@ -46,7 +48,7 @@ protected function createLocatedSource(Identifier $identifier): LocatedSource|nu return new EvaledLocatedSource($stubData->getStub(), $classReflection->getName()); } - private function getInternalReflectionClass(Identifier $identifier): ReflectionClass|null + private function getInternalReflectionClass(Identifier $identifier): ?\ReflectionClass { if (! $identifier->isClass()) { return null; diff --git a/src/SourceLocator/Type/FileIteratorSourceLocator.php b/src/SourceLocator/Type/FileIteratorSourceLocator.php index dcd9cc0f0..2a43b0335 100644 --- a/src/SourceLocator/Type/FileIteratorSourceLocator.php +++ b/src/SourceLocator/Type/FileIteratorSourceLocator.php @@ -27,7 +27,11 @@ */ class FileIteratorSourceLocator implements SourceLocator { - private AggregateSourceLocator|null $aggregateSourceLocator = null; + private Locator $astLocator; + /** + * @var \Roave\BetterReflection\SourceLocator\Type\AggregateSourceLocator|null + */ + private $aggregateSourceLocator = null; /** @var Iterator */ private Iterator $fileSystemIterator; @@ -37,8 +41,9 @@ class FileIteratorSourceLocator implements SourceLocator * * @throws InvalidFileInfo In case of iterator not contains only SplFileInfo. */ - public function __construct(Iterator $fileInfoIterator, private Locator $astLocator) + public function __construct(Iterator $fileInfoIterator, Locator $astLocator) { + $this->astLocator = $astLocator; foreach ($fileInfoIterator as $fileInfo) { /** @phpstan-ignore instanceof.alwaysTrue */ if (! $fileInfo instanceof SplFileInfo) { @@ -55,7 +60,7 @@ private function getAggregatedSourceLocator(): AggregateSourceLocator // @infection-ignore-all Coalesce: There's no difference, it's just optimization return $this->aggregateSourceLocator ?? $this->aggregateSourceLocator = new AggregateSourceLocator(array_values(array_filter(array_map( - function (SplFileInfo $item): SingleFileSourceLocator|null { + function (SplFileInfo $item): ?\Roave\BetterReflection\SourceLocator\Type\SingleFileSourceLocator { $realPath = $item->getRealPath(); if (! ($item->isFile() && pathinfo($realPath, PATHINFO_EXTENSION) === 'php')) { @@ -73,7 +78,7 @@ function (SplFileInfo $item): SingleFileSourceLocator|null { * * @throws InvalidFileLocation */ - public function locateIdentifier(Reflector $reflector, Identifier $identifier): Reflection|null + public function locateIdentifier(Reflector $reflector, Identifier $identifier): ?\Roave\BetterReflection\Reflection\Reflection { return $this->getAggregatedSourceLocator()->locateIdentifier($reflector, $identifier); } diff --git a/src/SourceLocator/Type/MemoizingSourceLocator.php b/src/SourceLocator/Type/MemoizingSourceLocator.php index 8ac20e31a..0155a3c9b 100644 --- a/src/SourceLocator/Type/MemoizingSourceLocator.php +++ b/src/SourceLocator/Type/MemoizingSourceLocator.php @@ -15,17 +15,19 @@ final class MemoizingSourceLocator implements SourceLocator { + private SourceLocator $wrappedSourceLocator; /** @var array indexed by reflector key and identifier cache key */ private array $cacheByIdentifierKeyAndOid = []; /** @var array> indexed by reflector key and identifier type cache key */ private array $cacheByIdentifierTypeKeyAndOid = []; - public function __construct(private SourceLocator $wrappedSourceLocator) + public function __construct(SourceLocator $wrappedSourceLocator) { + $this->wrappedSourceLocator = $wrappedSourceLocator; } - public function locateIdentifier(Reflector $reflector, Identifier $identifier): Reflection|null + public function locateIdentifier(Reflector $reflector, Identifier $identifier): ?\Roave\BetterReflection\Reflection\Reflection { $cacheKey = sprintf('%s_%s', $this->reflectorCacheKey($reflector), $this->identifierToCacheKey($identifier)); @@ -52,7 +54,7 @@ public function locateIdentifiersByType(Reflector $reflector, IdentifierType $id private function reflectorCacheKey(Reflector $reflector): string { - return sprintf('type:%s#oid:%d', $reflector::class, spl_object_id($reflector)); + return sprintf('type:%s#oid:%d', get_class($reflector), spl_object_id($reflector)); } private function identifierToCacheKey(Identifier $identifier): string diff --git a/src/SourceLocator/Type/PhpInternalSourceLocator.php b/src/SourceLocator/Type/PhpInternalSourceLocator.php index 0332df35f..8a809d5e3 100644 --- a/src/SourceLocator/Type/PhpInternalSourceLocator.php +++ b/src/SourceLocator/Type/PhpInternalSourceLocator.php @@ -19,8 +19,10 @@ final class PhpInternalSourceLocator extends AbstractSourceLocator { - public function __construct(Locator $astLocator, private SourceStubber $stubber) + private SourceStubber $stubber; + public function __construct(Locator $astLocator, SourceStubber $stubber) { + $this->stubber = $stubber; parent::__construct($astLocator); } @@ -30,14 +32,14 @@ public function __construct(Locator $astLocator, private SourceStubber $stubber) * @throws InvalidArgumentException * @throws InvalidFileLocation */ - protected function createLocatedSource(Identifier $identifier): LocatedSource|null + protected function createLocatedSource(Identifier $identifier): ?\Roave\BetterReflection\SourceLocator\Located\LocatedSource { return $this->getClassSource($identifier) ?? $this->getFunctionSource($identifier) ?? $this->getConstantSource($identifier); } - private function getClassSource(Identifier $identifier): InternalLocatedSource|null + private function getClassSource(Identifier $identifier): ?\Roave\BetterReflection\SourceLocator\Located\InternalLocatedSource { if (! $identifier->isClass()) { return null; @@ -60,7 +62,7 @@ private function getClassSource(Identifier $identifier): InternalLocatedSource|n return $this->createLocatedSourceFromStubData($identifier, $this->stubber->generateClassStub($className), $aliasName); } - private function getFunctionSource(Identifier $identifier): InternalLocatedSource|null + private function getFunctionSource(Identifier $identifier): ?\Roave\BetterReflection\SourceLocator\Located\InternalLocatedSource { if (! $identifier->isFunction()) { return null; @@ -69,7 +71,7 @@ private function getFunctionSource(Identifier $identifier): InternalLocatedSourc return $this->createLocatedSourceFromStubData($identifier, $this->stubber->generateFunctionStub($identifier->getName())); } - private function getConstantSource(Identifier $identifier): InternalLocatedSource|null + private function getConstantSource(Identifier $identifier): ?\Roave\BetterReflection\SourceLocator\Located\InternalLocatedSource { if (! $identifier->isConstant()) { return null; @@ -78,7 +80,7 @@ private function getConstantSource(Identifier $identifier): InternalLocatedSourc return $this->createLocatedSourceFromStubData($identifier, $this->stubber->generateConstantStub($identifier->getName())); } - private function createLocatedSourceFromStubData(Identifier $identifier, StubData|null $stubData, string|null $aliasName = null): InternalLocatedSource|null + private function createLocatedSourceFromStubData(Identifier $identifier, ?\Roave\BetterReflection\SourceLocator\SourceStubber\StubData $stubData, ?string $aliasName = null): ?\Roave\BetterReflection\SourceLocator\Located\InternalLocatedSource { if ($stubData === null) { return null; diff --git a/src/SourceLocator/Type/SingleFileSourceLocator.php b/src/SourceLocator/Type/SingleFileSourceLocator.php index b0873b9f0..5fd356f70 100644 --- a/src/SourceLocator/Type/SingleFileSourceLocator.php +++ b/src/SourceLocator/Type/SingleFileSourceLocator.php @@ -23,13 +23,18 @@ */ class SingleFileSourceLocator extends AbstractSourceLocator { + /** + * @var non-empty-string + */ + private string $fileName; /** * @param non-empty-string $fileName * * @throws InvalidFileLocation */ - public function __construct(private string $fileName, Locator $astLocator) + public function __construct(string $fileName, Locator $astLocator) { + $this->fileName = $fileName; FileChecker::assertReadableFile($fileName); parent::__construct($astLocator); @@ -41,7 +46,7 @@ public function __construct(private string $fileName, Locator $astLocator) * @throws InvalidArgumentException * @throws InvalidFileLocation */ - protected function createLocatedSource(Identifier $identifier): LocatedSource|null + protected function createLocatedSource(Identifier $identifier): ?\Roave\BetterReflection\SourceLocator\Located\LocatedSource { return new LocatedSource( file_get_contents($this->fileName), diff --git a/src/SourceLocator/Type/SourceLocator.php b/src/SourceLocator/Type/SourceLocator.php index 372b51cd6..8754ae107 100644 --- a/src/SourceLocator/Type/SourceLocator.php +++ b/src/SourceLocator/Type/SourceLocator.php @@ -21,7 +21,7 @@ interface SourceLocator * locate the identifier, it should simply return null. If an exception is * thrown, it will break the Generic Reflector. */ - public function locateIdentifier(Reflector $reflector, Identifier $identifier): Reflection|null; + public function locateIdentifier(Reflector $reflector, Identifier $identifier): ?\Roave\BetterReflection\Reflection\Reflection; /** * Find all identifiers of a type diff --git a/src/SourceLocator/Type/StringSourceLocator.php b/src/SourceLocator/Type/StringSourceLocator.php index f1210ccdb..b6dad78bc 100644 --- a/src/SourceLocator/Type/StringSourceLocator.php +++ b/src/SourceLocator/Type/StringSourceLocator.php @@ -19,9 +19,14 @@ */ class StringSourceLocator extends AbstractSourceLocator { + /** + * @var non-empty-string + */ + private string $source; /** @param non-empty-string $source */ - public function __construct(private string $source, Locator $astLocator) + public function __construct(string $source, Locator $astLocator) { + $this->source = $source; parent::__construct($astLocator); } @@ -31,7 +36,7 @@ public function __construct(private string $source, Locator $astLocator) * @throws InvalidArgumentException * @throws InvalidFileLocation */ - protected function createLocatedSource(Identifier $identifier): LocatedSource|null + protected function createLocatedSource(Identifier $identifier): ?\Roave\BetterReflection\SourceLocator\Located\LocatedSource { return new LocatedSource( $this->source, diff --git a/src/Util/Exception/NoNodePosition.php b/src/Util/Exception/NoNodePosition.php index 9216a595d..b76e3752c 100644 --- a/src/Util/Exception/NoNodePosition.php +++ b/src/Util/Exception/NoNodePosition.php @@ -14,6 +14,6 @@ class NoNodePosition extends InvalidArgumentException { public static function fromNode(Node $node): self { - return new self(sprintf('%s doesn\'t contain position. Your %s is not configured properly', $node::class, Lexer::class)); + return new self(sprintf('%s doesn\'t contain position. Your %s is not configured properly', get_class($node), Lexer::class)); } } diff --git a/src/Util/FindReflectionOnLine.php b/src/Util/FindReflectionOnLine.php index 24c6cac9f..0cb7e8b30 100644 --- a/src/Util/FindReflectionOnLine.php +++ b/src/Util/FindReflectionOnLine.php @@ -23,8 +23,12 @@ final class FindReflectionOnLine { - public function __construct(private SourceLocator $sourceLocator, private Locator $astLocator) + private SourceLocator $sourceLocator; + private Locator $astLocator; + public function __construct(SourceLocator $sourceLocator, Locator $astLocator) { + $this->sourceLocator = $sourceLocator; + $this->astLocator = $astLocator; } /** @@ -37,8 +41,9 @@ public function __construct(private SourceLocator $sourceLocator, private Locato * @throws InvalidFileLocation * @throws ParseToAstFailure * @throws InvalidArgumentException + * @return \Roave\BetterReflection\Reflection\ReflectionMethod|\Roave\BetterReflection\Reflection\ReflectionClass|\Roave\BetterReflection\Reflection\ReflectionFunction|\Roave\BetterReflection\Reflection\ReflectionConstant|\Roave\BetterReflection\Reflection\Reflection|null */ - public function __invoke(string $filename, int $lineNumber): ReflectionMethod|ReflectionClass|ReflectionFunction|ReflectionConstant|Reflection|null + public function __invoke(string $filename, int $lineNumber) { $reflections = $this->computeReflections($filename); @@ -89,8 +94,9 @@ private function computeReflections(string $filename): array /** * Check to see if the line is within the boundaries of the reflection specified. + * @param \Roave\BetterReflection\Reflection\ReflectionClass|\Roave\BetterReflection\Reflection\ReflectionMethod|\Roave\BetterReflection\Reflection\ReflectionFunction|\Roave\BetterReflection\Reflection\ReflectionConstant $reflection */ - private function containsLine(ReflectionClass|ReflectionMethod|ReflectionFunction|ReflectionConstant $reflection, int $lineNumber): bool + private function containsLine($reflection, int $lineNumber): bool { return $lineNumber >= $reflection->getStartLine() && $lineNumber <= $reflection->getEndLine(); } diff --git a/src/Util/GetLastDocComment.php b/src/Util/GetLastDocComment.php index bb7cc8b33..1a9e17b29 100644 --- a/src/Util/GetLastDocComment.php +++ b/src/Util/GetLastDocComment.php @@ -16,7 +16,7 @@ final class GetLastDocComment * * @psalm-pure */ - public static function forNode(NodeAbstract $node): string|null + public static function forNode(NodeAbstract $node): ?string { /** @psalm-suppress ImpureMethodCall */ $docComment = $node->getDocComment(); diff --git a/test/unit/NodeCompiler/CompileNodeToValueTest.php b/test/unit/NodeCompiler/CompileNodeToValueTest.php index 64b6bea0c..bdafd6f5d 100644 --- a/test/unit/NodeCompiler/CompileNodeToValueTest.php +++ b/test/unit/NodeCompiler/CompileNodeToValueTest.php @@ -197,8 +197,11 @@ public static function nodeProvider(): array ]; } + /** + * @param mixed $expectedValue + */ #[DataProvider('nodeProvider')] - public function testVariousNodeCompilations(string $phpCode, mixed $expectedValue): void + public function testVariousNodeCompilations(string $phpCode, $expectedValue): void { $node = $this->parseCode($phpCode); @@ -477,7 +480,7 @@ class Bat { $reflector = new DefaultReflector(new StringSourceLocator($phpCode, $this->astLocator)); $classInfo = $reflector->reflectClass('Bat'); - self::assertSame('Foo', $classInfo->getConstant('QUX')?->getValue()); + self::assertSame('Foo', ($nullsafeVariable1 = $classInfo->getConstant('QUX')) ? $nullsafeVariable1->getValue() : null); } public function testClassConstantClassNameNamespaceResolution(): void @@ -494,7 +497,7 @@ class Bat { $reflector = new DefaultReflector(new StringSourceLocator($phpCode, $this->astLocator)); $classInfo = $reflector->reflectClass('Bar\Bat'); - self::assertSame('Bar\Foo', $classInfo->getConstant('QUX')?->getValue()); + self::assertSame('Bar\Foo', ($nullsafeVariable2 = $classInfo->getConstant('QUX')) ? $nullsafeVariable2->getValue() : null); } public function testClassConstantClassNameOutOfScopeResolution(): void @@ -511,7 +514,7 @@ class Bat { $reflector = new DefaultReflector(new StringSourceLocator($phpCode, $this->astLocator)); $classInfo = $reflector->reflectClass('Bar\Bat'); - self::assertSame('My\Awesome\Foo', $classInfo->getConstant('QUX')?->getValue()); + self::assertSame('My\Awesome\Foo', ($nullsafeVariable3 = $classInfo->getConstant('QUX')) ? $nullsafeVariable3->getValue() : null); } public function testClassConstantClassNameAliasedResolution(): void @@ -528,7 +531,7 @@ class Bat { $reflector = new DefaultReflector(new StringSourceLocator($phpCode, $this->astLocator)); $classInfo = $reflector->reflectClass('Bar\Bat'); - self::assertSame('My\Awesome\Foo', $classInfo->getConstant('QUX')?->getValue()); + self::assertSame('My\Awesome\Foo', ($nullsafeVariable4 = $classInfo->getConstant('QUX')) ? $nullsafeVariable4->getValue() : null); } public function testClassConstantResolutionFromParent(): void @@ -649,8 +652,11 @@ public static function enumCasePropertyProvider(): array ]; } + /** + * @param string|int $expectedPropertyValue + */ #[DataProvider('enumCasePropertyProvider')] - public function testEnumPropertyValue(string $propertyName, string|int $expectedPropertyValue): void + public function testEnumPropertyValue(string $propertyName, $expectedPropertyValue): void { $phpCode = sprintf( <<<'PHP' @@ -671,7 +677,7 @@ class Bat { new PhpInternalSourceLocator($this->astLocator, $this->sourceStubber), ])); $classInfo = $reflector->reflectClass('Bat'); - self::assertSame($expectedPropertyValue, $classInfo->getConstant('ONE_VALUE')?->getValue()); + self::assertSame($expectedPropertyValue, ($nullsafeVariable5 = $classInfo->getConstant('ONE_VALUE')) ? $nullsafeVariable5->getValue() : null); } public function testEnumPropertyValueThrowsExceptionWhenNoEnum(): void @@ -804,8 +810,11 @@ public static function magicConstantsWithoutNamespaceProvider(): array ]; } + /** + * @param mixed $expectedValue + */ #[DataProvider('magicConstantsWithoutNamespaceProvider')] - public function testMagicConstantsWithoutNamespace(string $constantName, mixed $expectedValue): void + public function testMagicConstantsWithoutNamespace(string $constantName, $expectedValue): void { $reflector = new DefaultReflector(new SingleFileSourceLocator(self::realPath(__DIR__ . '/../Fixture/MagicConstants.php'), $this->astLocator)); $constant = $reflector->reflectConstant($constantName); @@ -831,8 +840,11 @@ public static function magicConstantsInNamespaceProvider(): array ]; } + /** + * @param mixed $expectedValue + */ #[DataProvider('magicConstantsInNamespaceProvider')] - public function testMagicConstantsInNamespace(string $constantName, mixed $expectedValue): void + public function testMagicConstantsInNamespace(string $constantName, $expectedValue): void { $reflector = new DefaultReflector(new SingleFileSourceLocator(self::realPath(__DIR__ . '/../Fixture/MagicConstants.php'), $this->astLocator)); $constant = $reflector->reflectConstant('Roave\BetterReflectionTest\Fixture\\' . $constantName); @@ -858,9 +870,10 @@ public static function magicConstantsInTraitProvider(): array ]; } - /** @param non-empty-string $propertyName */ + /** @param non-empty-string $propertyName + * @param mixed $expectedValue */ #[DataProvider('magicConstantsInTraitProvider')] - public function testMagicConstantsInTrait(string $propertyName, mixed $expectedValue): void + public function testMagicConstantsInTrait(string $propertyName, $expectedValue): void { $reflector = new DefaultReflector(new SingleFileSourceLocator(self::realPath(__DIR__ . '/../Fixture/MagicConstants.php'), $this->astLocator)); $class = $reflector->reflectClass(MagicConstantsTrait::class); @@ -887,9 +900,10 @@ public static function magicConstantsInClassProvider(): array ]; } - /** @param non-empty-string $propertyName */ + /** @param non-empty-string $propertyName + * @param mixed $expectedValue */ #[DataProvider('magicConstantsInClassProvider')] - public function testMagicConstantsInClass(string $propertyName, mixed $expectedValue): void + public function testMagicConstantsInClass(string $propertyName, $expectedValue): void { $reflector = new DefaultReflector(new SingleFileSourceLocator(self::realPath(__DIR__ . '/../Fixture/MagicConstants.php'), $this->astLocator)); $class = $reflector->reflectClass(MagicConstantsClass::class); @@ -916,9 +930,10 @@ public static function magicConstantsInMethodProvider(): array ]; } - /** @param non-empty-string $parameterName */ + /** @param non-empty-string $parameterName + * @param mixed $expectedValue */ #[DataProvider('magicConstantsInMethodProvider')] - public function testMagicConstantsInMethod(string $parameterName, mixed $expectedValue): void + public function testMagicConstantsInMethod(string $parameterName, $expectedValue): void { $reflector = new DefaultReflector(new SingleFileSourceLocator(self::realPath(__DIR__ . '/../Fixture/MagicConstants.php'), $this->astLocator)); $class = $reflector->reflectClass(MagicConstantsClass::class); @@ -946,9 +961,10 @@ public static function magicConstantsInFunctionProvider(): array ]; } - /** @param non-empty-string $parameterName */ + /** @param non-empty-string $parameterName + * @param mixed $expectedValue */ #[DataProvider('magicConstantsInFunctionProvider')] - public function testMagicConstantsInFunction(string $parameterName, mixed $expectedValue): void + public function testMagicConstantsInFunction(string $parameterName, $expectedValue): void { $reflector = new DefaultReflector(new SingleFileSourceLocator(self::realPath(__DIR__ . '/../Fixture/MagicConstants.php'), $this->astLocator)); $function = $reflector->reflectFunction('Roave\BetterReflectionTest\Fixture\magicConstantsFunction'); @@ -1013,9 +1029,10 @@ public static function magicConstantsInPropertyHooks(): array ]; } - /** @param non-empty-string $propertyName */ + /** @param non-empty-string $propertyName + * @param mixed $expectedValue */ #[DataProvider('magicConstantsInPropertyHooks')] - public function testMagicConstantsInPropertyHooks(string $propertyName, mixed $expectedValue): void + public function testMagicConstantsInPropertyHooks(string $propertyName, $expectedValue): void { $reflector = new DefaultReflector(new SingleFileSourceLocator(self::realPath(__DIR__ . '/../Fixture/MagicConstantsInPropertyHooks.php'), $this->astLocator)); $class = $reflector->reflectClass(MagicConstantsInPropertyHooks::class); @@ -1027,8 +1044,9 @@ public function testMagicConstantsInPropertyHooks(string $propertyName, mixed $e self::assertSame($expectedValue, $getHookParameterAttribute->getArguments()[0]); } - /** @return non-empty-string */ - private static function realPath(string|false $path): string + /** @return non-empty-string + * @param string|false $path */ + private static function realPath($path): string { $realPath = realpath($path); diff --git a/test/unit/Reflection/Adapter/ReflectionAttributeTest.php b/test/unit/Reflection/Adapter/ReflectionAttributeTest.php index 81dc0a5e5..8f75b3d5b 100644 --- a/test/unit/Reflection/Adapter/ReflectionAttributeTest.php +++ b/test/unit/Reflection/Adapter/ReflectionAttributeTest.php @@ -63,9 +63,10 @@ public static function methodExpectationProvider(): array ]; } - /** @param list $args */ + /** @param list $args + * @param mixed $returnValue */ #[DataProvider('methodExpectationProvider')] - public function testAdapterMethods(string $methodName, string|null $expectedException, mixed $returnValue, array $args): void + public function testAdapterMethods(string $methodName, ?string $expectedException, $returnValue, array $args): void { $reflectionStub = $this->createMock(BetterReflectionAttribute::class); diff --git a/test/unit/Reflection/Adapter/ReflectionClassConstantTest.php b/test/unit/Reflection/Adapter/ReflectionClassConstantTest.php index 339a1d3ad..a21b28535 100644 --- a/test/unit/Reflection/Adapter/ReflectionClassConstantTest.php +++ b/test/unit/Reflection/Adapter/ReflectionClassConstantTest.php @@ -65,9 +65,10 @@ public static function methodExpectationProvider(): array ]; } - /** @param list $args */ + /** @param list $args + * @param mixed $returnValue */ #[DataProvider('methodExpectationProvider')] - public function testAdapterMethods(string $methodName, string|null $expectedException, mixed $returnValue, array $args): void + public function testAdapterMethods(string $methodName, ?string $expectedException, $returnValue, array $args): void { $reflectionStub = $this->createMock(BetterReflectionClassConstant::class); @@ -98,8 +99,11 @@ public static function dataAdapterMethodsForEnumCase(): array ]; } + /** + * @param mixed $expectedValue + */ #[DataProvider('dataAdapterMethodsForEnumCase')] - public function testAdapterMethodsForEnumCase(string $methodName, mixed $expectedValue): void + public function testAdapterMethodsForEnumCase(string $methodName, $expectedValue): void { $reflectionClassConstantAdapter = new ReflectionClassConstantAdapter($this->createMock(BetterReflectionEnumCase::class)); @@ -137,7 +141,7 @@ public function testGetAttributes(): void ->willReturn($betterReflectionAttributes); $reflectionClassConstantAdapter = new ReflectionClassConstantAdapter($betterReflectionClassConstant); - $attributes = $reflectionClassConstantAdapter->getAttributes(); + $attributes = method_exists($reflectionClassConstantAdapter, 'getAttributes') ? $reflectionClassConstantAdapter->getAttributes() : []; self::assertCount(2, $attributes); self::assertSame('SomeAttribute', $attributes[0]->getName()); @@ -172,7 +176,7 @@ public function testGetAttributesWithName(): void ->willReturn($betterReflectionAttributes); $reflectionClassAdapter = new ReflectionClassConstantAdapter($betterReflectionClassConstant); - $attributes = $reflectionClassAdapter->getAttributes($someAttributeClassName); + $attributes = method_exists($reflectionClassAdapter, 'getAttributes') ? $reflectionClassAdapter->getAttributes($someAttributeClassName) : []; self::assertCount(1, $attributes); self::assertSame($someAttributeClassName, $attributes[0]->getName()); @@ -274,9 +278,9 @@ public function testGetAttributesWithInstance(): void $reflectionClassConstantAdapter = new ReflectionClassConstantAdapter($betterReflectionClassConstant); - self::assertCount(1, $reflectionClassConstantAdapter->getAttributes($className, ReflectionAttributeAdapter::IS_INSTANCEOF)); - self::assertCount(2, $reflectionClassConstantAdapter->getAttributes($parentClassName, ReflectionAttributeAdapter::IS_INSTANCEOF)); - self::assertCount(2, $reflectionClassConstantAdapter->getAttributes($interfaceName, ReflectionAttributeAdapter::IS_INSTANCEOF)); + self::assertCount(1, method_exists($reflectionClassConstantAdapter, 'getAttributes') ? $reflectionClassConstantAdapter->getAttributes($className, ReflectionAttributeAdapter::IS_INSTANCEOF) : []); + self::assertCount(2, method_exists($reflectionClassConstantAdapter, 'getAttributes') ? $reflectionClassConstantAdapter->getAttributes($parentClassName, ReflectionAttributeAdapter::IS_INSTANCEOF) : []); + self::assertCount(2, method_exists($reflectionClassConstantAdapter, 'getAttributes') ? $reflectionClassConstantAdapter->getAttributes($interfaceName, ReflectionAttributeAdapter::IS_INSTANCEOF) : []); } public function testGetAttributesThrowsExceptionForInvalidFlags(): void @@ -285,7 +289,7 @@ public function testGetAttributesThrowsExceptionForInvalidFlags(): void $reflectionClassConstantAdapter = new ReflectionClassConstantAdapter($betterReflectionClassConstant); $this->expectException(Error::class); - $reflectionClassConstantAdapter->getAttributes(null, 123); + method_exists($reflectionClassConstantAdapter, 'getAttributes') ? $reflectionClassConstantAdapter->getAttributes(null, 123) : []; } public function testIsEnumCaseWithClassConstant(): void diff --git a/test/unit/Reflection/Adapter/ReflectionClassTest.php b/test/unit/Reflection/Adapter/ReflectionClassTest.php index d4df19417..e2b388017 100644 --- a/test/unit/Reflection/Adapter/ReflectionClassTest.php +++ b/test/unit/Reflection/Adapter/ReflectionClassTest.php @@ -110,36 +110,27 @@ public static function methodExpectationProvider(): array ]; } - /** @param list $args */ + /** @param list $args + * @param mixed $returnValue + * @param mixed $expectedReturnValue */ #[DataProvider('methodExpectationProvider')] - public function testAdapterMethods( - string $methodName, - array $args, - mixed $returnValue, - string|null $expectedException, - mixed $expectedReturnValue, - ): void { + public function testAdapterMethods(string $methodName, array $args, $returnValue, ?string $expectedException, $expectedReturnValue) : void + { $reflectionStub = $this->createMock(BetterReflectionClass::class); - if ($expectedException === null) { $reflectionStub->expects($this->once()) ->method($methodName) ->with(...$args) ->willReturn($returnValue); } - $adapter = new ReflectionClassAdapter($reflectionStub); - if ($expectedException !== null) { $this->expectException($expectedException); } - $actualReturnValue = $adapter->{$methodName}(...$args); - if ($expectedReturnValue === null) { return; } - self::assertSame($expectedReturnValue, $actualReturnValue); } @@ -998,7 +989,7 @@ public function testGetAttributes(): void ->willReturn($betterReflectionAttributes); $reflectionClassAdapter = new ReflectionClassAdapter($betterReflectionClass); - $attributes = $reflectionClassAdapter->getAttributes(); + $attributes = method_exists($reflectionClassAdapter, 'getAttributes') ? $reflectionClassAdapter->getAttributes() : []; self::assertCount(2, $attributes); self::assertSame('SomeAttribute', $attributes[0]->getName()); @@ -1033,7 +1024,7 @@ public function testGetAttributesWithName(): void ->willReturn($betterReflectionAttributes); $reflectionClassAdapter = new ReflectionClassAdapter($betterReflectionClass); - $attributes = $reflectionClassAdapter->getAttributes($someAttributeClassName); + $attributes = method_exists($reflectionClassAdapter, 'getAttributes') ? $reflectionClassAdapter->getAttributes($someAttributeClassName) : []; self::assertCount(1, $attributes); self::assertSame($someAttributeClassName, $attributes[0]->getName()); @@ -1135,9 +1126,9 @@ public function testGetAttributesWithInstance(): void $reflectionClassAdapter = new ReflectionClassAdapter($betterReflectionClass); - self::assertCount(1, $reflectionClassAdapter->getAttributes($className, ReflectionAttributeAdapter::IS_INSTANCEOF)); - self::assertCount(2, $reflectionClassAdapter->getAttributes($parentClassName, ReflectionAttributeAdapter::IS_INSTANCEOF)); - self::assertCount(2, $reflectionClassAdapter->getAttributes($interfaceName, ReflectionAttributeAdapter::IS_INSTANCEOF)); + self::assertCount(1, method_exists($reflectionClassAdapter, 'getAttributes') ? $reflectionClassAdapter->getAttributes($className, ReflectionAttributeAdapter::IS_INSTANCEOF) : []); + self::assertCount(2, method_exists($reflectionClassAdapter, 'getAttributes') ? $reflectionClassAdapter->getAttributes($parentClassName, ReflectionAttributeAdapter::IS_INSTANCEOF) : []); + self::assertCount(2, method_exists($reflectionClassAdapter, 'getAttributes') ? $reflectionClassAdapter->getAttributes($interfaceName, ReflectionAttributeAdapter::IS_INSTANCEOF) : []); } public function testGetAttributesThrowsExceptionForInvalidFlags(): void @@ -1146,7 +1137,7 @@ public function testGetAttributesThrowsExceptionForInvalidFlags(): void $reflectionClassAdapter = new ReflectionClassAdapter($betterReflectionClass); $this->expectException(Error::class); - $reflectionClassAdapter->getAttributes(null, 123); + method_exists($reflectionClassAdapter, 'getAttributes') ? $reflectionClassAdapter->getAttributes(null, 123) : []; } public function testHasConstantWithEnumCase(): void diff --git a/test/unit/Reflection/Adapter/ReflectionEnumBackedCaseTest.php b/test/unit/Reflection/Adapter/ReflectionEnumBackedCaseTest.php index 0f2fd2c32..4cfc42118 100644 --- a/test/unit/Reflection/Adapter/ReflectionEnumBackedCaseTest.php +++ b/test/unit/Reflection/Adapter/ReflectionEnumBackedCaseTest.php @@ -70,9 +70,10 @@ public static function methodExpectationProvider(): array ]; } - /** @param list $args */ + /** @param list $args + * @param mixed $returnValue */ #[DataProvider('methodExpectationProvider')] - public function testAdapterMethods(string $methodName, string|null $expectedException, mixed $returnValue, array $args): void + public function testAdapterMethods(string $methodName, ?string $expectedException, $returnValue, array $args): void { $reflectionStub = $this->createMock(BetterReflectionEnumCase::class); @@ -158,7 +159,7 @@ public function testGetAttributes(): void ->willReturn($betterReflectionAttributes); $reflectionEnumBackedCaseAdapter = new ReflectionEnumBackedCaseAdapter($betterReflectionEnumCase); - $attributes = $reflectionEnumBackedCaseAdapter->getAttributes(); + $attributes = method_exists($reflectionEnumBackedCaseAdapter, 'getAttributes') ? $reflectionEnumBackedCaseAdapter->getAttributes() : []; self::assertCount(2, $attributes); self::assertSame('SomeAttribute', $attributes[0]->getName()); @@ -193,7 +194,7 @@ public function testGetAttributesWithName(): void ->willReturn($betterReflectionAttributes); $reflectionEnumBackedCaseAdapter = new ReflectionEnumBackedCaseAdapter($betterReflectionEnumCase); - $attributes = $reflectionEnumBackedCaseAdapter->getAttributes($someAttributeClassName); + $attributes = method_exists($reflectionEnumBackedCaseAdapter, 'getAttributes') ? $reflectionEnumBackedCaseAdapter->getAttributes($someAttributeClassName) : []; self::assertCount(1, $attributes); self::assertSame($someAttributeClassName, $attributes[0]->getName()); @@ -295,9 +296,9 @@ public function testGetAttributesWithInstance(): void $reflectionEnumBackedCaseAdapter = new ReflectionEnumBackedCaseAdapter($betterReflectionEnumCase); - self::assertCount(1, $reflectionEnumBackedCaseAdapter->getAttributes($className, ReflectionAttributeAdapter::IS_INSTANCEOF)); - self::assertCount(2, $reflectionEnumBackedCaseAdapter->getAttributes($parentClassName, ReflectionAttributeAdapter::IS_INSTANCEOF)); - self::assertCount(2, $reflectionEnumBackedCaseAdapter->getAttributes($interfaceName, ReflectionAttributeAdapter::IS_INSTANCEOF)); + self::assertCount(1, method_exists($reflectionEnumBackedCaseAdapter, 'getAttributes') ? $reflectionEnumBackedCaseAdapter->getAttributes($className, ReflectionAttributeAdapter::IS_INSTANCEOF) : []); + self::assertCount(2, method_exists($reflectionEnumBackedCaseAdapter, 'getAttributes') ? $reflectionEnumBackedCaseAdapter->getAttributes($parentClassName, ReflectionAttributeAdapter::IS_INSTANCEOF) : []); + self::assertCount(2, method_exists($reflectionEnumBackedCaseAdapter, 'getAttributes') ? $reflectionEnumBackedCaseAdapter->getAttributes($interfaceName, ReflectionAttributeAdapter::IS_INSTANCEOF) : []); } public function testGetAttributesThrowsExceptionForInvalidFlags(): void @@ -306,7 +307,7 @@ public function testGetAttributesThrowsExceptionForInvalidFlags(): void $reflectionEnumBackedCaseAdapter = new ReflectionEnumBackedCaseAdapter($betterReflectionEnumCase); $this->expectException(Error::class); - $reflectionEnumBackedCaseAdapter->getAttributes(null, 123); + method_exists($reflectionEnumBackedCaseAdapter, 'getAttributes') ? $reflectionEnumBackedCaseAdapter->getAttributes(null, 123) : []; } public function testIsFinal(): void diff --git a/test/unit/Reflection/Adapter/ReflectionEnumTest.php b/test/unit/Reflection/Adapter/ReflectionEnumTest.php index 3fa36b2c8..fbcec4728 100644 --- a/test/unit/Reflection/Adapter/ReflectionEnumTest.php +++ b/test/unit/Reflection/Adapter/ReflectionEnumTest.php @@ -134,36 +134,27 @@ public static function methodExpectationProvider(): array ]; } - /** @param list $args */ + /** @param list $args + * @param mixed $returnValue + * @param mixed $expectedReturnValue */ #[DataProvider('methodExpectationProvider')] - public function testAdapterMethods( - string $methodName, - array $args, - mixed $returnValue, - string|null $expectedException, - mixed $expectedReturnValue, - ): void { + public function testAdapterMethods(string $methodName, array $args, $returnValue, ?string $expectedException, $expectedReturnValue) : void + { $reflectionStub = $this->createMock(BetterReflectionEnum::class); - if ($expectedException === null) { $reflectionStub->expects($this->once()) ->method($methodName) ->with(...$args) ->willReturn($returnValue); } - $adapter = new ReflectionEnumAdapter($reflectionStub); - if ($expectedException !== null) { $this->expectException($expectedException); } - $actualReturnValue = $adapter->{$methodName}(...$args); - if ($expectedReturnValue === null) { return; } - self::assertSame($expectedReturnValue, $actualReturnValue); } @@ -512,7 +503,7 @@ public function testGetAttributes(): void ->willReturn($betterReflectionAttributes); $reflectionEnumAdapter = new ReflectionEnumAdapter($betterReflectionEnum); - $attributes = $reflectionEnumAdapter->getAttributes(); + $attributes = method_exists($reflectionEnumAdapter, 'getAttributes') ? $reflectionEnumAdapter->getAttributes() : []; self::assertCount(2, $attributes); self::assertSame('SomeAttribute', $attributes[0]->getName()); @@ -547,7 +538,7 @@ public function testGetAttributesWithName(): void ->willReturn($betterReflectionAttributes); $reflectionEnumAdapter = new ReflectionEnumAdapter($betterReflectionEnum); - $attributes = $reflectionEnumAdapter->getAttributes($someAttributeClassName); + $attributes = method_exists($reflectionEnumAdapter, 'getAttributes') ? $reflectionEnumAdapter->getAttributes($someAttributeClassName) : []; self::assertCount(1, $attributes); self::assertSame($someAttributeClassName, $attributes[0]->getName()); @@ -649,9 +640,9 @@ public function testGetAttributesWithInstance(): void $reflectionEnumAdapter = new ReflectionEnumAdapter($betterReflectionEnum); - self::assertCount(1, $reflectionEnumAdapter->getAttributes($className, ReflectionAttributeAdapter::IS_INSTANCEOF)); - self::assertCount(2, $reflectionEnumAdapter->getAttributes($parentClassName, ReflectionAttributeAdapter::IS_INSTANCEOF)); - self::assertCount(2, $reflectionEnumAdapter->getAttributes($interfaceName, ReflectionAttributeAdapter::IS_INSTANCEOF)); + self::assertCount(1, method_exists($reflectionEnumAdapter, 'getAttributes') ? $reflectionEnumAdapter->getAttributes($className, ReflectionAttributeAdapter::IS_INSTANCEOF) : []); + self::assertCount(2, method_exists($reflectionEnumAdapter, 'getAttributes') ? $reflectionEnumAdapter->getAttributes($parentClassName, ReflectionAttributeAdapter::IS_INSTANCEOF) : []); + self::assertCount(2, method_exists($reflectionEnumAdapter, 'getAttributes') ? $reflectionEnumAdapter->getAttributes($interfaceName, ReflectionAttributeAdapter::IS_INSTANCEOF) : []); } public function testGetAttributesThrowsExceptionForInvalidFlags(): void @@ -660,7 +651,7 @@ public function testGetAttributesThrowsExceptionForInvalidFlags(): void $reflectionEnumAdapter = new ReflectionEnumAdapter($betterReflectionEnum); $this->expectException(Error::class); - $reflectionEnumAdapter->getAttributes(null, 123); + method_exists($reflectionEnumAdapter, 'getAttributes') ? $reflectionEnumAdapter->getAttributes(null, 123) : []; } public function testHasCaseReturnsFalseWhenCaseNameIsEmpty(): void diff --git a/test/unit/Reflection/Adapter/ReflectionEnumUnitCaseTest.php b/test/unit/Reflection/Adapter/ReflectionEnumUnitCaseTest.php index a175443a0..4faeb72a3 100644 --- a/test/unit/Reflection/Adapter/ReflectionEnumUnitCaseTest.php +++ b/test/unit/Reflection/Adapter/ReflectionEnumUnitCaseTest.php @@ -70,9 +70,10 @@ public static function methodExpectationProvider(): array ]; } - /** @param list $args */ + /** @param list $args + * @param mixed $returnValue */ #[DataProvider('methodExpectationProvider')] - public function testAdapterMethods(string $methodName, string|null $expectedException, mixed $returnValue, array $args): void + public function testAdapterMethods(string $methodName, ?string $expectedException, $returnValue, array $args): void { $reflectionStub = $this->createMock(BetterReflectionEnumCase::class); @@ -158,7 +159,7 @@ public function testGetAttributes(): void ->willReturn($betterReflectionAttributes); $reflectionEnumUnitCaseAdapter = new ReflectionEnumUnitCaseAdapter($betterReflectionEnumCase); - $attributes = $reflectionEnumUnitCaseAdapter->getAttributes(); + $attributes = method_exists($reflectionEnumUnitCaseAdapter, 'getAttributes') ? $reflectionEnumUnitCaseAdapter->getAttributes() : []; self::assertCount(2, $attributes); self::assertSame('SomeAttribute', $attributes[0]->getName()); @@ -193,7 +194,7 @@ public function testGetAttributesWithName(): void ->willReturn($betterReflectionAttributes); $reflectionEnumUnitCaseAdapter = new ReflectionEnumUnitCaseAdapter($betterReflectionEnumCase); - $attributes = $reflectionEnumUnitCaseAdapter->getAttributes($someAttributeClassName); + $attributes = method_exists($reflectionEnumUnitCaseAdapter, 'getAttributes') ? $reflectionEnumUnitCaseAdapter->getAttributes($someAttributeClassName) : []; self::assertCount(1, $attributes); self::assertSame($someAttributeClassName, $attributes[0]->getName()); @@ -295,9 +296,9 @@ public function testGetAttributesWithInstance(): void $reflectionEnumUnitCaseAdapter = new ReflectionEnumUnitCaseAdapter($betterReflectionEnumCase); - self::assertCount(1, $reflectionEnumUnitCaseAdapter->getAttributes($className, ReflectionAttributeAdapter::IS_INSTANCEOF)); - self::assertCount(2, $reflectionEnumUnitCaseAdapter->getAttributes($parentClassName, ReflectionAttributeAdapter::IS_INSTANCEOF)); - self::assertCount(2, $reflectionEnumUnitCaseAdapter->getAttributes($interfaceName, ReflectionAttributeAdapter::IS_INSTANCEOF)); + self::assertCount(1, method_exists($reflectionEnumUnitCaseAdapter, 'getAttributes') ? $reflectionEnumUnitCaseAdapter->getAttributes($className, ReflectionAttributeAdapter::IS_INSTANCEOF) : []); + self::assertCount(2, method_exists($reflectionEnumUnitCaseAdapter, 'getAttributes') ? $reflectionEnumUnitCaseAdapter->getAttributes($parentClassName, ReflectionAttributeAdapter::IS_INSTANCEOF) : []); + self::assertCount(2, method_exists($reflectionEnumUnitCaseAdapter, 'getAttributes') ? $reflectionEnumUnitCaseAdapter->getAttributes($interfaceName, ReflectionAttributeAdapter::IS_INSTANCEOF) : []); } public function testGetAttributesThrowsExceptionForInvalidFlags(): void @@ -306,7 +307,7 @@ public function testGetAttributesThrowsExceptionForInvalidFlags(): void $reflectionEnumUnitCaseAdapter = new ReflectionEnumUnitCaseAdapter($betterReflectionEnumCase); $this->expectException(Error::class); - $reflectionEnumUnitCaseAdapter->getAttributes(null, 123); + method_exists($reflectionEnumUnitCaseAdapter, 'getAttributes') ? $reflectionEnumUnitCaseAdapter->getAttributes(null, 123) : []; } public function testIsFinal(): void diff --git a/test/unit/Reflection/Adapter/ReflectionFunctionTest.php b/test/unit/Reflection/Adapter/ReflectionFunctionTest.php index cf642132b..3a84e9311 100644 --- a/test/unit/Reflection/Adapter/ReflectionFunctionTest.php +++ b/test/unit/Reflection/Adapter/ReflectionFunctionTest.php @@ -96,36 +96,27 @@ public static function methodExpectationProvider(): array ]; } - /** @param list $args */ + /** @param list $args + * @param mixed $returnValue + * @param mixed $expectedReturnValue */ #[DataProvider('methodExpectationProvider')] - public function testAdapterMethods( - string $methodName, - array $args, - mixed $returnValue, - string|null $expectedException, - mixed $expectedReturnValue, - ): void { + public function testAdapterMethods(string $methodName, array $args, $returnValue, ?string $expectedException, $expectedReturnValue) : void + { $reflectionStub = $this->createMock(BetterReflectionFunction::class); - if ($expectedException === null) { $reflectionStub->expects($this->once()) ->method($methodName) ->with(...$args) ->willReturn($returnValue); } - $adapter = new ReflectionFunctionAdapter($reflectionStub); - if ($expectedException !== null) { $this->expectException($expectedException); } - $actualReturnValue = $adapter->{$methodName}(...$args); - if ($expectedReturnValue === null) { return; } - self::assertSame($expectedReturnValue, $actualReturnValue); } @@ -265,7 +256,7 @@ public function testGetAttributes(): void ->willReturn($betterReflectionAttributes); $reflectionFunctionAdapter = new ReflectionFunctionAdapter($betterReflectionFunction); - $attributes = $reflectionFunctionAdapter->getAttributes(); + $attributes = method_exists($reflectionFunctionAdapter, 'getAttributes') ? $reflectionFunctionAdapter->getAttributes() : []; self::assertCount(2, $attributes); self::assertSame('SomeAttribute', $attributes[0]->getName()); @@ -300,7 +291,7 @@ public function testGetAttributesWithName(): void ->willReturn($betterReflectionAttributes); $reflectionFunctionAdapter = new ReflectionFunctionAdapter($betterReflectionFunction); - $attributes = $reflectionFunctionAdapter->getAttributes($someAttributeClassName); + $attributes = method_exists($reflectionFunctionAdapter, 'getAttributes') ? $reflectionFunctionAdapter->getAttributes($someAttributeClassName) : []; self::assertCount(1, $attributes); self::assertSame($someAttributeClassName, $attributes[0]->getName()); @@ -402,9 +393,9 @@ public function testGetAttributesWithInstance(): void $reflectionFunctionAdapter = new ReflectionFunctionAdapter($betterReflectionFunction); - self::assertCount(1, $reflectionFunctionAdapter->getAttributes($className, ReflectionAttributeAdapter::IS_INSTANCEOF)); - self::assertCount(2, $reflectionFunctionAdapter->getAttributes($parentClassName, ReflectionAttributeAdapter::IS_INSTANCEOF)); - self::assertCount(2, $reflectionFunctionAdapter->getAttributes($interfaceName, ReflectionAttributeAdapter::IS_INSTANCEOF)); + self::assertCount(1, method_exists($reflectionFunctionAdapter, 'getAttributes') ? $reflectionFunctionAdapter->getAttributes($className, ReflectionAttributeAdapter::IS_INSTANCEOF) : []); + self::assertCount(2, method_exists($reflectionFunctionAdapter, 'getAttributes') ? $reflectionFunctionAdapter->getAttributes($parentClassName, ReflectionAttributeAdapter::IS_INSTANCEOF) : []); + self::assertCount(2, method_exists($reflectionFunctionAdapter, 'getAttributes') ? $reflectionFunctionAdapter->getAttributes($interfaceName, ReflectionAttributeAdapter::IS_INSTANCEOF) : []); } public function testGetAttributesThrowsExceptionForInvalidFlags(): void @@ -413,7 +404,7 @@ public function testGetAttributesThrowsExceptionForInvalidFlags(): void $reflectionFunctionAdapter = new ReflectionFunctionAdapter($betterReflectionFunction); $this->expectException(Error::class); - $reflectionFunctionAdapter->getAttributes(null, 123); + method_exists($reflectionFunctionAdapter, 'getAttributes') ? $reflectionFunctionAdapter->getAttributes(null, 123) : []; } public function testPropertyName(): void diff --git a/test/unit/Reflection/Adapter/ReflectionIntersectionTypeTest.php b/test/unit/Reflection/Adapter/ReflectionIntersectionTypeTest.php index 0cb2f62c3..061432f19 100644 --- a/test/unit/Reflection/Adapter/ReflectionIntersectionTypeTest.php +++ b/test/unit/Reflection/Adapter/ReflectionIntersectionTypeTest.php @@ -48,9 +48,10 @@ public static function methodExpectationProvider(): array ]; } - /** @param list $args */ + /** @param list $args + * @param mixed $returnValue */ #[DataProvider('methodExpectationProvider')] - public function testAdapterMethods(string $methodName, string|null $expectedException, mixed $returnValue, array $args): void + public function testAdapterMethods(string $methodName, ?string $expectedException, $returnValue, array $args): void { $reflectionStub = $this->createMock(BetterReflectionIntersectionType::class); diff --git a/test/unit/Reflection/Adapter/ReflectionMethodTest.php b/test/unit/Reflection/Adapter/ReflectionMethodTest.php index b1506c53f..f831fdd5b 100644 --- a/test/unit/Reflection/Adapter/ReflectionMethodTest.php +++ b/test/unit/Reflection/Adapter/ReflectionMethodTest.php @@ -105,36 +105,27 @@ public static function methodExpectationProvider(): array ]; } - /** @param list $args */ + /** @param list $args + * @param mixed $returnValue + * @param mixed $expectedReturnValue */ #[DataProvider('methodExpectationProvider')] - public function testAdapterMethods( - string $methodName, - array $args, - mixed $returnValue, - string|null $expectedException, - mixed $expectedReturnValue, - ): void { + public function testAdapterMethods(string $methodName, array $args, $returnValue, ?string $expectedException, $expectedReturnValue) : void + { $reflectionStub = $this->createMock(BetterReflectionMethod::class); - if ($expectedException === null) { $reflectionStub->expects($this->once()) ->method($methodName) ->with(...$args) ->willReturn($returnValue); } - $adapter = new ReflectionMethodAdapter($reflectionStub); - if ($expectedException !== null) { $this->expectException($expectedException); } - $actualReturnValue = $adapter->{$methodName}(...$args); - if ($expectedReturnValue === null) { return; } - self::assertSame($expectedReturnValue, $actualReturnValue); } @@ -373,7 +364,7 @@ public function testGetAttributes(): void ->willReturn($betterReflectionAttributes); $reflectionMethodAdapter = new ReflectionMethodAdapter($betterReflectionMethod); - $attributes = $reflectionMethodAdapter->getAttributes(); + $attributes = method_exists($reflectionMethodAdapter, 'getAttributes') ? $reflectionMethodAdapter->getAttributes() : []; self::assertCount(2, $attributes); self::assertSame('SomeAttribute', $attributes[0]->getName()); @@ -408,7 +399,7 @@ public function testGetAttributesWithName(): void ->willReturn($betterReflectionAttributes); $reflectionMethodAdapter = new ReflectionMethodAdapter($betterReflectionMethod); - $attributes = $reflectionMethodAdapter->getAttributes($someAttributeClassName); + $attributes = method_exists($reflectionMethodAdapter, 'getAttributes') ? $reflectionMethodAdapter->getAttributes($someAttributeClassName) : []; self::assertCount(1, $attributes); self::assertSame($someAttributeClassName, $attributes[0]->getName()); @@ -510,9 +501,9 @@ public function testGetAttributesWithInstance(): void $reflectionMethodAdapter = new ReflectionMethodAdapter($betterReflectionMethod); - self::assertCount(1, $reflectionMethodAdapter->getAttributes($className, ReflectionAttributeAdapter::IS_INSTANCEOF)); - self::assertCount(2, $reflectionMethodAdapter->getAttributes($parentClassName, ReflectionAttributeAdapter::IS_INSTANCEOF)); - self::assertCount(2, $reflectionMethodAdapter->getAttributes($interfaceName, ReflectionAttributeAdapter::IS_INSTANCEOF)); + self::assertCount(1, method_exists($reflectionMethodAdapter, 'getAttributes') ? $reflectionMethodAdapter->getAttributes($className, ReflectionAttributeAdapter::IS_INSTANCEOF) : []); + self::assertCount(2, method_exists($reflectionMethodAdapter, 'getAttributes') ? $reflectionMethodAdapter->getAttributes($parentClassName, ReflectionAttributeAdapter::IS_INSTANCEOF) : []); + self::assertCount(2, method_exists($reflectionMethodAdapter, 'getAttributes') ? $reflectionMethodAdapter->getAttributes($interfaceName, ReflectionAttributeAdapter::IS_INSTANCEOF) : []); } public function testGetAttributesThrowsExceptionForInvalidFlags(): void @@ -521,7 +512,7 @@ public function testGetAttributesThrowsExceptionForInvalidFlags(): void $reflectionMethodAdapter = new ReflectionMethodAdapter($betterReflectionMethod); $this->expectException(Error::class); - $reflectionMethodAdapter->getAttributes(null, 123); + method_exists($reflectionMethodAdapter, 'getAttributes') ? $reflectionMethodAdapter->getAttributes(null, 123) : []; } public function testPropertyName(): void diff --git a/test/unit/Reflection/Adapter/ReflectionNamedTypeTest.php b/test/unit/Reflection/Adapter/ReflectionNamedTypeTest.php index 8a714d0ec..1ea2a584a 100644 --- a/test/unit/Reflection/Adapter/ReflectionNamedTypeTest.php +++ b/test/unit/Reflection/Adapter/ReflectionNamedTypeTest.php @@ -89,9 +89,10 @@ public static function methodExpectationProvider(): array ]; } - /** @param list $args */ + /** @param list $args + * @param mixed $returnValue */ #[DataProvider('methodExpectationProvider')] - public function testAdapterMethods(string $methodName, string|null $expectedException, mixed $returnValue, array $args): void + public function testAdapterMethods(string $methodName, ?string $expectedException, $returnValue, array $args): void { $reflectionStub = $this->createMock(BetterReflectionNamedType::class); diff --git a/test/unit/Reflection/Adapter/ReflectionObjectTest.php b/test/unit/Reflection/Adapter/ReflectionObjectTest.php index e4ab3450b..37c4b2590 100644 --- a/test/unit/Reflection/Adapter/ReflectionObjectTest.php +++ b/test/unit/Reflection/Adapter/ReflectionObjectTest.php @@ -110,36 +110,27 @@ public static function methodExpectationProvider(): array ]; } - /** @param list $args */ + /** @param list $args + * @param mixed $returnValue + * @param mixed $expectedReturnValue */ #[DataProvider('methodExpectationProvider')] - public function testAdapterMethods( - string $methodName, - array $args, - mixed $returnValue, - string|null $expectedException, - mixed $expectedReturnValue, - ): void { + public function testAdapterMethods(string $methodName, array $args, $returnValue, ?string $expectedException, $expectedReturnValue) : void + { $reflectionStub = $this->createMock(BetterReflectionObject::class); - if ($expectedException === null) { $reflectionStub->expects($this->once()) ->method($methodName) ->with(...$args) ->willReturn($returnValue); } - $adapter = new ReflectionObjectAdapter($reflectionStub); - if ($expectedException !== null) { $this->expectException($expectedException); } - $actualReturnValue = $adapter->{$methodName}(...$args); - if ($expectedReturnValue === null) { return; } - self::assertSame($expectedReturnValue, $actualReturnValue); } @@ -901,7 +892,7 @@ public function testGetAttributes(): void ->willReturn($betterReflectionAttributes); $reflectionObjectAdapter = new ReflectionObjectAdapter($betterReflectionObject); - $attributes = $reflectionObjectAdapter->getAttributes(); + $attributes = method_exists($reflectionObjectAdapter, 'getAttributes') ? $reflectionObjectAdapter->getAttributes() : []; self::assertCount(2, $attributes); self::assertSame('SomeAttribute', $attributes[0]->getName()); @@ -944,7 +935,7 @@ public function testGetAttributesWithName(): void $reflectionObjectAdapter = new ReflectionObjectAdapter($betterReflectionObject); - $attributes = $reflectionObjectAdapter->getAttributes($someAttributeClassName); + $attributes = method_exists($reflectionObjectAdapter, 'getAttributes') ? $reflectionObjectAdapter->getAttributes($someAttributeClassName) : []; self::assertCount(1, $attributes); self::assertSame($someAttributeClassName, $attributes[0]->getName()); @@ -1053,9 +1044,9 @@ public function testGetAttributesWithInstance(): void $reflectionObjectAdapter = new ReflectionObjectAdapter($betterReflectionObject); - self::assertCount(1, $reflectionObjectAdapter->getAttributes($className, ReflectionAttributeAdapter::IS_INSTANCEOF)); - self::assertCount(2, $reflectionObjectAdapter->getAttributes($parentClassName, ReflectionAttributeAdapter::IS_INSTANCEOF)); - self::assertCount(2, $reflectionObjectAdapter->getAttributes($interfaceName, ReflectionAttributeAdapter::IS_INSTANCEOF)); + self::assertCount(1, method_exists($reflectionObjectAdapter, 'getAttributes') ? $reflectionObjectAdapter->getAttributes($className, ReflectionAttributeAdapter::IS_INSTANCEOF) : []); + self::assertCount(2, method_exists($reflectionObjectAdapter, 'getAttributes') ? $reflectionObjectAdapter->getAttributes($parentClassName, ReflectionAttributeAdapter::IS_INSTANCEOF) : []); + self::assertCount(2, method_exists($reflectionObjectAdapter, 'getAttributes') ? $reflectionObjectAdapter->getAttributes($interfaceName, ReflectionAttributeAdapter::IS_INSTANCEOF) : []); } public function testGetAttributesThrowsExceptionForInvalidFlags(): void @@ -1064,7 +1055,7 @@ public function testGetAttributesThrowsExceptionForInvalidFlags(): void $reflectionObjectAdapter = new ReflectionObjectAdapter($betterReflectionObject); $this->expectException(Error::class); - $reflectionObjectAdapter->getAttributes(null, 123); + method_exists($reflectionObjectAdapter, 'getAttributes') ? $reflectionObjectAdapter->getAttributes(null, 123) : []; } public function testGetTraits(): void diff --git a/test/unit/Reflection/Adapter/ReflectionParameterTest.php b/test/unit/Reflection/Adapter/ReflectionParameterTest.php index 80bd575d8..a0f2c7336 100644 --- a/test/unit/Reflection/Adapter/ReflectionParameterTest.php +++ b/test/unit/Reflection/Adapter/ReflectionParameterTest.php @@ -78,36 +78,27 @@ public static function methodExpectationProvider(): array ]; } - /** @param list $args */ + /** @param list $args + * @param mixed $returnValue + * @param mixed $expectedReturnValue */ #[DataProvider('methodExpectationProvider')] - public function testAdapterMethods( - string $methodName, - array $args, - mixed $returnValue, - string|null $expectedException, - mixed $expectedReturnValue, - ): void { + public function testAdapterMethods(string $methodName, array $args, $returnValue, ?string $expectedException, $expectedReturnValue) : void + { $reflectionStub = $this->createMock(BetterReflectionParameter::class); - if ($expectedException === null) { $reflectionStub->expects($this->once()) ->method($methodName) ->with(...$args) ->willReturn($returnValue); } - $adapter = new ReflectionParameterAdapter($reflectionStub); - if ($expectedException !== null) { $this->expectException($expectedException); } - $actualReturnValue = $adapter->{$methodName}(...$args); - if ($expectedReturnValue === null) { return; } - self::assertSame($expectedReturnValue, $actualReturnValue); } @@ -178,7 +169,7 @@ public function testGetAttributes(): void ->willReturn($betterReflectionAttributes); $reflectionParameterAdapter = new ReflectionParameterAdapter($betterReflectionParameter); - $attributes = $reflectionParameterAdapter->getAttributes(); + $attributes = method_exists($reflectionParameterAdapter, 'getAttributes') ? $reflectionParameterAdapter->getAttributes() : []; self::assertCount(2, $attributes); self::assertSame('SomeAttribute', $attributes[0]->getName()); @@ -213,7 +204,7 @@ public function testGetAttributesWithName(): void ->willReturn($betterReflectionAttributes); $reflectionParameterAdapter = new ReflectionParameterAdapter($betterReflectionParameter); - $attributes = $reflectionParameterAdapter->getAttributes($someAttributeClassName); + $attributes = method_exists($reflectionParameterAdapter, 'getAttributes') ? $reflectionParameterAdapter->getAttributes($someAttributeClassName) : []; self::assertCount(1, $attributes); self::assertSame($someAttributeClassName, $attributes[0]->getName()); @@ -315,9 +306,9 @@ public function testGetAttributesWithInstance(): void $reflectionParameterAdapter = new ReflectionParameterAdapter($betterReflectionParameter); - self::assertCount(1, $reflectionParameterAdapter->getAttributes($className, ReflectionAttributeAdapter::IS_INSTANCEOF)); - self::assertCount(2, $reflectionParameterAdapter->getAttributes($parentClassName, ReflectionAttributeAdapter::IS_INSTANCEOF)); - self::assertCount(2, $reflectionParameterAdapter->getAttributes($interfaceName, ReflectionAttributeAdapter::IS_INSTANCEOF)); + self::assertCount(1, method_exists($reflectionParameterAdapter, 'getAttributes') ? $reflectionParameterAdapter->getAttributes($className, ReflectionAttributeAdapter::IS_INSTANCEOF) : []); + self::assertCount(2, method_exists($reflectionParameterAdapter, 'getAttributes') ? $reflectionParameterAdapter->getAttributes($parentClassName, ReflectionAttributeAdapter::IS_INSTANCEOF) : []); + self::assertCount(2, method_exists($reflectionParameterAdapter, 'getAttributes') ? $reflectionParameterAdapter->getAttributes($interfaceName, ReflectionAttributeAdapter::IS_INSTANCEOF) : []); } public function testGetAttributesThrowsExceptionForInvalidFlags(): void @@ -326,7 +317,7 @@ public function testGetAttributesThrowsExceptionForInvalidFlags(): void $reflectionParameterAdapter = new ReflectionParameterAdapter($betterReflectionParameter); $this->expectException(Error::class); - $reflectionParameterAdapter->getAttributes(null, 123); + method_exists($reflectionParameterAdapter, 'getAttributes') ? $reflectionParameterAdapter->getAttributes(null, 123) : []; } public function testPropertyName(): void diff --git a/test/unit/Reflection/Adapter/ReflectionPropertyTest.php b/test/unit/Reflection/Adapter/ReflectionPropertyTest.php index ee7fae9cb..24ebbbc7c 100644 --- a/test/unit/Reflection/Adapter/ReflectionPropertyTest.php +++ b/test/unit/Reflection/Adapter/ReflectionPropertyTest.php @@ -86,41 +86,30 @@ public static function methodExpectationProvider(): array ]; } - /** @param list $args */ + /** @param list $args + * @param mixed $returnValue + * @param mixed $expectedReturnValue */ #[DataProvider('methodExpectationProvider')] - public function testAdapterMethods( - string $methodName, - array $args, - mixed $returnValue, - string|null $expectedException, - mixed $expectedReturnValue, - string|null $expectedReturnValueInstance, - ): void { + public function testAdapterMethods(string $methodName, array $args, $returnValue, ?string $expectedException, $expectedReturnValue, ?string $expectedReturnValueInstance) : void + { $reflectionStub = $this->createMock(BetterReflectionProperty::class); - if ($expectedException === null) { $reflectionStub->expects($this->once()) ->method($methodName) ->with(...$args) ->willReturn($returnValue); } - $adapter = new ReflectionPropertyAdapter($reflectionStub); - if ($expectedException !== null) { $this->expectException($expectedException); } - $actualReturnValue = $adapter->{$methodName}(...$args); - if ($expectedReturnValue !== null) { self::assertSame($expectedReturnValue, $actualReturnValue); } - if ($expectedReturnValueInstance === null) { return; } - if (is_array($actualReturnValue)) { self::assertNotEmpty($actualReturnValue); self::assertContainsOnlyInstancesOf($expectedReturnValueInstance, $actualReturnValue); @@ -286,7 +275,7 @@ public function testGetAttributes(): void ->willReturn($betterReflectionAttributes); $reflectionPropertyAdapter = new ReflectionPropertyAdapter($betterReflectionProperty); - $attributes = $reflectionPropertyAdapter->getAttributes(); + $attributes = method_exists($reflectionPropertyAdapter, 'getAttributes') ? $reflectionPropertyAdapter->getAttributes() : []; self::assertCount(2, $attributes); self::assertSame('SomeAttribute', $attributes[0]->getName()); @@ -321,7 +310,7 @@ public function testGetAttributesWithName(): void ->willReturn($betterReflectionAttributes); $reflectionPropertyAdapter = new ReflectionPropertyAdapter($betterReflectionProperty); - $attributes = $reflectionPropertyAdapter->getAttributes($someAttributeClassName); + $attributes = method_exists($reflectionPropertyAdapter, 'getAttributes') ? $reflectionPropertyAdapter->getAttributes($someAttributeClassName) : []; self::assertCount(1, $attributes); self::assertSame($someAttributeClassName, $attributes[0]->getName()); @@ -423,9 +412,9 @@ public function testGetAttributesWithInstance(): void $reflectionPropertyAdapter = new ReflectionPropertyAdapter($betterReflectionProperty); - self::assertCount(1, $reflectionPropertyAdapter->getAttributes($className, ReflectionAttributeAdapter::IS_INSTANCEOF)); - self::assertCount(2, $reflectionPropertyAdapter->getAttributes($parentClassName, ReflectionAttributeAdapter::IS_INSTANCEOF)); - self::assertCount(2, $reflectionPropertyAdapter->getAttributes($interfaceName, ReflectionAttributeAdapter::IS_INSTANCEOF)); + self::assertCount(1, method_exists($reflectionPropertyAdapter, 'getAttributes') ? $reflectionPropertyAdapter->getAttributes($className, ReflectionAttributeAdapter::IS_INSTANCEOF) : []); + self::assertCount(2, method_exists($reflectionPropertyAdapter, 'getAttributes') ? $reflectionPropertyAdapter->getAttributes($parentClassName, ReflectionAttributeAdapter::IS_INSTANCEOF) : []); + self::assertCount(2, method_exists($reflectionPropertyAdapter, 'getAttributes') ? $reflectionPropertyAdapter->getAttributes($interfaceName, ReflectionAttributeAdapter::IS_INSTANCEOF) : []); } public function testGetAttributesThrowsExceptionForInvalidFlags(): void @@ -434,7 +423,7 @@ public function testGetAttributesThrowsExceptionForInvalidFlags(): void $reflectionPropertyAdapter = new ReflectionPropertyAdapter($betterReflectionProperty); $this->expectException(Error::class); - $reflectionPropertyAdapter->getAttributes(null, 123); + method_exists($reflectionPropertyAdapter, 'getAttributes') ? $reflectionPropertyAdapter->getAttributes(null, 123) : []; } public function testPropertyName(): void diff --git a/test/unit/Reflection/Adapter/ReflectionUnionTypeTest.php b/test/unit/Reflection/Adapter/ReflectionUnionTypeTest.php index 528151604..e65ecd298 100644 --- a/test/unit/Reflection/Adapter/ReflectionUnionTypeTest.php +++ b/test/unit/Reflection/Adapter/ReflectionUnionTypeTest.php @@ -49,9 +49,10 @@ public static function methodExpectationProvider(): array ]; } - /** @param list $args */ + /** @param list $args + * @param mixed $returnValue */ #[DataProvider('methodExpectationProvider')] - public function testAdapterMethods(string $methodName, string|null $expectedException, mixed $returnValue, array $args): void + public function testAdapterMethods(string $methodName, ?string $expectedException, $returnValue, array $args): void { $reflectionStub = $this->createMock(BetterReflectionUnionType::class); diff --git a/test/unit/Reflection/Annotation/AnnotationHelperTest.php b/test/unit/Reflection/Annotation/AnnotationHelperTest.php index 6d7a284bd..248c5ec6e 100644 --- a/test/unit/Reflection/Annotation/AnnotationHelperTest.php +++ b/test/unit/Reflection/Annotation/AnnotationHelperTest.php @@ -42,7 +42,7 @@ public static function deprecatedDocCommentProvider(): array } #[DataProvider('deprecatedDocCommentProvider')] - public function testIsDeprecated(string|null $docComment, bool $isDeprecated): void + public function testIsDeprecated(?string $docComment, bool $isDeprecated): void { self::assertSame($isDeprecated, AnnotationHelper::isDeprecated($docComment)); } @@ -71,7 +71,7 @@ public static function tentativeReturnTypeDocCommentProvider(): array } #[DataProvider('tentativeReturnTypeDocCommentProvider')] - public function testhasTentativeReturnType(string|null $docComment, bool $isDeprecated): void + public function testhasTentativeReturnType(?string $docComment, bool $isDeprecated): void { self::assertSame($isDeprecated, AnnotationHelper::hasTentativeReturnType($docComment)); } diff --git a/test/unit/Reflection/Deprecated/DeprecatedHelperTest.php b/test/unit/Reflection/Deprecated/DeprecatedHelperTest.php index 0bebcd39b..ebd89fe3d 100644 --- a/test/unit/Reflection/Deprecated/DeprecatedHelperTest.php +++ b/test/unit/Reflection/Deprecated/DeprecatedHelperTest.php @@ -88,7 +88,7 @@ public static function deprecatedDocCommentProvider(): array } #[DataProvider('deprecatedDocCommentProvider')] - public function testIsDeprecatedByDocComment(string|null $docComment, bool $isDeprecated): void + public function testIsDeprecatedByDocComment(?string $docComment, bool $isDeprecated): void { $reflection = $this->createMock(ReflectionClass::class); $reflection diff --git a/test/unit/Reflection/ReflectionClassConstantTest.php b/test/unit/Reflection/ReflectionClassConstantTest.php index 32f6e6884..78185a3df 100644 --- a/test/unit/Reflection/ReflectionClassConstantTest.php +++ b/test/unit/Reflection/ReflectionClassConstantTest.php @@ -49,7 +49,7 @@ private function getComposerLocator(): ComposerSourceLocator } /** @param non-empty-string $name */ - private function getExampleConstant(string $name): ReflectionClassConstant|null + private function getExampleConstant(string $name): ?\Roave\BetterReflection\Reflection\ReflectionClassConstant { $reflector = new DefaultReflector($this->getComposerLocator()); $classInfo = $reflector->reflectClass(ExampleClass::class); diff --git a/test/unit/Reflection/ReflectionClassTest.php b/test/unit/Reflection/ReflectionClassTest.php index 0a84523b4..50d4b0bfb 100644 --- a/test/unit/Reflection/ReflectionClassTest.php +++ b/test/unit/Reflection/ReflectionClassTest.php @@ -1395,24 +1395,15 @@ public static function declaringClassProvider(): array /** @param non-empty-string $methodName */ #[DataProvider('declaringClassProvider')] - public function testGetDeclaringClassWithTraitAndParent( - string $className, - string $methodName, - string $declaringClassShortName, - string $implementingClassShortName, - string $currentClassShortName, - ): void { + public function testGetDeclaringClassWithTraitAndParent(string $className, string $methodName, string $declaringClassShortName, string $implementingClassShortName, string $currentClassShortName) : void + { $reflector = new DefaultReflector(new SingleFileSourceLocator( __DIR__ . '/../Fixture/TraitWithAbstractMethod.php', $this->astLocator, )); - $classInfo = $reflector->reflectClass($className); - self::assertTrue($classInfo->hasMethod($methodName)); - $fooMethodInfo = $classInfo->getMethod($methodName); - self::assertSame($declaringClassShortName, $fooMethodInfo->getDeclaringClass()->getShortName()); self::assertSame($implementingClassShortName, $fooMethodInfo->getImplementingClass()->getShortName()); self::assertSame($currentClassShortName, $fooMethodInfo->getCurrentClass()->getShortName()); @@ -2220,7 +2211,7 @@ static function ($constantValue, string $constantName) use ($reflection): void { self::assertTrue($reflection->hasConstant($constantName), 'Constant ' . $constantName . ' not set'); self::assertSame( $constantValue, - $reflection->getConstant($constantName)?->getValue(), + ($nullsafeVariable1 = $reflection->getConstant($constantName)) ? $nullsafeVariable1->getValue() : null, 'Constant value for ' . $constantName . ' does not match', ); }, diff --git a/test/unit/Reflection/ReflectionEnumCaseTest.php b/test/unit/Reflection/ReflectionEnumCaseTest.php index 781db1259..71adb759f 100644 --- a/test/unit/Reflection/ReflectionEnumCaseTest.php +++ b/test/unit/Reflection/ReflectionEnumCaseTest.php @@ -71,9 +71,10 @@ public static function dataGetValue(): array ]; } - /** @param non-empty-string $caseName */ + /** @param non-empty-string $caseName + * @param int|string $value */ #[DataProvider('dataGetValue')] - public function testGetValue(string $enumName, string $caseName, int|string $value): void + public function testGetValue(string $enumName, string $caseName, $value): void { $enumReflection = $this->reflector->reflectClass($enumName); @@ -161,7 +162,7 @@ public static function dataGetDocComment(): array /** @param non-empty-string $caseName */ #[DataProvider('dataGetDocComment')] - public function testGetDocComment(string $caseName, string|null $docComment): void + public function testGetDocComment(string $caseName, ?string $docComment): void { $enumReflection = $this->reflector->reflectClass(DocComment::class); diff --git a/test/unit/Reflection/ReflectionFunctionAbstractTest.php b/test/unit/Reflection/ReflectionFunctionAbstractTest.php index be4e43e64..1ea232dfd 100644 --- a/test/unit/Reflection/ReflectionFunctionAbstractTest.php +++ b/test/unit/Reflection/ReflectionFunctionAbstractTest.php @@ -464,7 +464,7 @@ public static function returnTypeFunctionProvider(): array } #[DataProvider('returnTypeFunctionProvider')] - public function testGetReturnTypeWithDeclaredType(string $functionToReflect, string|null $expectedType): void + public function testGetReturnTypeWithDeclaredType(string $functionToReflect, ?string $expectedType): void { $functionInfo = (new DefaultReflector( new SingleFileSourceLocator(__DIR__ . '/../Fixture/ReturnTypeDeclarations.php', $this->astLocator), diff --git a/test/unit/Reflection/ReflectionMethodTest.php b/test/unit/Reflection/ReflectionMethodTest.php index 55df3429f..03306393d 100644 --- a/test/unit/Reflection/ReflectionMethodTest.php +++ b/test/unit/Reflection/ReflectionMethodTest.php @@ -114,18 +114,10 @@ public static function visibilityProvider(): array /** @param non-empty-string $methodName */ #[DataProvider('visibilityProvider')] - public function testVisibilityOfMethods( - string $methodName, - bool $shouldBePublic, - bool $shouldBePrivate, - bool $shouldBeProtected, - bool $shouldBeFinal, - bool $shouldBeAbstract, - bool $shouldBeStatic, - ): void { + public function testVisibilityOfMethods(string $methodName, bool $shouldBePublic, bool $shouldBePrivate, bool $shouldBeProtected, bool $shouldBeFinal, bool $shouldBeAbstract, bool $shouldBeStatic) : void + { $classInfo = $this->reflector->reflectClass(Methods::class); $reflectionMethod = $classInfo->getMethod($methodName); - self::assertSame($shouldBePublic, $reflectionMethod->isPublic()); self::assertSame($shouldBePrivate, $reflectionMethod->isPrivate()); self::assertSame($shouldBeProtected, $reflectionMethod->isProtected()); @@ -330,7 +322,7 @@ public static function prototypeProvider(): array /** @param non-empty-string $method */ #[DataProvider('prototypeProvider')] - public function testGetPrototype(string $class, string $method, string|null $expectedPrototype): void + public function testGetPrototype(string $class, string $method, ?string $expectedPrototype): void { $fixture = __DIR__ . '/../Fixture/PrototypeTree.php'; $reflector = new DefaultReflector(new SingleFileSourceLocator($fixture, $this->astLocator)); @@ -887,7 +879,7 @@ public static function getPropertyHookReturnTypeProvider(): array } #[DataProvider('getPropertyHookReturnTypeProvider')] - public function testGetPropertyHookReturnType(string $propertyName, string|null $returnType): void + public function testGetPropertyHookReturnType(string $propertyName, ?string $returnType): void { $reflector = new DefaultReflector(new SingleFileSourceLocator(__DIR__ . '/../Fixture/PropertyHooks.php', $this->astLocator)); $classInfo = $reflector->reflectClass('Roave\BetterReflectionTest\Fixture\GetPropertyHooksReturnTypes'); @@ -895,6 +887,6 @@ public function testGetPropertyHookReturnType(string $propertyName, string|null $hookProperty = $classInfo->getProperty($propertyName); $getHookReflection = $hookProperty->getHook(ReflectionPropertyHookType::Get); self::assertNotNull($getHookReflection); - self::assertSame($returnType, $getHookReflection->getReturnType()?->__toString()); + self::assertSame($returnType, ($nullsafeVariable1 = $getHookReflection->getReturnType()) ? $nullsafeVariable1->__toString() : null); } } diff --git a/test/unit/Reflection/ReflectionParameterTest.php b/test/unit/Reflection/ReflectionParameterTest.php index 4c5f58ebd..c38324f44 100644 --- a/test/unit/Reflection/ReflectionParameterTest.php +++ b/test/unit/Reflection/ReflectionParameterTest.php @@ -122,8 +122,11 @@ public static function defaultParameterProvider(): array ]; } + /** + * @param mixed $expectedValue + */ #[DataProvider('defaultParameterProvider')] - public function testDefaultParametersTypes(string $defaultExpression, mixed $expectedValue): void + public function testDefaultParametersTypes(string $defaultExpression, $expectedValue): void { $content = sprintf('reflector->reflectClass(Methods::class); - $method = $classInfo->getMethod('methodWithExplicitTypedParameters'); - $type = $method->getParameter($parameterToTest)->getType(); - self::assertSame($expectedType, (string) $type); } diff --git a/test/unit/Reflection/ReflectionPropertyTest.php b/test/unit/Reflection/ReflectionPropertyTest.php index a00645732..67adac81b 100644 --- a/test/unit/Reflection/ReflectionPropertyTest.php +++ b/test/unit/Reflection/ReflectionPropertyTest.php @@ -327,9 +327,10 @@ public static function propertyDefaultValueProvider(): array ]; } - /** @param non-empty-string $propertyName */ + /** @param non-empty-string $propertyName + * @param mixed $defaultValue */ #[DataProvider('propertyDefaultValueProvider')] - public function testPropertyDefaultValue(string $propertyName, bool $hasDefaultValue, mixed $defaultValue, string|null $defaultValueExpression): void + public function testPropertyDefaultValue(string $propertyName, bool $hasDefaultValue, $defaultValue, ?string $defaultValueExpression): void { $classInfo = (new DefaultReflector(new SingleFileSourceLocator(__DIR__ . '/../Fixture/DefaultProperties.php', $this->astLocator)))->reflectClass(DefaultProperties::class); $property = $classInfo->getProperty($propertyName); @@ -653,13 +654,10 @@ public static function hasTypeProvider(): array /** @param non-empty-string $propertyName */ #[DataProvider('hasTypeProvider')] - public function testHasType( - string $propertyName, - bool $expectedHasType, - ): void { + public function testHasType(string $propertyName, bool $expectedHasType) : void + { $classReflection = $this->reflector->reflectClass(Php74PropertyTypeDeclarations::class); $propertyReflection = $classReflection->getProperty($propertyName); - self::assertSame($expectedHasType, $propertyReflection->hasType()); } @@ -677,15 +675,11 @@ public static function getTypeProvider(): array /** @param non-empty-string $propertyName */ #[DataProvider('getTypeProvider')] - public function testGetType( - string $propertyName, - string $expectedType, - ): void { + public function testGetType(string $propertyName, string $expectedType) : void + { $classReflection = $this->reflector->reflectClass(Php74PropertyTypeDeclarations::class); $propertyReflection = $classReflection->getProperty($propertyName); - $type = $propertyReflection->getType(); - self::assertSame($expectedType, (string) $type); } @@ -708,7 +702,7 @@ public static function isInitializedProvider(): array /** @param non-empty-string $propertyName */ #[DataProvider('isInitializedProvider')] - public function testIsInitialized(string $propertyName, object|null $object, bool $isInitialized): void + public function testIsInitialized(string $propertyName, ?object $object, bool $isInitialized): void { $classReflection = $this->reflector->reflectClass(InitializedProperties::class); @@ -1173,7 +1167,7 @@ public static function getPropertyHookReturnTypeProvider(): array } #[DataProvider('getPropertyHookReturnTypeProvider')] - public function testGetPropertyHookReturnType(string $propertyName, string|null $returnType): void + public function testGetPropertyHookReturnType(string $propertyName, ?string $returnType): void { $reflector = new DefaultReflector(new SingleFileSourceLocator(__DIR__ . '/../Fixture/PropertyHooks.php', $this->astLocator)); $classInfo = $reflector->reflectClass('Roave\BetterReflectionTest\Fixture\GetPropertyHooksReturnTypes'); @@ -1181,6 +1175,6 @@ public function testGetPropertyHookReturnType(string $propertyName, string|null $hookProperty = $classInfo->getProperty($propertyName); $getHookReflection = $hookProperty->getHook(ReflectionPropertyHookType::Get); self::assertNotNull($getHookReflection); - self::assertSame($returnType, $getHookReflection->getReturnType()?->__toString()); + self::assertSame($returnType, ($nullsafeVariable1 = $getHookReflection->getReturnType()) ? $nullsafeVariable1->__toString() : null); } } diff --git a/test/unit/Reflection/ReflectionTypeTest.php b/test/unit/Reflection/ReflectionTypeTest.php index 2fccfd370..6f61bc414 100644 --- a/test/unit/Reflection/ReflectionTypeTest.php +++ b/test/unit/Reflection/ReflectionTypeTest.php @@ -89,16 +89,13 @@ public static function dataProvider(): array ]; } + /** + * @param \PhpParser\Node\Identifier|\PhpParser\Node\Name|\PhpParser\Node\NullableType|\PhpParser\Node\UnionType|\PhpParser\Node\IntersectionType $node + */ #[DataProvider('dataProvider')] - public function test( - Node\Identifier|Node\Name|Node\NullableType|Node\UnionType|Node\IntersectionType $node, - bool $forceAllowsNull, - string $expectedReflectionClass, - string $expectedTypeAsString, - bool $expectedAllowsNull, - ): void { + public function test($node, bool $forceAllowsNull, string $expectedReflectionClass, string $expectedTypeAsString, bool $expectedAllowsNull) : void + { $reflectionType = ReflectionType::createFromNode($this->reflector, $this->owner, $node, $forceAllowsNull); - self::assertInstanceOf($expectedReflectionClass, $reflectionType); self::assertSame($expectedTypeAsString, $reflectionType->__toString()); self::assertSame($expectedAllowsNull, $reflectionType->allowsNull()); diff --git a/test/unit/Reflection/StringCast/ReflectionTypeStringCastTest.php b/test/unit/Reflection/StringCast/ReflectionTypeStringCastTest.php index 47162629c..713148662 100644 --- a/test/unit/Reflection/StringCast/ReflectionTypeStringCastTest.php +++ b/test/unit/Reflection/StringCast/ReflectionTypeStringCastTest.php @@ -46,7 +46,7 @@ function k(): null|(A&B)|(A&C) {} ->astLocator(), )); - $returnTypeForFunction = static function (string $function) use ($reflector): ReflectionNamedType|ReflectionUnionType|ReflectionIntersectionType { + $returnTypeForFunction = static function (string $function) use ($reflector) { $type = $reflector->reflectFunction($function) ->getReturnType(); @@ -70,11 +70,12 @@ function k(): null|(A&B)|(A&C) {} ]; } + /** + * @param \Roave\BetterReflection\Reflection\ReflectionNamedType|\Roave\BetterReflection\Reflection\ReflectionUnionType|\Roave\BetterReflection\Reflection\ReflectionIntersectionType $type + */ #[DataProvider('toStringProvider')] - public function testToString( - ReflectionNamedType|ReflectionUnionType|ReflectionIntersectionType $type, - string $expectedString, - ): void { + public function testToString($type, string $expectedString) : void + { self::assertSame($expectedString, ReflectionTypeStringCast::toString($type)); } } diff --git a/test/unit/SourceLocator/Exception/InvalidFileInfoTest.php b/test/unit/SourceLocator/Exception/InvalidFileInfoTest.php index 57b7014d1..43578f500 100644 --- a/test/unit/SourceLocator/Exception/InvalidFileInfoTest.php +++ b/test/unit/SourceLocator/Exception/InvalidFileInfoTest.php @@ -13,8 +13,11 @@ #[CoversClass(InvalidFileInfo::class)] class InvalidFileInfoTest extends TestCase { + /** + * @param mixed $value + */ #[DataProvider('nonSplFileInfoProvider')] - public function testFromNonSplFileInfo(string $expectedMessage, mixed $value): void + public function testFromNonSplFileInfo(string $expectedMessage, $value): void { $exception = InvalidFileInfo::fromNonSplFileInfo($value); diff --git a/test/unit/SourceLocator/FileCheckerTest.php b/test/unit/SourceLocator/FileCheckerTest.php index af836dbeb..5aceccf7e 100644 --- a/test/unit/SourceLocator/FileCheckerTest.php +++ b/test/unit/SourceLocator/FileCheckerTest.php @@ -36,7 +36,7 @@ public function testCheckFileThrowsExceptionIfFileIsNotAFile(): void public function testCheckFileThrowsExceptionIfFileIsNotReadable(): void { - if (str_starts_with(PHP_OS, 'WIN')) { + if (strncmp(PHP_OS, 'WIN', strlen('WIN')) === 0) { self::markTestSkipped('It\'s not possible to change file mode on Windows'); } diff --git a/test/unit/SourceLocator/SourceStubber/PhpStormStubsSourceStubberTest.php b/test/unit/SourceLocator/SourceStubber/PhpStormStubsSourceStubberTest.php index 1fe769092..b5d52681f 100644 --- a/test/unit/SourceLocator/SourceStubber/PhpStormStubsSourceStubberTest.php +++ b/test/unit/SourceLocator/SourceStubber/PhpStormStubsSourceStubberTest.php @@ -256,17 +256,12 @@ private function assertSameMethodAttributes(CoreReflectionMethod $original, Refl } } - private function assertSameParameterAttributes( - CoreReflectionMethod $originalMethod, - CoreReflectionParameter $original, - ReflectionParameter $stubbed, - ): void { + private function assertSameParameterAttributes(CoreReflectionMethod $originalMethod, CoreReflectionParameter $original, ReflectionParameter $stubbed): void + { $parameterName = $original->getDeclaringClass()->getName() . '#' . $originalMethod->getName() . '.' . $original->getName(); - self::assertSame($original->getName(), $stubbed->getName(), $parameterName); - if ( in_array($parameterName, [ 'ErrorException#__construct.filename', @@ -276,7 +271,6 @@ private function assertSameParameterAttributes( // These parameters have default values __FILE__ and __LINE__ and we cannot resolve them for stubs return; } - self::assertSame($original->canBePassedByValue(), $stubbed->canBePassedByValue(), $parameterName); // Bugs in PHP if ( @@ -287,7 +281,6 @@ private function assertSameParameterAttributes( ) { self::assertSame($original->isOptional(), $stubbed->isOptional(), $parameterName); } - self::assertSame($original->isPassedByReference(), $stubbed->isPassedByReference(), $parameterName); self::assertSame($original->isVariadic(), $stubbed->isVariadic(), $parameterName); } @@ -372,8 +365,11 @@ public static function internalConstantsProvider(): array return $provider; } + /** + * @param mixed $constantValue + */ #[DataProvider('internalConstantsProvider')] - public function testInternalConstants(string $constantName, mixed $constantValue, string $extensionName): void + public function testInternalConstants(string $constantName, $constantValue, string $extensionName): void { $constantReflection = $this->reflector->reflectConstant($constantName); @@ -815,14 +811,8 @@ public static function dataMethodInPhpVersion(): array /** @param non-empty-string $methodName */ #[DataProvider('dataMethodInPhpVersion')] - public function testMethodInPhpVersion( - string $className, - string $methodName, - int $phpVersion, - bool $isSupported, - string|null $returnType = null, - string|null $tentativeReturnType = null, - ): void { + public function testMethodInPhpVersion(string $className, string $methodName, int $phpVersion, bool $isSupported, ?string $returnType = null, ?string $tentativeReturnType = null) : void + { $sourceStubber = new PhpStormStubsSourceStubber($this->phpParser, $this->prettyPrinter,$phpVersion); $sourceLocator = new AggregateSourceLocator([ // We need to hack Stringable to make the test work @@ -830,18 +820,15 @@ public function testMethodInPhpVersion( new PhpInternalSourceLocator($this->astLocator, $sourceStubber), ]); $reflector = new DefaultReflector($sourceLocator); - $class = $reflector->reflectClass($className); - $fullMethodName = sprintf('%s#%s', $className, $methodName); - if ($isSupported) { self::assertTrue($class->hasMethod($methodName), $fullMethodName); $method = $class->getMethod($methodName); - self::assertSame($returnType, $method->getReturnType()?->__toString()); - self::assertSame($tentativeReturnType, $method->getTentativeReturnType()?->__toString()); + self::assertSame($returnType, ($nullsafeVariable1 = $method->getReturnType()) ? $nullsafeVariable1->__toString() : null); + self::assertSame($tentativeReturnType, ($nullsafeVariable2 = $method->getTentativeReturnType()) ? $nullsafeVariable2->__toString() : null); } else { self::assertFalse($class->hasMethod($methodName), $fullMethodName); } @@ -865,28 +852,18 @@ public static function dataMethodParameterInPhpVersion(): array * @param non-empty-string $parameterName */ #[DataProvider('dataMethodParameterInPhpVersion')] - public function testMethodParameterInPhpVersion( - string $className, - string $methodName, - string $parameterName, - int|null $phpVersion, - bool $isSupported, - string|null $type = null, - bool|null $allowsNull = null, - ): void { + public function testMethodParameterInPhpVersion(string $className, string $methodName, string $parameterName, ?int $phpVersion, bool $isSupported, ?string $type = null, ?bool $allowsNull = null) : void + { $sourceStubber = new PhpStormStubsSourceStubber($this->phpParser, $this->prettyPrinter,$phpVersion); $phpInternalSourceLocator = new PhpInternalSourceLocator($this->astLocator, $sourceStubber); $reflector = new DefaultReflector($phpInternalSourceLocator); - $class = $reflector->reflectClass($className); $method = $class->getMethod($methodName); $parameter = $method->getParameter($parameterName); - $fullParameterName = sprintf('%s#%s.$%s', $className, $methodName, $parameterName); - if ($isSupported) { self::assertInstanceOf(ReflectionParameter::class, $parameter, $fullParameterName); - self::assertSame($type, $parameter->getType()?->__toString(), $fullParameterName); + self::assertSame($type, ($nullsafeVariable3 = $parameter->getType()) ? $nullsafeVariable3->__toString() : null, $fullParameterName); self::assertSame($allowsNull, $parameter->allowsNull(), $fullParameterName); } else { self::assertNull($parameter, $fullParameterName); @@ -911,7 +888,7 @@ public static function dataPropertyInPhpVersion(): array /** @param non-empty-string $propertyName */ #[DataProvider('dataPropertyInPhpVersion')] - public function testPropertyInPhpVersion(string $className, string $propertyName, int $phpVersion, bool $isSupported, string|null $type = null): void + public function testPropertyInPhpVersion(string $className, string $propertyName, int $phpVersion, bool $isSupported, ?string $type = null): void { $sourceStubber = new PhpStormStubsSourceStubber($this->phpParser, $this->prettyPrinter,$phpVersion); $phpInternalSourceLocator = new PhpInternalSourceLocator($this->astLocator, $sourceStubber); @@ -924,7 +901,7 @@ public function testPropertyInPhpVersion(string $className, string $propertyName if ($isSupported) { self::assertInstanceOf(ReflectionProperty::class, $property, $fullPropertyName); - self::assertSame($type, $property->getType()?->__toString(), $fullPropertyName); + self::assertSame($type, ($nullsafeVariable4 = $property->getType()) ? $nullsafeVariable4->__toString() : null, $fullPropertyName); } else { self::assertNull($property, $fullPropertyName); } @@ -963,7 +940,7 @@ public static function dataFunctionInPhpVersion(): array } #[DataProvider('dataFunctionInPhpVersion')] - public function testFunctionInPhpVersion(string $functionName, int $phpVersion, bool $isSupported, string|null $returnType = null): void + public function testFunctionInPhpVersion(string $functionName, int $phpVersion, bool $isSupported, ?string $returnType = null): void { $sourceStubber = new PhpStormStubsSourceStubber($this->phpParser, $this->prettyPrinter,$phpVersion); $phpInternalSourceLocator = new PhpInternalSourceLocator($this->astLocator, $sourceStubber); @@ -973,7 +950,7 @@ public function testFunctionInPhpVersion(string $functionName, int $phpVersion, $function = $reflector->reflectFunction($functionName); self::assertInstanceOf(ReflectionFunction::class, $function, $functionName); - self::assertSame($returnType, $function->getReturnType()?->__toString()); + self::assertSame($returnType, ($nullsafeVariable5 = $function->getReturnType()) ? $nullsafeVariable5->__toString() : null); } else { $this->expectException(IdentifierNotFound::class); $this->expectExceptionMessage(sprintf('Function "%s" could not be found in the located source', $functionName)); @@ -1002,26 +979,17 @@ public static function dataFunctionParameterInPhpVersion(): array /** @param non-empty-string $parameterName */ #[DataProvider('dataFunctionParameterInPhpVersion')] - public function testFunctionParameterInPhpVersion( - string $functionName, - string $parameterName, - int|null $phpVersion, - bool $isSupported, - string|null $type = null, - bool|null $allowsNull = null, - ): void { + public function testFunctionParameterInPhpVersion(string $functionName, string $parameterName, ?int $phpVersion, bool $isSupported, ?string $type = null, ?bool $allowsNull = null) : void + { $sourceStubber = new PhpStormStubsSourceStubber($this->phpParser, $this->prettyPrinter,$phpVersion); $phpInternalSourceLocator = new PhpInternalSourceLocator($this->astLocator, $sourceStubber); $reflector = new DefaultReflector($phpInternalSourceLocator); - $function = $reflector->reflectFunction($functionName); $parameter = $function->getParameter($parameterName); - $fullParameterName = sprintf('%s::$%s', $functionName, $parameterName); - if ($isSupported) { self::assertInstanceOf(ReflectionParameter::class, $parameter, $fullParameterName); - self::assertSame($type, $parameter->getType()?->__toString(), $fullParameterName); + self::assertSame($type, ($nullsafeVariable6 = $parameter->getType()) ? $nullsafeVariable6->__toString() : null, $fullParameterName); self::assertSame($allowsNull, $parameter->allowsNull(), $fullParameterName); } else { self::assertNull($parameter, $fullParameterName); @@ -1267,16 +1235,12 @@ public static function dataImmediateInterfaces(): array /** @param string[] $interfaceNames */ #[DataProvider('dataImmediateInterfaces')] - public function testImmediateInterfaces( - string $className, - array $interfaceNames, - int $phpVersion, - ): void { + public function testImmediateInterfaces(string $className, array $interfaceNames, int $phpVersion) : void + { $sourceStubber = new PhpStormStubsSourceStubber($this->phpParser, $this->prettyPrinter,$phpVersion); $phpInternalSourceLocator = new PhpInternalSourceLocator($this->astLocator, $sourceStubber); $reflector = new DefaultReflector($phpInternalSourceLocator); $class = $reflector->reflectClass($className); - self::assertSame($interfaceNames, array_keys($class->getImmediateInterfaces())); } @@ -1303,16 +1267,12 @@ public static function dataSubclass(): array } #[DataProvider('dataSubclass')] - public function testSubclass( - string $className, - string $subclassName, - int $phpVersion, - ): void { + public function testSubclass(string $className, string $subclassName, int $phpVersion) : void + { $sourceStubber = new PhpStormStubsSourceStubber($this->phpParser, $this->prettyPrinter,$phpVersion); $phpInternalSourceLocator = new PhpInternalSourceLocator($this->astLocator, $sourceStubber); $reflector = new DefaultReflector($phpInternalSourceLocator); $class = $reflector->reflectClass($className); - self::assertTrue($class->isSubclassOf($subclassName)); } diff --git a/test/unit/SourceLocator/SourceStubber/ReflectionSourceStubberTest.php b/test/unit/SourceLocator/SourceStubber/ReflectionSourceStubberTest.php index 74f15f630..08ae3fbd2 100644 --- a/test/unit/SourceLocator/SourceStubber/ReflectionSourceStubberTest.php +++ b/test/unit/SourceLocator/SourceStubber/ReflectionSourceStubberTest.php @@ -266,7 +266,11 @@ private function assertSameInterfaces(CoreReflectionClass $original, ReflectionC self::assertSame($originalInterfacesNames, $stubbedInterfacesNames); } - private function assertSameClassAttributes(CoreReflectionClass|CoreReflectionEnum $original, ReflectionClass|ReflectionEnum $stubbed): void + /** + * @param CoreReflectionClass|CoreReflectionEnum $original + * @param \Roave\BetterReflection\Reflection\ReflectionClass|\Roave\BetterReflection\Reflection\ReflectionEnum $stubbed + */ + private function assertSameClassAttributes($original, $stubbed): void { self::assertSame($original->getName(), $stubbed->getName()); @@ -371,24 +375,17 @@ private function assertSameMethodAttributes(CoreReflectionMethod $original, Refl ); } - private function assertSameParameterAttributes( - CoreReflectionMethod $originalMethod, - CoreReflectionParameter $original, - ReflectionParameter $stubbed, - ): void { + private function assertSameParameterAttributes(CoreReflectionMethod $originalMethod, CoreReflectionParameter $original, ReflectionParameter $stubbed): void + { $methodName = $original->getDeclaringClass()->getName() . '#' . $originalMethod->getName(); $parameterName = $methodName . '.' . $original->getName(); - self::assertSame($original->getName(), $stubbed->getName(), $parameterName); - if ($original->isDefaultValueAvailable()) { self::assertSame($original->getDefaultValue(), $stubbed->getDefaultValue(), $parameterName); } else { self::assertSame($original->isDefaultValueAvailable(), $stubbed->isDefaultValueAvailable(), $parameterName); } - //self::assertSame($original->allowsNull(), $stubbed->allowsNull()); @TODO WTF? - self::assertSame($original->canBePassedByValue(), $stubbed->canBePassedByValue(), $parameterName); self::assertSame($original->isOptional(), $stubbed->isOptional(), $parameterName); self::assertSame($original->isPassedByReference(), $stubbed->isPassedByReference(), $parameterName); @@ -515,8 +512,11 @@ public static function internalConstantsProvider(): array return $provider; } + /** + * @param mixed $constantValue + */ #[DataProvider('internalConstantsProvider')] - public function testInternalConstants(string $constantName, mixed $constantValue, string $extensionName): void + public function testInternalConstants(string $constantName, $constantValue, string $extensionName): void { $constantReflection = $this->reflector->reflectConstant($constantName); @@ -555,8 +555,8 @@ public function testClosureWithEnumParameterDefaultValue(): void public function testClosureWithNewInInitializer(): void { - $closure = function ($test = new \stdClass()): void { - + $closure = function ($test = null) : void { + $test ??= new \stdClass(); }; $stub = $this->stubber->generateFunctionStubFromReflection(new CoreReflectionFunction($closure)); self::assertStringContainsString('$test = new \stdClass()', $stub->getStub()); diff --git a/test/unit/SourceLocator/Type/AggregateSourceLocatorTest.php b/test/unit/SourceLocator/Type/AggregateSourceLocatorTest.php index 267cbd55d..c9c126a2d 100644 --- a/test/unit/SourceLocator/Type/AggregateSourceLocatorTest.php +++ b/test/unit/SourceLocator/Type/AggregateSourceLocatorTest.php @@ -29,7 +29,10 @@ protected function setUp(): void $this->astLocator = BetterReflectionSingleton::instance()->astLocator(); } - private function getMockReflector(): Reflector|MockObject + /** + * @return \Roave\BetterReflection\Reflector\Reflector|\PHPUnit\Framework\MockObject\MockObject + */ + private function getMockReflector() { return $this->createMock(Reflector::class); } diff --git a/test/unit/SourceLocator/Type/AnonymousClassObjectSourceLocatorTest.php b/test/unit/SourceLocator/Type/AnonymousClassObjectSourceLocatorTest.php index cdc9f1a04..cf5719842 100644 --- a/test/unit/SourceLocator/Type/AnonymousClassObjectSourceLocatorTest.php +++ b/test/unit/SourceLocator/Type/AnonymousClassObjectSourceLocatorTest.php @@ -67,7 +67,7 @@ public function testLocateIdentifier(object $class, string $file, int $startLine $reflection = (new AnonymousClassObjectSourceLocator($class, $this->parser))->locateIdentifier( $this->reflector, new Identifier( - $class::class, + get_class($class), new IdentifierType(IdentifierType::IDENTIFIER_CLASS), ), ); @@ -87,7 +87,7 @@ public function testCannotLocateNonAnonymousClass(): void $reflection = (new AnonymousClassObjectSourceLocator($class, $this->parser))->locateIdentifier( $this->reflector, new Identifier( - $class::class, + get_class($class), new IdentifierType(IdentifierType::IDENTIFIER_CLASS), ), ); @@ -194,7 +194,7 @@ public function testExceptionIfTwoAnonymousClassesOnSameLine(string $file, objec (new AnonymousClassObjectSourceLocator($class, $this->parser))->locateIdentifier( $this->reflector, new Identifier( - $class::class, + get_class($class), new IdentifierType(IdentifierType::IDENTIFIER_CLASS), ), ); @@ -221,7 +221,7 @@ public function testExceptionIfEvaledAnonymousClass(): void (new AnonymousClassObjectSourceLocator($class, $this->parser))->locateIdentifier( $this->reflector, new Identifier( - $class::class, + get_class($class), new IdentifierType(IdentifierType::IDENTIFIER_CLASS), ), ); @@ -237,7 +237,7 @@ public function testNamesAreResolved(): void $reflection = $sourceLocator->locateIdentifier( $reflector, new Identifier( - $class::class, + get_class($class), new IdentifierType(IdentifierType::IDENTIFIER_CLASS), ), ); @@ -269,8 +269,9 @@ public function testExceptionIfSourceFileIsNotReadable(): void $sourceLocator->locateIdentifier($this->reflector, new Identifier(stdClass::class, new IdentifierType(IdentifierType::IDENTIFIER_CLASS))); } - /** @return non-empty-string */ - private static function realPath(string|false $path): string + /** @return non-empty-string + * @param string|false $path */ + private static function realPath($path): string { $realPath = realpath($path); diff --git a/test/unit/SourceLocator/Type/AutoloadSourceLocatorTest.php b/test/unit/SourceLocator/Type/AutoloadSourceLocatorTest.php index 9ca33733b..dba1c009b 100644 --- a/test/unit/SourceLocator/Type/AutoloadSourceLocatorTest.php +++ b/test/unit/SourceLocator/Type/AutoloadSourceLocatorTest.php @@ -64,7 +64,10 @@ protected function setUp(): void $this->astLocator = $configuration->astLocator(); } - private function getMockReflector(): Reflector&MockObject + /** + * @return (\PHPUnit\Framework\MockObject\MockObject & \Roave\BetterReflection\Reflector\Reflector) + */ + private function getMockReflector() { return $this->createMock(Reflector::class); } @@ -442,7 +445,7 @@ public function testWillLocateSourcesInPharPath(): void public function testBrokenAutoloader(): void { - $getErrorHandler = static function (): callable|null { + $getErrorHandler = static function (): ?callable { $errorHandler = set_error_handler(static fn (): bool => true); restore_error_handler(); diff --git a/test/unit/SourceLocator/Type/ClosureSourceLocatorTest.php b/test/unit/SourceLocator/Type/ClosureSourceLocatorTest.php index 7e2d31e54..f1b24532a 100644 --- a/test/unit/SourceLocator/Type/ClosureSourceLocatorTest.php +++ b/test/unit/SourceLocator/Type/ClosureSourceLocatorTest.php @@ -62,7 +62,7 @@ public static function closuresProvider(): array /** @param non-empty-string $file */ #[DataProvider('closuresProvider')] - public function testLocateIdentifier(Closure $closure, string|null $namespace, string $file, int $startLine, int $endLine): void + public function testLocateIdentifier(Closure $closure, ?string $namespace, string $file, int $startLine, int $endLine): void { $locator = new ClosureSourceLocator($closure, $this->parser); @@ -103,7 +103,7 @@ public function testEvaledClosureThrowsInvalidFileLocation(): void } #[DataProvider('closuresProvider')] - public function testLocateIdentifiersByType(Closure $closure, string|null $namespace, string $file, int $startLine, int $endLine): void + public function testLocateIdentifiersByType(Closure $closure, ?string $namespace, string $file, int $startLine, int $endLine): void { /** @var list $reflections */ $reflections = (new ClosureSourceLocator($closure, $this->parser))->locateIdentifiersByType( @@ -206,7 +206,7 @@ public function testNamesAreResolved(): void ); self::assertInstanceOf(ReflectionFunction::class, $reflection); - self::assertSame('Roave\BetterReflectionTest\Fixture\ClassUsedAsClosureParameter', $reflection->getParameter('parameter')->getType()?->__toString()); + self::assertSame('Roave\BetterReflectionTest\Fixture\ClassUsedAsClosureParameter', ($nullsafeVariable1 = $reflection->getParameter('parameter')->getType()) ? $nullsafeVariable1->__toString() : null); } public function testExceptionIfSourceFileIsNotReadable(): void @@ -228,8 +228,9 @@ public function testExceptionIfSourceFileIsNotReadable(): void $sourceLocator->locateIdentifier($this->reflector, new Identifier('whatever', new IdentifierType(IdentifierType::IDENTIFIER_FUNCTION))); } - /** @return non-empty-string */ - private static function realPath(string|false $path): string + /** @return non-empty-string + * @param string|false $path */ + private static function realPath($path): string { $realPath = realpath($path); diff --git a/test/unit/SourceLocator/Type/ComposerSourceLocatorTest.php b/test/unit/SourceLocator/Type/ComposerSourceLocatorTest.php index 9bbc37a15..5935438f7 100644 --- a/test/unit/SourceLocator/Type/ComposerSourceLocatorTest.php +++ b/test/unit/SourceLocator/Type/ComposerSourceLocatorTest.php @@ -28,7 +28,10 @@ protected function setUp(): void $this->astLocator = BetterReflectionSingleton::instance()->astLocator(); } - private function getMockReflector(): Reflector|MockObject + /** + * @return \Roave\BetterReflection\Reflector\Reflector|\PHPUnit\Framework\MockObject\MockObject + */ + private function getMockReflector() { return $this->createMock(Reflector::class); } diff --git a/test/unit/SourceLocator/Type/EvaledCodeSourceLocatorTest.php b/test/unit/SourceLocator/Type/EvaledCodeSourceLocatorTest.php index a269c8de3..14d8da16c 100644 --- a/test/unit/SourceLocator/Type/EvaledCodeSourceLocatorTest.php +++ b/test/unit/SourceLocator/Type/EvaledCodeSourceLocatorTest.php @@ -39,7 +39,10 @@ protected function setUp(): void $this->sourceStubber = $betterReflection->sourceStubber(); } - private function getMockReflector(): Reflector|MockObject + /** + * @return \Roave\BetterReflection\Reflector\Reflector|\PHPUnit\Framework\MockObject\MockObject + */ + private function getMockReflector() { return $this->createMock(Reflector::class); } diff --git a/test/unit/SourceLocator/Type/MemoizingSourceLocatorTest.php b/test/unit/SourceLocator/Type/MemoizingSourceLocatorTest.php index 6263ee2cd..fe5b89a32 100644 --- a/test/unit/SourceLocator/Type/MemoizingSourceLocatorTest.php +++ b/test/unit/SourceLocator/Type/MemoizingSourceLocatorTest.php @@ -28,11 +28,20 @@ #[CoversClass(MemoizingSourceLocator::class)] class MemoizingSourceLocatorTest extends TestCase { - private Reflector|MockObject $reflector1; + /** + * @var \Roave\BetterReflection\Reflector\Reflector|\PHPUnit\Framework\MockObject\MockObject + */ + private $reflector1; - private Reflector|MockObject $reflector2; + /** + * @var \Roave\BetterReflection\Reflector\Reflector|\PHPUnit\Framework\MockObject\MockObject + */ + private $reflector2; - private SourceLocator|MockObject $wrappedLocator; + /** + * @var \Roave\BetterReflection\SourceLocator\Type\SourceLocator|\PHPUnit\Framework\MockObject\MockObject + */ + private $wrappedLocator; private MemoizingSourceLocator $memoizingLocator; @@ -128,17 +137,10 @@ public function testMemoizationByTypeDistinguishesBetweenSourceLocatorsAndType() ->expects(self::exactly(4)) ->method('locateIdentifiersByType') ->with(self::logicalOr($this->reflector1, $this->reflector2)) - ->willReturnCallback(function ( - Reflector $reflector, - IdentifierType $identifierType, - ) use ( - $symbols1, - $symbols2, - ): array { + ->willReturnCallback(function (Reflector $reflector, IdentifierType $identifierType) use ($symbols1, $symbols2) : array { if ($reflector === $this->reflector1) { return $symbols1[$identifierType->getName()]; } - return $symbols2[$identifierType->getName()]; }); @@ -168,13 +170,9 @@ public function testMemoizationByTypeDistinguishesBetweenSourceLocatorsAndType() * @param list $identifiers * @param list $reflectors */ - private function assertMemoization( - array $identifiers, - int $expectedFetchOperationsCount, - array $reflectors, - ): void { + private function assertMemoization(array $identifiers, int $expectedFetchOperationsCount, array $reflectors): void + { $fetchedSymbolsCount = []; - $this ->wrappedLocator ->expects(self::exactly($expectedFetchOperationsCount)) @@ -183,35 +181,23 @@ private function assertMemoization( self::logicalOr(...$reflectors), self::callback(static fn (Identifier $identifier): bool => in_array($identifier, $identifiers, true)), ) - ->willReturnCallback(function ( - Reflector $reflector, - Identifier $identifier, - ) use ( - &$fetchedSymbolsCount, - ): Reflection|null { + ->willReturnCallback(function (Reflector $reflector, Identifier $identifier) use (&$fetchedSymbolsCount) : ?\Roave\BetterReflection\Reflection\Reflection { $identifierId = spl_object_id($identifier); $reflectorId = spl_object_id($reflector); $hash = $reflectorId . $identifierId; - $fetchedSymbolsCount[$hash] = ($fetchedSymbolsCount[$hash] ?? 0) + 1; - return [ $this->createMock(Reflection::class), null, ][random_int(0, 1)]; }); - $memoizedSymbols = $this->locateIdentifiers($reflectors, $identifiers); $cachedSymbols = $this->locateIdentifiers($reflectors, $identifiers); - self::assertCount($expectedFetchOperationsCount, $memoizedSymbols); - foreach ($fetchedSymbolsCount as $fetchedSymbolCount) { self::assertSame(1, $fetchedSymbolCount, 'Each fetch is unique'); } - self::assertSame($memoizedSymbols, $cachedSymbols); - $memoizedSymbolsIds = array_map('spl_object_id', array_filter($memoizedSymbols)); self::assertCount(count($memoizedSymbolsIds), array_unique($memoizedSymbolsIds), 'No duplicate symbols'); } diff --git a/test/unit/SourceLocator/Type/PhpInternalSourceLocatorTest.php b/test/unit/SourceLocator/Type/PhpInternalSourceLocatorTest.php index 288c2ce7e..8898d5b02 100644 --- a/test/unit/SourceLocator/Type/PhpInternalSourceLocatorTest.php +++ b/test/unit/SourceLocator/Type/PhpInternalSourceLocatorTest.php @@ -53,7 +53,10 @@ protected function setUp(): void ); } - private function getMockReflector(): Reflector|MockObject + /** + * @return \Roave\BetterReflection\Reflector\Reflector|\PHPUnit\Framework\MockObject\MockObject + */ + private function getMockReflector() { return $this->createMock(Reflector::class); } diff --git a/test/unit/SourceLocator/Type/SingleFileSourceLocatorTest.php b/test/unit/SourceLocator/Type/SingleFileSourceLocatorTest.php index 322fe30f0..50c6959b7 100644 --- a/test/unit/SourceLocator/Type/SingleFileSourceLocatorTest.php +++ b/test/unit/SourceLocator/Type/SingleFileSourceLocatorTest.php @@ -27,7 +27,10 @@ protected function setUp(): void $this->astLocator = BetterReflectionSingleton::instance()->astLocator(); } - private function getMockReflector(): Reflector|MockObject + /** + * @return \Roave\BetterReflection\Reflector\Reflector|\PHPUnit\Framework\MockObject\MockObject + */ + private function getMockReflector() { return $this->createMock(Reflector::class); } diff --git a/test/unit/SourceLocator/Type/StringSourceLocatorTest.php b/test/unit/SourceLocator/Type/StringSourceLocatorTest.php index 60cacae3c..dd9f173fd 100644 --- a/test/unit/SourceLocator/Type/StringSourceLocatorTest.php +++ b/test/unit/SourceLocator/Type/StringSourceLocatorTest.php @@ -26,7 +26,10 @@ protected function setUp(): void $this->astLocator = BetterReflectionSingleton::instance()->astLocator(); } - private function getMockReflector(): Reflector|MockObject + /** + * @return \Roave\BetterReflection\Reflector\Reflector|\PHPUnit\Framework\MockObject\MockObject + */ + private function getMockReflector() { return $this->createMock(Reflector::class); } diff --git a/test/unit/Util/ClassExistenceCheckerTest.php b/test/unit/Util/ClassExistenceCheckerTest.php index b5d483a70..66a333776 100644 --- a/test/unit/Util/ClassExistenceCheckerTest.php +++ b/test/unit/Util/ClassExistenceCheckerTest.php @@ -22,7 +22,10 @@ #[CoversClass(ClassExistenceChecker::class)] class ClassExistenceCheckerTest extends TestCase { - private Closure|null $loader = null; + /** + * @var \Closure|null + */ + private $loader = null; protected function setUp(): void { diff --git a/test/unit/Util/Exception/NoNodePositionTest.php b/test/unit/Util/Exception/NoNodePositionTest.php index ecfafee5c..dbc5d180c 100644 --- a/test/unit/Util/Exception/NoNodePositionTest.php +++ b/test/unit/Util/Exception/NoNodePositionTest.php @@ -22,6 +22,6 @@ public function testFromPosition(): void $exception = NoNodePosition::fromNode($node); self::assertInstanceOf(NoNodePosition::class, $exception); - self::assertSame(sprintf('%s doesn\'t contain position. Your %s is not configured properly', $node::class, Lexer::class), $exception->getMessage()); + self::assertSame(sprintf('%s doesn\'t contain position. Your %s is not configured properly', get_class($node), Lexer::class), $exception->getMessage()); } }