Skip to content

Commit 86733dc

Browse files
authored
Merge pull request #226 from phpDocumentor/fix-resolve-all-fqsen-formats
Fix FQSEN resolving on see,covers,uses
2 parents 08c0b36 + 73650dd commit 86733dc

File tree

5 files changed

+119
-4
lines changed

5 files changed

+119
-4
lines changed

src/DocBlock/Tags/Covers.php

+16-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
use phpDocumentor\Reflection\Types\Context as TypeContext;
2121
use phpDocumentor\Reflection\Utils;
2222
use Webmozart\Assert\Assert;
23+
use function array_key_exists;
24+
use function explode;
2325

2426
/**
2527
* Reflection class for a @covers tag in a Docblock.
@@ -54,11 +56,24 @@ public static function create(
5456
$parts = Utils::pregSplit('/\s+/Su', $body, 2);
5557

5658
return new static(
57-
$resolver->resolve($parts[0], $context),
59+
self::resolveFqsen($parts[0], $resolver, $context),
5860
$descriptionFactory->create($parts[1] ?? '', $context)
5961
);
6062
}
6163

64+
private static function resolveFqsen(string $parts, ?FqsenResolver $fqsenResolver, ?TypeContext $context) : Fqsen
65+
{
66+
Assert::notNull($fqsenResolver);
67+
$fqsenParts = explode('::', $parts);
68+
$resolved = $fqsenResolver->resolve($fqsenParts[0], $context);
69+
70+
if (!array_key_exists(1, $fqsenParts)) {
71+
return $resolved;
72+
}
73+
74+
return new Fqsen($resolved . '::' . $fqsenParts[1]);
75+
}
76+
6277
/**
6378
* Returns the structural element this tag refers to.
6479
*/

src/DocBlock/Tags/See.php

+17-2
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,13 @@
1818
use phpDocumentor\Reflection\DocBlock\Tags\Reference\Fqsen as FqsenRef;
1919
use phpDocumentor\Reflection\DocBlock\Tags\Reference\Reference;
2020
use phpDocumentor\Reflection\DocBlock\Tags\Reference\Url;
21+
use phpDocumentor\Reflection\Fqsen;
2122
use phpDocumentor\Reflection\FqsenResolver;
2223
use phpDocumentor\Reflection\Types\Context as TypeContext;
2324
use phpDocumentor\Reflection\Utils;
2425
use Webmozart\Assert\Assert;
26+
use function array_key_exists;
27+
use function explode;
2528
use function preg_match;
2629

