Skip to content

Commit 9e847ae

Browse files
committed
Add tags and description interfaces
1 parent 2fc92eb commit 9e847ae

19 files changed

+193
-95
lines changed

src/DocBlock.php

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,44 @@
55
namespace TypeLang\PHPDoc;
66

77
use TypeLang\PHPDoc\Tag\Description;
8-
use TypeLang\PHPDoc\Tag\Tag;
8+
use TypeLang\PHPDoc\Tag\DescriptionInterface;
9+
use TypeLang\PHPDoc\Tag\DescriptionProviderInterface;
10+
use TypeLang\PHPDoc\Tag\TagInterface;
911
use TypeLang\PHPDoc\Tag\TagProvider;
1012
use TypeLang\PHPDoc\Tag\TagProviderInterface;
1113

1214
/**
13-
* @template-implements \IteratorAggregate<int<0, max>, Tag>
14-
* @template-implements \ArrayAccess<int<0, max>, Tag|null>
15+
* This class represents structure containing a description and a set of tags
16+
* that describe an arbitrary DocBlock Comment in the code.
17+
*
18+
* @template-implements \IteratorAggregate<int<0, max>, TagInterface>
19+
* @template-implements \ArrayAccess<int<0, max>, TagInterface|null>
1520
*/
1621
final class DocBlock implements
22+
DescriptionProviderInterface,
1723
TagProviderInterface,
1824
\IteratorAggregate,
1925
\ArrayAccess
2026
{
2127
use TagProvider;
2228

29+
private readonly DescriptionInterface $description;
30+
2331
/**
24-
* @param iterable<array-key, Tag> $tags
32+
* @param iterable<array-key, TagInterface> $tags List of all tags contained in
33+
* a docblock object.
34+
*
35+
* Note that the constructor can receive an arbitrary iterator, like
36+
* {@see \Traversable} or {@see array}, but the object itself
37+
* contains the directly generated list ({@see array}} of
38+
* {@see TagInterface} objects.
2539
*/
2640
public function __construct(
27-
private readonly Description $description = new Description(),
41+
string|\Stringable $description = '',
2842
iterable $tags = [],
2943
) {
44+
$this->description = Description::fromStringable($description);
45+
3046
$this->bootTagProvider($tags);
3147
}
3248

@@ -35,7 +51,7 @@ public function offsetExists(mixed $offset): bool
3551
return isset($this->tags[$offset]);
3652
}
3753

38-
public function offsetGet(mixed $offset): ?Tag
54+
public function offsetGet(mixed $offset): ?TagInterface
3955
{
4056
return $this->tags[$offset] ?? null;
4157
}
@@ -50,7 +66,7 @@ public function offsetUnset(mixed $offset): void
5066
throw new \BadMethodCallException(self::class . ' objects are immutable');
5167
}
5268

53-
public function getDescription(): Description
69+
public function getDescription(): DescriptionInterface
5470
{
5571
return $this->description;
5672
}

src/Parser.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
use TypeLang\PHPDoc\Parser\SourceMap;
1616
use TypeLang\PHPDoc\Parser\Tag\TagParser;
1717
use TypeLang\PHPDoc\Parser\Tag\TagParserInterface;
18-
use TypeLang\PHPDoc\Tag\TagFactory;
19-
use TypeLang\PHPDoc\Tag\FactoryInterface;
18+
use TypeLang\PHPDoc\Tag\Factory\FactoryInterface;
19+
use TypeLang\PHPDoc\Tag\Factory\TagFactory;
2020

2121
/**
2222
* @psalm-suppress UndefinedAttributeClass : JetBrains language attribute may not be available

src/Parser/Description/DescriptionParserInterface.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
namespace TypeLang\PHPDoc\Parser\Description;
66

7-
use TypeLang\PHPDoc\Tag\Description;
7+
use TypeLang\PHPDoc\Tag\DescriptionInterface;
88

99
interface DescriptionParserInterface
1010
{
@@ -25,5 +25,5 @@ interface DescriptionParserInterface
2525
* // }
2626
* ```
2727
*/
28-
public function parse(string $description): Description;
28+
public function parse(string $description): DescriptionInterface;
2929
}

src/Parser/Tag/TagParser.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@
77
use TypeLang\PHPDoc\Exception\InvalidTagNameException;
88
use TypeLang\PHPDoc\Exception\RuntimeExceptionInterface;
99
use TypeLang\PHPDoc\Parser\Description\DescriptionParserInterface;
10-
use TypeLang\PHPDoc\Tag\FactoryInterface;
10+
use TypeLang\PHPDoc\Tag\Factory\FactoryInterface;
1111
use TypeLang\PHPDoc\Tag\Tag;
12+
use TypeLang\PHPDoc\Tag\TagInterface;
1213

