Skip to content

Commit be887d2

Browse files
committed
Improve tag parsing
1 parent b4b0c09 commit be887d2

File tree

5 files changed

+36
-28
lines changed

5 files changed

+36
-28
lines changed

src/DocBlock/Tag/Factory/TagFactory.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public function create(string $tag, string $content, DescriptionParserInterface
6565

6666
$description = null;
6767

68-
if ($content === '') {
68+
if ($content !== '') {
6969
$description = $descriptions->parse($content);
7070
}
7171

src/DocBlock/Tag/InvalidTag.php

+12-6
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,35 @@ final class InvalidTag extends Tag implements InvalidTagInterface
99
/**
1010
* @var non-empty-string
1111
*/
12-
public const DEFAULT_UNKNOWN_TAG_NAME = '<unknown>';
12+
public const DEFAULT_UNKNOWN_TAG_NAME = 'invalid';
13+
14+
private readonly bool $isUnknownName;
1315

1416
/**
1517
* @param non-empty-string $name
1618
*/
1719
public function __construct(
1820
public readonly \Throwable $reason,
1921
\Stringable|string|null $description = null,
20-
string $name = self::DEFAULT_UNKNOWN_TAG_NAME,
22+
?string $name = null,
2123
) {
22-
parent::__construct($name, $description);
24+
$this->isUnknownName = $name === null;
25+
26+
parent::__construct($name ?? self::DEFAULT_UNKNOWN_TAG_NAME, $description);
2327
}
2428

2529
public function __toString(): string
2630
{
27-
$name = $this->name === self::DEFAULT_UNKNOWN_TAG_NAME ? '' : $this->name;
31+
if ($this->isUnknownName) {
32+
return \sprintf('@%s', $this->description);
33+
}
2834

2935
if ($this->description === null) {
30-
return \sprintf('@%s', $name);
36+
return \sprintf('@%s', $this->name);
3137
}
3238

3339
return \rtrim(\vsprintf('@%s %s', [
34-
$name,
40+
$this->name,
3541
(string) $this->description,
3642
]));
3743
}

src/Parser/Description/RegexDescriptionParser.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public function parse(string $description): DescriptionInterface
5454
private function createFromChunk(string $chunk): DescriptionInterface|TagInterface
5555
{
5656
if ($chunk === '@') {
57-
return new Description('{' . $chunk . '}');
57+
return new Description('{@}');
5858
}
5959

6060
if (\str_starts_with($chunk, '@')) {

src/Parser/Tag/RegexTagParser.php

+1-3
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,7 @@ public function parse(string $tag, DescriptionParserInterface $parser): TagInter
6767
try {
6868
$name = $this->getTagName($tag);
6969
} catch (InvalidTagNameException $e) {
70-
return new InvalidTag($e, $parser->parse(
71-
description: \substr($tag, 1),
72-
));
70+
return new InvalidTag($e, description: $tag);
7371
}
7472

7573
/** @var non-empty-string $name */

tests/Unit/DescriptionParserTest.php

+21-17
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@
55
namespace TypeLang\PHPDoc\Tests\Unit;
66

77
use PHPUnit\Framework\Attributes\DataProvider;
8-
use TypeLang\PHPDoc\DocBlock\Tag\Content\Stream;
9-
use TypeLang\PHPDoc\DocBlock\Tag\Description\Description;
10-
use TypeLang\PHPDoc\DocBlock\Tag\Description\TaggedDescription;
11-
use TypeLang\PHPDoc\DocBlock\Tag\Description\TaggedDescriptionInterface;
8+
use TypeLang\PHPDoc\DocBlock\Description\Description;
9+
use TypeLang\PHPDoc\DocBlock\Description\TaggedDescription;
10+
use TypeLang\PHPDoc\DocBlock\Description\TaggedDescriptionInterface;
1211
use TypeLang\PHPDoc\DocBlock\Tag\Factory\TagFactory;
1312
use TypeLang\PHPDoc\DocBlock\Tag\Factory\TagFactoryInterface;
1413
use TypeLang\PHPDoc\DocBlock\Tag\InvalidTag;
@@ -24,9 +23,12 @@ public static function parserDataProvider(): iterable
2423
{
2524
$tags = new TagFactory([
2625
'error' => new class implements TagFactoryInterface {
27-
public function create(Stream $tag, DescriptionParserInterface $descriptions): TagInterface
28-
{
29-
throw new \LogicException('Error tag ' . $tag->getName());
26+
public function create(
27+
string $tag,
28+
string $content,
29+
DescriptionParserInterface $descriptions
30+
): TagInterface {
31+
throw new \LogicException('Error tag ' . $tag);
3032
}
3133
},
3234
]);
@@ -123,14 +125,15 @@ public function testDescriptionWithBadTagName(DescriptionParserInterface $parser
123125
$description = $parser->parse('Hello {@@} World!');
124126

125127
self::assertInstanceOf(TaggedDescriptionInterface::class, $description);
126-
self::assertCount(3, $description);
127-
self::assertInstanceOf(InvalidTag::class, $description[1]);
128+
self::assertCount(3, $description->components);
129+
self::assertCount(1, $description);
130+
self::assertInstanceOf(InvalidTag::class, $description[0]);
128131

129-
$reason = $description[1]->reason;
132+
$reason = $description[0]->reason;
130133

131134
self::assertSame('Tag name cannot be empty', $reason->getMessage());
132-
self::assertSame(InvalidTag::DEFAULT_UNKNOWN_TAG_NAME, $description[1]->getName());
133-
self::assertEquals(new Description('{@}'), $description[1]->getDescription());
135+
self::assertSame(InvalidTag::DEFAULT_UNKNOWN_TAG_NAME, $description[0]->name);
136+
self::assertEquals(new Description('@@'), $description[0]->description);
134137
}
135138

136139
#[DataProvider('parserDataProvider')]
@@ -139,13 +142,14 @@ public function testErrorWhileParsingInline(DescriptionParserInterface $parser):
139142
$description = $parser->parse('Hello {@error description} World!');
140143

141144
self::assertInstanceOf(TaggedDescriptionInterface::class, $description);
142-
self::assertCount(3, $description);
143-
self::assertInstanceOf(InvalidTag::class, $description[1]);
145+
self::assertCount(3, $description->components);
146+
self::assertCount(1, $description);
147+
self::assertInstanceOf(InvalidTag::class, $description[0]);
144148

145-
$reason = $description[1]->reason;
149+
$reason = $description[0]->reason;
146150

147151
self::assertSame('Error while parsing tag @error', $reason->getMessage());
148-
self::assertSame('error', $description[1]->getName());
149-
self::assertEquals(new Description('description'), $description[1]->getDescription());
152+
self::assertSame('error', $description[0]->name);
153+
self::assertEquals(new Description('description'), $description[0]->description);
150154
}
151155
}

0 commit comments

Comments
 (0)