mirror of
https://github.com/barryvdh/ReflectionDocBlock.git
synced 2026-08-18 01:57:13 +00:00
Fix FQSEN resolving on see,covers,uses
The See, Covers and Use tags can reference also methods, properties and constants. Which means that the FqsenResolver cannot handle those properly. This patch fixes that issue.
This commit is contained in:
@@ -20,6 +20,8 @@ use phpDocumentor\Reflection\FqsenResolver;
|
|||||||
use phpDocumentor\Reflection\Types\Context as TypeContext;
|
use phpDocumentor\Reflection\Types\Context as TypeContext;
|
||||||
use phpDocumentor\Reflection\Utils;
|
use phpDocumentor\Reflection\Utils;
|
||||||
use Webmozart\Assert\Assert;
|
use Webmozart\Assert\Assert;
|
||||||
|
use function array_key_exists;
|
||||||
|
use function explode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reflection class for a @covers tag in a Docblock.
|
* Reflection class for a @covers tag in a Docblock.
|
||||||
@@ -54,11 +56,24 @@ final class Covers extends BaseTag implements Factory\StaticMethod
|
|||||||
$parts = Utils::pregSplit('/\s+/Su', $body, 2);
|
$parts = Utils::pregSplit('/\s+/Su', $body, 2);
|
||||||
|
|
||||||
return new static(
|
return new static(
|
||||||
$resolver->resolve($parts[0], $context),
|
self::resolveFqsen($parts[0], $resolver, $context),
|
||||||
$descriptionFactory->create($parts[1] ?? '', $context)
|
$descriptionFactory->create($parts[1] ?? '', $context)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static function resolveFqsen(string $parts, ?FqsenResolver $fqsenResolver, ?TypeContext $context) : Fqsen
|
||||||
|
{
|
||||||
|
Assert::notNull($fqsenResolver);
|
||||||
|
$fqsenParts = explode('::', $parts);
|
||||||
|
$resolved = $fqsenResolver->resolve($fqsenParts[0], $context);
|
||||||
|
|
||||||
|
if (!array_key_exists(1, $fqsenParts)) {
|
||||||
|
return $resolved;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Fqsen($resolved . '::' . $fqsenParts[1]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the structural element this tag refers to.
|
* Returns the structural element this tag refers to.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -18,10 +18,13 @@ use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
|
|||||||
use phpDocumentor\Reflection\DocBlock\Tags\Reference\Fqsen as FqsenRef;
|
use phpDocumentor\Reflection\DocBlock\Tags\Reference\Fqsen as FqsenRef;
|
||||||
use phpDocumentor\Reflection\DocBlock\Tags\Reference\Reference;
|
use phpDocumentor\Reflection\DocBlock\Tags\Reference\Reference;
|
||||||
use phpDocumentor\Reflection\DocBlock\Tags\Reference\Url;
|
use phpDocumentor\Reflection\DocBlock\Tags\Reference\Url;
|
||||||
|
use phpDocumentor\Reflection\Fqsen;
|
||||||
use phpDocumentor\Reflection\FqsenResolver;
|
use phpDocumentor\Reflection\FqsenResolver;
|
||||||
use phpDocumentor\Reflection\Types\Context as TypeContext;
|
use phpDocumentor\Reflection\Types\Context as TypeContext;
|
||||||
use phpDocumentor\Reflection\Utils;
|
use phpDocumentor\Reflection\Utils;
|
||||||
use Webmozart\Assert\Assert;
|
use Webmozart\Assert\Assert;
|
||||||
|
use function array_key_exists;
|
||||||
|
use function explode;
|
||||||
use function preg_match;
|
use function preg_match;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -50,7 +53,6 @@ final class See extends BaseTag implements Factory\StaticMethod
|
|||||||
?DescriptionFactory $descriptionFactory = null,
|
?DescriptionFactory $descriptionFactory = null,
|
||||||
?TypeContext $context = null
|
?TypeContext $context = null
|
||||||
) : self {
|
) : self {
|
||||||
Assert::notNull($typeResolver);
|
|
||||||
Assert::notNull($descriptionFactory);
|
Assert::notNull($descriptionFactory);
|
||||||
|
|
||||||
$parts = Utils::pregSplit('/\s+/Su', $body, 2);
|
$parts = Utils::pregSplit('/\s+/Su', $body, 2);
|
||||||
@@ -61,7 +63,20 @@ final class See extends BaseTag implements Factory\StaticMethod
|
|||||||
return new static(new Url($parts[0]), $description);
|
return new static(new Url($parts[0]), $description);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new static(new FqsenRef($typeResolver->resolve($parts[0], $context)), $description);
|
return new static(new FqsenRef(self::resolveFqsen($parts[0], $typeResolver, $context)), $description);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function resolveFqsen(string $parts, ?FqsenResolver $fqsenResolver, ?TypeContext $context) : Fqsen
|
||||||
|
{
|
||||||
|
Assert::notNull($fqsenResolver);
|
||||||
|
$fqsenParts = explode('::', $parts);
|
||||||
|
$resolved = $fqsenResolver->resolve($fqsenParts[0], $context);
|
||||||
|
|
||||||
|
if (!array_key_exists(1, $fqsenParts)) {
|
||||||
|
return $resolved;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Fqsen($resolved . '::' . $fqsenParts[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ use phpDocumentor\Reflection\FqsenResolver;
|
|||||||
use phpDocumentor\Reflection\Types\Context as TypeContext;
|
use phpDocumentor\Reflection\Types\Context as TypeContext;
|
||||||
use phpDocumentor\Reflection\Utils;
|
use phpDocumentor\Reflection\Utils;
|
||||||
use Webmozart\Assert\Assert;
|
use Webmozart\Assert\Assert;
|
||||||
|
use function array_key_exists;
|
||||||
|
use function explode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reflection class for a {@}uses tag in a Docblock.
|
* Reflection class for a {@}uses tag in a Docblock.
|
||||||
@@ -53,11 +55,24 @@ final class Uses extends BaseTag implements Factory\StaticMethod
|
|||||||
$parts = Utils::pregSplit('/\s+/Su', $body, 2);
|
$parts = Utils::pregSplit('/\s+/Su', $body, 2);
|
||||||
|
|
||||||
return new static(
|
return new static(
|
||||||
$resolver->resolve($parts[0], $context),
|
self::resolveFqsen($parts[0], $resolver, $context),
|
||||||
$descriptionFactory->create($parts[1] ?? '', $context)
|
$descriptionFactory->create($parts[1] ?? '', $context)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static function resolveFqsen(string $parts, ?FqsenResolver $fqsenResolver, ?TypeContext $context) : Fqsen
|
||||||
|
{
|
||||||
|
Assert::notNull($fqsenResolver);
|
||||||
|
$fqsenParts = explode('::', $parts);
|
||||||
|
$resolved = $fqsenResolver->resolve($fqsenParts[0], $context);
|
||||||
|
|
||||||
|
if (!array_key_exists(1, $fqsenParts)) {
|
||||||
|
return $resolved;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Fqsen($resolved . '::' . $fqsenParts[1]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the structural element this tag refers to.
|
* Returns the structural element this tag refers to.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace phpDocumentor\Reflection;
|
||||||
|
|
||||||
|
use phpDocumentor\Reflection\DocBlock\Tags\See;
|
||||||
|
use phpDocumentor\Reflection\Types\Context;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class DocblockSeeTagResolvingTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testResolvesSeeFQSENOfInlineTags()
|
||||||
|
{
|
||||||
|
$context = new Context('\Project\Sub\Level', ['Issue2425B' => '\Project\Other\Level\Issue2425B', 'Aliased' => 'Project\Other\Level\Issue2425C']);
|
||||||
|
$docblockString = <<<DOCBLOCK
|
||||||
|
/**
|
||||||
|
* Class summary.
|
||||||
|
*
|
||||||
|
* A description containing an inline {@see Issue2425B::bar()} tag
|
||||||
|
* to a class inside of the project referenced via a use statement.
|
||||||
|
*
|
||||||
|
* And here is another inline {@see Aliased::bar()} tag to a class
|
||||||
|
* aliased via a use statement.
|
||||||
|
*/
|
||||||
|
DOCBLOCK;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$factory = DocBlockFactory::createInstance();
|
||||||
|
$docblock = $factory->create($docblockString, $context);
|
||||||
|
|
||||||
|
/** @var See $see1 */
|
||||||
|
$see1 = $docblock->getDescription()->getTags()[0];
|
||||||
|
|
||||||
|
$this->assertSame('\Project\Other\Level\Issue2425B::bar()', (string)$see1->getReference());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -167,6 +167,38 @@ class SeeTest extends TestCase
|
|||||||
$this->assertSame($description, $fixture->getDescription());
|
$this->assertSame($description, $fixture->getDescription());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @uses \phpDocumentor\Reflection\DocBlock\Tags\See::<public>
|
||||||
|
* @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory
|
||||||
|
* @uses \phpDocumentor\Reflection\FqsenResolver
|
||||||
|
* @uses \phpDocumentor\Reflection\DocBlock\Description
|
||||||
|
* @uses \phpDocumentor\Reflection\DocBlock\Tags\Reference\Fqsen
|
||||||
|
* @uses \phpDocumentor\Reflection\Fqsen
|
||||||
|
* @uses \phpDocumentor\Reflection\Types\Context
|
||||||
|
*
|
||||||
|
* @covers ::create
|
||||||
|
*/
|
||||||
|
public function testFactoryMethodWithNonClassFQSEN() : void
|
||||||
|
{
|
||||||
|
$descriptionFactory = m::mock(DescriptionFactory::class);
|
||||||
|
$resolver = m::mock(FqsenResolver::class);
|
||||||
|
$context = new Context('');
|
||||||
|
|
||||||
|
$fqsen = new Fqsen('\DateTime');
|
||||||
|
$description = new Description('My Description');
|
||||||
|
|
||||||
|
$descriptionFactory
|
||||||
|
->shouldReceive('create')->with('My Description', $context)->andReturn($description);
|
||||||
|
$resolver->shouldReceive('resolve')->with('DateTime', $context)->andReturn($fqsen);
|
||||||
|
|
||||||
|
$fixture = See::create('DateTime::createFromFormat() My Description', $resolver, $descriptionFactory, $context);
|
||||||
|
|
||||||
|
$this->assertSame('\DateTime::createFromFormat() My Description', (string) $fixture);
|
||||||
|
$this->assertInstanceOf(FqsenRef::class, $fixture->getReference());
|
||||||
|
$this->assertSame('\DateTime::createFromFormat()', (string) $fixture->getReference());
|
||||||
|
$this->assertSame($description, $fixture->getDescription());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @uses \phpDocumentor\Reflection\DocBlock\Tags\See::<public>
|
* @uses \phpDocumentor\Reflection\DocBlock\Tags\See::<public>
|
||||||
* @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory
|
* @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory
|
||||||
|
|||||||
Reference in New Issue
Block a user