Skip to content

Commit a10a69c

Browse files
committed
Add invalid tags support
1 parent 516b84f commit a10a69c

File tree

6 files changed

+74
-19
lines changed

6 files changed

+74
-19
lines changed

Diff for: src/Exception/ParsingException.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public function withSource(string $source, int $offset): self
4747
offset: $offset,
4848
message: $this->message,
4949
code: $this->code,
50-
previous: $this->getPrevious(),
50+
previous: $this,
5151
);
5252
}
5353

Diff for: src/Parser.php

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
namespace TypeLang\PHPDoc;
66

77
use JetBrains\PhpStorm\Language;
8+
use TypeLang\PHPDoc\Exception\InvalidTagException;
9+
use TypeLang\PHPDoc\Exception\InvalidTagNameException;
810
use TypeLang\PHPDoc\Exception\ParsingException;
911
use TypeLang\PHPDoc\Exception\RuntimeExceptionInterface;
1012
use TypeLang\PHPDoc\Parser\Comment\CommentParserInterface;

Diff for: src/Parser/Tag/TagParser.php

+9-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use TypeLang\PHPDoc\Parser\Description\DescriptionParserInterface;
1010
use TypeLang\PHPDoc\Tag\Factory\FactoryInterface;
1111
use TypeLang\PHPDoc\Tag\Content;
12+
use TypeLang\PHPDoc\Tag\InvalidTag;
1213
use TypeLang\PHPDoc\Tag\TagInterface;
1314

1415
final class TagParser implements TagParserInterface
@@ -66,7 +67,14 @@ private function getTagName(string $content): string
6667
*/
6768
public function parse(string $tag, DescriptionParserInterface $parser): TagInterface
6869
{
69-
$name = $this->getTagName($tag);
70+
try {
71+
$name = $this->getTagName($tag);
72+
} catch (InvalidTagNameException $e) {
73+
return new InvalidTag($e, $parser->parse(
74+
description: \substr($tag, 1),
75+
));
76+
}
77+
7078
/** @var non-empty-string $name */
7179
$name = \substr($name, 1);
7280

Diff for: src/Tag/Content.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
class Content implements \Stringable
1919
{
20-
private readonly string $original;
20+
public readonly string $source;
2121

2222
/**
2323
* @var int<0, max>
@@ -28,7 +28,7 @@ class Content implements \Stringable
2828
public function __construct(
2929
public string $value,
3030
) {
31-
$this->original = $this->value;
31+
$this->source = $this->value;
3232
}
3333

3434
/**
@@ -54,7 +54,7 @@ public function shift(int $offset, bool $ltrim = true): void
5454
public function getTagException(string $message, \Throwable $previous = null): InvalidTagException
5555
{
5656
return new InvalidTagException(
57-
source: $this->original,
57+
source: $this->source,
5858
offset: $this->offset,
5959
message: $message,
6060
previous: $previous,

Diff for: src/Tag/Factory/TagFactory.php

+16-14
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use TypeLang\PHPDoc\Exception\ParsingException;
99
use TypeLang\PHPDoc\Exception\RuntimeExceptionInterface;
1010
use TypeLang\PHPDoc\Parser\Description\DescriptionParserInterface;
11+
use TypeLang\PHPDoc\Tag\InvalidTag;
1112
use TypeLang\PHPDoc\Tag\Tag;
1213
use TypeLang\PHPDoc\Tag\Content;
1314
use TypeLang\PHPDoc\Tag\TagInterface;
@@ -34,21 +35,22 @@ public function create(string $name, Content $content, DescriptionParserInterfac
3435

3536
if ($delegate !== null) {
3637
try {
37-
return $delegate->create($name, $content, $descriptions);
38-
} catch (ParsingException $e) {
39-
throw $e;
38+
try {
39+
return $delegate->create($name, $content, $descriptions);
40+
} catch (RuntimeExceptionInterface $e) {
41+
throw $e;
42+
} catch (\Throwable $e) {
43+
throw InvalidTagException::fromCreatingTag(
44+
tag: $name,
45+
source: $content->value,
46+
prev: $e,
47+
);
48+
}
4049
} catch (RuntimeExceptionInterface $e) {
41-
throw InvalidTagException::fromCreatingTag(
42-
tag: $name,
43-
source: $e->getSource(),
44-
offset: $e->getOffset(),
45-
prev: $e,
46-
);
47-
} catch (\Throwable $e) {
48-
throw InvalidTagException::fromCreatingTag(
49-
tag: $name,
50-
source: $content->value,
51-
prev: $e,
50+
return new InvalidTag(
51+
reason: $e,
52+
description: $descriptions->parse($content->source),
53+
name: $name,
5254
);
5355
}
5456
}

Diff for: src/Tag/InvalidTag.php

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace TypeLang\PHPDoc\Tag;
6+
7+
final class InvalidTag extends Tag
8+
{
9+
/**
10+
* @var non-empty-string
11+
*/
12+
public const DEFAULT_UNKNOWN_TAG_NAME = '<unknown>';
13+
14+
/**
15+
* @param non-empty-string $name
16+
*/
17+
public function __construct(
18+
protected readonly \Throwable $reason,
19+
\Stringable|string|null $description = null,
20+
string $name = self::DEFAULT_UNKNOWN_TAG_NAME,
21+
) {
22+
parent::__construct($name, $description);
23+
}
24+
25+
public function getReason(): \Throwable
26+
{
27+
return $this->reason;
28+
}
29+
30+
public function __toString(): string
31+
{
32+
$name = $this->name === self::DEFAULT_UNKNOWN_TAG_NAME ? '' : $this->name;
33+
34+
if ($this->description === null) {
35+
return \sprintf('@%s', $name);
36+
}
37+
38+
return \rtrim(\vsprintf('@%s %s', [
39+
$name,
40+
(string) $this->description,
41+
]));
42+
}
43+
}

0 commit comments

Comments
 (0)