mirror of
https://github.com/rectorphp/rector.git
synced 2025-02-23 03:02:33 +01:00
* remove doctrine/annotations * Refactor doctrine/annotation parser to static reflection with phpdoc-parser * remove doctirne-annotation-parser-syncer * remove annotation stubs * use nodes * almost there * [ci-review] Rector Rectify * skip temporary * phpstan: remove fixed messages Co-authored-by: kaizen-ci <info@kaizen-ci.org>
106 lines
3.1 KiB
PHP
106 lines
3.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Rector\BetterPhpDocParser\PhpDocNodeFactory;
|
|
|
|
use Nette\Utils\Strings;
|
|
use PhpParser\Node;
|
|
use PHPStan\Analyser\Scope;
|
|
use PHPStan\Reflection\ReflectionProvider;
|
|
use PHPStan\Type\ObjectType;
|
|
use Rector\BetterPhpDocParser\ValueObject\AroundSpaces;
|
|
use Rector\NodeTypeResolver\Node\AttributeKey;
|
|
use Rector\StaticTypeMapper\ValueObject\Type\ShortenedObjectType;
|
|
use Rector\TypeDeclaration\PHPStan\Type\ObjectTypeSpecifier;
|
|
|
|
abstract class AbstractPhpDocNodeFactory
|
|
{
|
|
/**
|
|
* @var string
|
|
* @see https://regex101.com/r/548EJJ/1
|
|
*/
|
|
private const CLASS_CONST_REGEX = '#::class#';
|
|
|
|
/**
|
|
* @var string
|
|
* @see https://regex101.com/r/CsmMaz/1
|
|
*/
|
|
private const OPENING_SPACE_REGEX = '#^\{(?<opening_space>\s+)#';
|
|
|
|
/**
|
|
* @var string
|
|
* @see https://regex101.com/r/Rrbi3V/1
|
|
*/
|
|
private const CLOSING_SPACE_REGEX = '#(?<closing_space>\s+)\}$#';
|
|
|
|
/**
|
|
* @var ObjectTypeSpecifier
|
|
*/
|
|
private $objectTypeSpecifier;
|
|
|
|
/**
|
|
* @var ReflectionProvider
|
|
*/
|
|
private $reflectionProvider;
|
|
|
|
/**
|
|
* @required
|
|
*/
|
|
public function autowireAbstractPhpDocNodeFactory(
|
|
ObjectTypeSpecifier $objectTypeSpecifier,
|
|
ReflectionProvider $reflectionProvider
|
|
): void {
|
|
$this->objectTypeSpecifier = $objectTypeSpecifier;
|
|
$this->reflectionProvider = $reflectionProvider;
|
|
}
|
|
|
|
protected function resolveFqnTargetEntity(string $targetEntity, Node $node): string
|
|
{
|
|
$targetEntity = $this->getCleanedUpTargetEntity($targetEntity);
|
|
if ($this->reflectionProvider->hasClass($targetEntity)) {
|
|
return $targetEntity;
|
|
}
|
|
|
|
$scope = $node->getAttribute(AttributeKey::SCOPE);
|
|
if (! $scope instanceof Scope) {
|
|
return $targetEntity;
|
|
}
|
|
|
|
$namespacedTargetEntity = $scope->getNamespace() . '\\' . $targetEntity;
|
|
if ($this->reflectionProvider->hasClass($namespacedTargetEntity)) {
|
|
return $namespacedTargetEntity;
|
|
}
|
|
|
|
$resolvedType = $this->objectTypeSpecifier->narrowToFullyQualifiedOrAliasedObjectType(
|
|
$node,
|
|
new ObjectType($targetEntity)
|
|
);
|
|
if ($resolvedType instanceof ShortenedObjectType) {
|
|
return $resolvedType->getFullyQualifiedName();
|
|
}
|
|
|
|
// probably tested class
|
|
return $targetEntity;
|
|
}
|
|
|
|
/**
|
|
* Covers spaces like https://github.com/rectorphp/rector/issues/2110
|
|
*/
|
|
protected function matchCurlyBracketAroundSpaces(string $annotationContent): AroundSpaces
|
|
{
|
|
$match = Strings::match($annotationContent, self::OPENING_SPACE_REGEX);
|
|
$openingSpace = $match['opening_space'] ?? '';
|
|
|
|
$match = Strings::match($annotationContent, self::CLOSING_SPACE_REGEX);
|
|
$closingSpace = $match['closing_space'] ?? '';
|
|
|
|
return new AroundSpaces($openingSpace, $closingSpace);
|
|
}
|
|
|
|
private function getCleanedUpTargetEntity(string $targetEntity): string
|
|
{
|
|
return Strings::replace($targetEntity, self::CLASS_CONST_REGEX, '');
|
|
}
|
|
}
|