1314
final class TagParser implements TagParserInterface
1415
{
@@ -63,7 +64,7 @@ private function getTagName(string $content): string
6364
* @throws \Throwable
6465
* @throws RuntimeExceptionInterface
6566
*/
66-
public function parse(string $tag, DescriptionParserInterface $parser): Tag
67+
public function parse(string $tag, DescriptionParserInterface $parser): TagInterface
6768
{
6869
$name = $this->getTagName($tag);
6970
/** @var non-empty-string $name */

src/Parser/Tag/TagParserInterface.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
namespace TypeLang\PHPDoc\Parser\Tag;
66

77
use TypeLang\PHPDoc\Parser\Description\DescriptionParserInterface;
8-
use TypeLang\PHPDoc\Tag\Tag;
8+
use TypeLang\PHPDoc\Tag\TagInterface;
99

1010
interface TagParserInterface
1111
{
@@ -24,5 +24,5 @@ interface TagParserInterface
2424
* // }
2525
* ```
2626
*/
27-
public function parse(string $tag, DescriptionParserInterface $parser): Tag;
27+
public function parse(string $tag, DescriptionParserInterface $parser): TagInterface;
2828
}

src/Tag/Description.php

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,16 @@
55
namespace TypeLang\PHPDoc\Tag;
66

77
/**
8-
* @template-implements \IteratorAggregate<int<0, max>, Tag>
8+
* @template-implements \IteratorAggregate<int<0, max>, TagInterface>
99
*/
10-
class Description implements
11-
TagProviderInterface,
12-
\IteratorAggregate,
13-
\Stringable
10+
class Description implements DescriptionInterface, \IteratorAggregate
1411
{
1512
use TagProvider;
1613

17-
private readonly string $template;
14+
protected readonly string $template;
1815

1916
/**
20-
* @param iterable<array-key, Tag> $tags
17+
* @param iterable<array-key, TagInterface> $tags
2118
*/
2219
public function __construct(
2320
string|\Stringable $template = '',
@@ -28,38 +25,29 @@ public function __construct(
2825
$this->bootTagProvider($tags);
2926
}
3027

31-
public static function fromString(string|\Stringable $description): self
28+
public static function fromStringable(string|\Stringable $description): DescriptionInterface
3229
{
33-
if ($description instanceof self) {
30+
if ($description instanceof DescriptionInterface) {
3431
return $description;
3532
}
3633

3734
return new self($description);
3835
}
3936

40-
public static function fromStringOrNull(string|\Stringable|null $description): ?self
37+
public static function fromStringableOrNull(string|\Stringable|null $description): ?DescriptionInterface
4138
{
4239
if ($description === null) {
4340
return null;
4441
}
4542

46-
return self::fromString($description);
43+
return self::fromStringable($description);
4744
}
4845

49-
/**
50-
* Returns the body template.
51-
*
52-
* @api
53-
* @psalm-immutable
54-
*/
5546
public function getTemplate(): string
5647
{
5748
return $this->template;
5849
}
5950

60-
/**
61-
* @psalm-immutable
62-
*/
6351
public function __toString(): string
6452
{
6553
$tags = [];

src/Tag/DescriptionInterface.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace TypeLang\PHPDoc\Tag;
6+
7+
interface DescriptionInterface extends TagProviderInterface, \Stringable
8+
{
9+
/**
10+
* Returns the body template.
11+
*
12+
* @psalm-immutable Each call to the method must return the same value.
13+
*/
14+
public function getTemplate(): string;
15+
16+
/**
17+
* Returns a plain string representation of this description.
18+
*
19+
* Magic method {@link https://www.php.net/manual/en/language.oop5.magic.php#object.tostring}
20+
* allows a class to decide how it will react when it is treated like
21+
* a string.
22+
*
23+
* @psalm-immutable Each call to the method must return the same value.
24+
*/
25+
public function __toString(): string;
26+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace TypeLang\PHPDoc\Tag;
6+
7+
interface DescriptionProviderInterface
8+
{
9+
/**
10+
* Returns description object which can be represented as a string and
11+
* contains additional information.
12+
*
13+
* @psalm-immutable Each call to the method must return the same value.
14+
*/
15+
public function getDescription(): ?DescriptionInterface;
16+
}

src/Tag/FactoryInterface.php renamed to src/Tag/Factory/FactoryInterface.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22

33
declare(strict_types=1);
44

5-
namespace TypeLang\PHPDoc\Tag;
5+
namespace TypeLang\PHPDoc\Tag\Factory;
66

77
use TypeLang\PHPDoc\Exception\RuntimeExceptionInterface;
88
use TypeLang\PHPDoc\Parser\Description\DescriptionParserInterface;
9+
use TypeLang\PHPDoc\Tag\TagInterface;
910

1011
interface FactoryInterface
1112
{
@@ -17,5 +18,5 @@ interface FactoryInterface
1718
* @throws RuntimeExceptionInterface In case of parsing error occurs.
1819
* @throws \Throwable In case of internal error occurs.
1920
*/
20-
public function create(string $name, string $content, DescriptionParserInterface $descriptions): Tag;
21+
public function create(string $name, string $content, DescriptionParserInterface $descriptions): TagInterface;
2122
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace TypeLang\PHPDoc\Tag\Factory;
6+
7+
interface MutableFactoryInterface extends FactoryInterface
8+
{
9+
/**
10+
* Registers a handler for tags.
11+
*
12+
* If you want to use your own tags then you can use this method to
13+
* instruct the {@see FactoryInterface} to register the name of a tag with
14+
* the custom {@see FactoryInterface} to which processing of this tag will
15+
* be delegated.
16+
*
17+
* @param non-empty-string|list<non-empty-string> $tags
18+
*/
19+
public function register(string|array $tags, FactoryInterface $delegate): void;
20+
}

0 commit comments

Comments
 (0)