2730
/**
@@ -50,7 +53,6 @@ public static function create(
5053
?DescriptionFactory $descriptionFactory = null,
5154
?TypeContext $context = null
5255
) : self {
53-
Assert::notNull($typeResolver);
5456
Assert::notNull($descriptionFactory);
5557

5658
$parts = Utils::pregSplit('/\s+/Su', $body, 2);
@@ -61,7 +63,20 @@ public static function create(
6163
return new static(new Url($parts[0]), $description);
6264
}
6365

64-
return new static(new FqsenRef($typeResolver->resolve($parts[0], $context)), $description);
66+
return new static(new FqsenRef(self::resolveFqsen($parts[0], $typeResolver, $context)), $description);
67+
}
68+
69+
private static function resolveFqsen(string $parts, ?FqsenResolver $fqsenResolver, ?TypeContext $context) : Fqsen
70+
{
71+
Assert::notNull($fqsenResolver);
72+
$fqsenParts = explode('::', $parts);
73+
$resolved = $fqsenResolver->resolve($fqsenParts[0], $context);
74+
75+
if (!array_key_exists(1, $fqsenParts)) {
76+
return $resolved;
77+
}
78+
79+
return new Fqsen($resolved . '::' . $fqsenParts[1]);
6580
}
6681

6782
/**

src/DocBlock/Tags/Uses.php

+16-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
use phpDocumentor\Reflection\Types\Context as TypeContext;
2121
use phpDocumentor\Reflection\Utils;
2222
use Webmozart\Assert\Assert;
23+
use function array_key_exists;
24+
use function explode;
2325

2426
/**
2527
* Reflection class for a {@}uses tag in a Docblock.
@@ -53,11 +55,24 @@ public static function create(
5355
$parts = Utils::pregSplit('/\s+/Su', $body, 2);
5456

5557
return new static(
56-
$resolver->resolve($parts[0], $context),
58+
self::resolveFqsen($parts[0], $resolver, $context),
5759
$descriptionFactory->create($parts[1] ?? '', $context)
5860
);
5961
}
6062

63+
private static function resolveFqsen(string $parts, ?FqsenResolver $fqsenResolver, ?TypeContext $context) : Fqsen
64+
{
65+
Assert::notNull($fqsenResolver);
66+
$fqsenParts = explode('::', $parts);
67+
$resolved = $fqsenResolver->resolve($fqsenParts[0], $context);
68+
69+
if (!array_key_exists(1, $fqsenParts)) {
70+
return $resolved;
71+
}
72+
73+
return new Fqsen($resolved . '::' . $fqsenParts[1]);
74+
}
75+
6176
/**
6277
* Returns the structural element this tag refers to.
6378
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace phpDocumentor\Reflection;
6+
7+
use phpDocumentor\Reflection\DocBlock\Tags\See;
8+
use phpDocumentor\Reflection\Types\Context;
9+
use PHPUnit\Framework\TestCase;
10+
11+
class DocblockSeeTagResolvingTest extends TestCase
12+
{
13+
public function testResolvesSeeFQSENOfInlineTags()
14+
{
15+
$context = new Context('\Project\Sub\Level', ['Issue2425B' => '\Project\Other\Level\Issue2425B', 'Aliased' => 'Project\Other\Level\Issue2425C']);
16+
$docblockString = <<<DOCBLOCK
17+
/**
18+
* Class summary.
19+
*
20+
* A description containing an inline {@see Issue2425B::bar()} tag
21+
* to a class inside of the project referenced via a use statement.
22+
*
23+
* And here is another inline {@see Aliased::bar()} tag to a class
24+
* aliased via a use statement.
25+
*/
26+
DOCBLOCK;
27+
28+
29+
30+
$factory = DocBlockFactory::createInstance();
31+
$docblock = $factory->create($docblockString, $context);
32+
33+
/** @var See $see1 */
34+
$see1 = $docblock->getDescription()->getTags()[0];
35+
36+
$this->assertSame('\Project\Other\Level\Issue2425B::bar()', (string)$see1->getReference());
37+
}
38+
}

tests/unit/DocBlock/Tags/SeeTest.php

+32
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,38 @@ public function testFactoryMethod() : void
167167
$this->assertSame($description, $fixture->getDescription());
168168
}
169169

170+
/**
171+
* @uses \phpDocumentor\Reflection\DocBlock\Tags\See::<public>
172+
* @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory
173+
* @uses \phpDocumentor\Reflection\FqsenResolver
174+
* @uses \phpDocumentor\Reflection\DocBlock\Description
175+
* @uses \phpDocumentor\Reflection\DocBlock\Tags\Reference\Fqsen
176+
* @uses \phpDocumentor\Reflection\Fqsen
177+
* @uses \phpDocumentor\Reflection\Types\Context
178+
*
179+
* @covers ::create
180+
*/
181+
public function testFactoryMethodWithNonClassFQSEN() : void
182+
{
183+
$descriptionFactory = m::mock(DescriptionFactory::class);
184+
$resolver = m::mock(FqsenResolver::class);
185+
$context = new Context('');
186+
187+
$fqsen = new Fqsen('\DateTime');
188+
$description = new Description('My Description');
189+
190+
$descriptionFactory
191+
->shouldReceive('create')->with('My Description', $context)->andReturn($description);
192+
$resolver->shouldReceive('resolve')->with('DateTime', $context)->andReturn($fqsen);
193+
194+
$fixture = See::create('DateTime::createFromFormat() My Description', $resolver, $descriptionFactory, $context);
195+
196+
$this->assertSame('\DateTime::createFromFormat() My Description', (string) $fixture);
197+
$this->assertInstanceOf(FqsenRef::class, $fixture->getReference());
198+
$this->assertSame('\DateTime::createFromFormat()', (string) $fixture->getReference());
199+
$this->assertSame($description, $fixture->getDescription());
200+
}
201+
170202
/**
171203
* @uses \phpDocumentor\Reflection\DocBlock\Tags\See::<public>
172204
* @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory

0 commit comments

Comments
 (0)