Initial commit
This commit is contained in:
137
vendor/nesbot/carbon/src/Carbon/PHPStan/MacroExtension.php
vendored
Normal file
137
vendor/nesbot/carbon/src/Carbon/PHPStan/MacroExtension.php
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* This file is part of the Carbon package.
|
||||
*
|
||||
* (c) Brian Nesbitt <brian@nesbot.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Carbon\PHPStan;
|
||||
|
||||
use Carbon\CarbonInterface;
|
||||
use Carbon\FactoryImmutable;
|
||||
use Closure;
|
||||
use InvalidArgumentException;
|
||||
use PHPStan\Reflection\ClassReflection;
|
||||
use PHPStan\Reflection\MethodReflection;
|
||||
use PHPStan\Reflection\MethodsClassReflectionExtension;
|
||||
use PHPStan\Reflection\ReflectionProvider;
|
||||
use PHPStan\Type\ClosureTypeFactory;
|
||||
use ReflectionFunction;
|
||||
use ReflectionMethod;
|
||||
use stdClass;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Class MacroExtension.
|
||||
*
|
||||
* @codeCoverageIgnore Pure PHPStan wrapper.
|
||||
*/
|
||||
final class MacroExtension implements MethodsClassReflectionExtension
|
||||
{
|
||||
/**
|
||||
* @var ReflectionProvider
|
||||
*/
|
||||
protected $reflectionProvider;
|
||||
|
||||
/**
|
||||
* @var ClosureTypeFactory
|
||||
*/
|
||||
protected $closureTypeFactory;
|
||||
|
||||
/**
|
||||
* Extension constructor.
|
||||
*
|
||||
* @param ReflectionProvider $reflectionProvider
|
||||
* @param ClosureTypeFactory $closureTypeFactory
|
||||
*/
|
||||
public function __construct(
|
||||
ReflectionProvider $reflectionProvider,
|
||||
ClosureTypeFactory $closureTypeFactory
|
||||
) {
|
||||
$this->reflectionProvider = $reflectionProvider;
|
||||
$this->closureTypeFactory = $closureTypeFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasMethod(ClassReflection $classReflection, string $methodName): bool
|
||||
{
|
||||
if (
|
||||
$classReflection->getName() !== CarbonInterface::class &&
|
||||
!$classReflection->isSubclassOf(CarbonInterface::class)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$className = $classReflection->getName();
|
||||
|
||||
return \is_callable([$className, 'hasMacro']) &&
|
||||
$className::hasMacro($methodName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMethod(ClassReflection $classReflection, string $methodName): MethodReflection
|
||||
{
|
||||
$macros = FactoryImmutable::getDefaultInstance()->getSettings()['macros'] ?? [];
|
||||
$macro = $macros[$methodName] ?? throw new InvalidArgumentException("Macro '$methodName' not found");
|
||||
$static = false;
|
||||
$final = false;
|
||||
$deprecated = false;
|
||||
$docComment = null;
|
||||
|
||||
if (\is_array($macro) && \count($macro) === 2 && \is_string($macro[1])) {
|
||||
\assert($macro[1] !== '');
|
||||
|
||||
$reflection = new ReflectionMethod($macro[0], $macro[1]);
|
||||
$closure = \is_object($macro[0]) ? $reflection->getClosure($macro[0]) : $reflection->getClosure();
|
||||
|
||||
$static = $reflection->isStatic();
|
||||
$final = $reflection->isFinal();
|
||||
$deprecated = $reflection->isDeprecated();
|
||||
$docComment = $reflection->getDocComment() ?: null;
|
||||
} elseif (\is_string($macro)) {
|
||||
$reflection = new ReflectionFunction($macro);
|
||||
$closure = $reflection->getClosure();
|
||||
$deprecated = $reflection->isDeprecated();
|
||||
$docComment = $reflection->getDocComment() ?: null;
|
||||
} elseif ($macro instanceof Closure) {
|
||||
$closure = $macro;
|
||||
|
||||
try {
|
||||
$boundClosure = Closure::bind($closure, new stdClass());
|
||||
$static = (!$boundClosure || (new ReflectionFunction($boundClosure))->getClosureThis() === null);
|
||||
} catch (Throwable) {
|
||||
$static = true;
|
||||
}
|
||||
|
||||
$reflection = new ReflectionFunction($macro);
|
||||
$deprecated = $reflection->isDeprecated();
|
||||
$docComment = $reflection->getDocComment() ?: null;
|
||||
}
|
||||
|
||||
if (!isset($closure)) {
|
||||
throw new InvalidArgumentException('Could not create reflection from the spec given'); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$closureType = $this->closureTypeFactory->fromClosureObject($closure);
|
||||
|
||||
return new MacroMethodReflection(
|
||||
$classReflection,
|
||||
$methodName,
|
||||
$closureType,
|
||||
$static,
|
||||
$final,
|
||||
$deprecated,
|
||||
$docComment,
|
||||
);
|
||||
}
|
||||
}
|
||||
124
vendor/nesbot/carbon/src/Carbon/PHPStan/MacroMethodReflection.php
vendored
Normal file
124
vendor/nesbot/carbon/src/Carbon/PHPStan/MacroMethodReflection.php
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* This file is part of the Carbon package.
|
||||
*
|
||||
* (c) Brian Nesbitt <brian@nesbot.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Carbon\PHPStan;
|
||||
|
||||
use PHPStan\Reflection\ClassReflection;
|
||||
use PHPStan\Reflection\MethodReflection;
|
||||
use PHPStan\Reflection\ParametersAcceptor;
|
||||
use PHPStan\TrinaryLogic;
|
||||
use PHPStan\Type\Type;
|
||||
|
||||
use function preg_match;
|
||||
|
||||
class MacroMethodReflection implements MethodReflection
|
||||
{
|
||||
private ClassReflection $declaringClass;
|
||||
private string $methodName;
|
||||
private ParametersAcceptor $macroClosureType;
|
||||
private bool $static;
|
||||
private bool $final;
|
||||
private bool $deprecated;
|
||||
private ?string $docComment;
|
||||
|
||||
public function __construct(
|
||||
ClassReflection $declaringClass,
|
||||
string $methodName,
|
||||
ParametersAcceptor $macroClosureType,
|
||||
bool $static,
|
||||
bool $final,
|
||||
bool $deprecated,
|
||||
?string $docComment
|
||||
) {
|
||||
$this->declaringClass = $declaringClass;
|
||||
$this->methodName = $methodName;
|
||||
$this->macroClosureType = $macroClosureType;
|
||||
$this->static = $static;
|
||||
$this->final = $final;
|
||||
$this->deprecated = $deprecated;
|
||||
$this->docComment = $docComment;
|
||||
}
|
||||
|
||||
public function getDeclaringClass(): ClassReflection
|
||||
{
|
||||
return $this->declaringClass;
|
||||
}
|
||||
|
||||
public function isStatic(): bool
|
||||
{
|
||||
return $this->static;
|
||||
}
|
||||
|
||||
public function isPrivate(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isPublic(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDocComment(): ?string
|
||||
{
|
||||
return $this->docComment;
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->methodName;
|
||||
}
|
||||
|
||||
public function getPrototype(): \PHPStan\Reflection\ClassMemberReflection
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getVariants(): array
|
||||
{
|
||||
return [$this->macroClosureType];
|
||||
}
|
||||
|
||||
public function isDeprecated(): TrinaryLogic
|
||||
{
|
||||
return TrinaryLogic::createFromBoolean(
|
||||
$this->deprecated ||
|
||||
preg_match('/@deprecated/i', $this->getDocComment() ?: '')
|
||||
);
|
||||
}
|
||||
|
||||
public function getDeprecatedDescription(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function isFinal(): TrinaryLogic
|
||||
{
|
||||
return TrinaryLogic::createFromBoolean($this->final);
|
||||
}
|
||||
|
||||
public function isInternal(): TrinaryLogic
|
||||
{
|
||||
return TrinaryLogic::createNo();
|
||||
}
|
||||
|
||||
public function getThrowType(): ?Type
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function hasSideEffects(): TrinaryLogic
|
||||
{
|
||||
return TrinaryLogic::createMaybe();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user