Skip to content

Commit c94e9e7

Browse files
committed
Add phpdoc platforms
1 parent a76c3f0 commit c94e9e7

File tree

6 files changed

+173
-40
lines changed

6 files changed

+173
-40
lines changed

Diff for: src/Parser.php

+20-38
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,6 @@
88
use TypeLang\PHPDoc\DocBlock\Tag\Factory\MutableTagFactoryInterface;
99
use TypeLang\PHPDoc\DocBlock\Tag\Factory\TagFactory;
1010
use TypeLang\PHPDoc\DocBlock\Tag\Factory\TagFactoryInterface;
11-
use TypeLang\PHPDoc\DocBlock\Tag\MethodTag\MethodTagFactory;
12-
use TypeLang\PHPDoc\DocBlock\Tag\ParamTag\ParamTagFactory;
13-
use TypeLang\PHPDoc\DocBlock\Tag\PropertyTag\PropertyReadTagFactory;
14-
use TypeLang\PHPDoc\DocBlock\Tag\PropertyTag\PropertyTagFactory;
15-
use TypeLang\PHPDoc\DocBlock\Tag\PropertyTag\PropertyWriteTagFactory;
16-
use TypeLang\PHPDoc\DocBlock\Tag\ReturnTag\ReturnTagFactory;
17-
use TypeLang\PHPDoc\DocBlock\Tag\TemplateExtendsTag\TemplateExtendsTagFactory;
18-
use TypeLang\PHPDoc\DocBlock\Tag\TemplateExtendsTag\TemplateImplementsTagFactory;
19-
use TypeLang\PHPDoc\DocBlock\Tag\TemplateTag\TemplateCovariantTagFactory;
20-
use TypeLang\PHPDoc\DocBlock\Tag\TemplateTag\TemplateTagFactory;
21-
use TypeLang\PHPDoc\DocBlock\Tag\ThrowsTag\ThrowsTagFactory;
22-
use TypeLang\PHPDoc\DocBlock\Tag\VarTag\VarTagFactory;
2311
use TypeLang\PHPDoc\Exception\ParsingException;
2412
use TypeLang\PHPDoc\Exception\RuntimeExceptionInterface;
2513
use TypeLang\PHPDoc\Parser\Comment\CommentParserInterface;
@@ -30,6 +18,8 @@
3018
use TypeLang\PHPDoc\Parser\SourceMap;
3119
use TypeLang\PHPDoc\Parser\Tag\RegexTagParser;
3220
use TypeLang\PHPDoc\Parser\Tag\TagParserInterface;
21+
use TypeLang\PHPDoc\Platform\PlatformInterface;
22+
use TypeLang\PHPDoc\Platform\StandardPlatform;
3323

3424
class Parser implements ParserInterface
3525
{
@@ -41,36 +31,28 @@ class Parser implements ParserInterface
4131

4232
private readonly MutableTagFactoryInterface $factories;
4333

44-
/**
45-
* @param iterable<non-empty-string, TagFactoryInterface>|null $tags
46-
*/
47-
public function __construct(?iterable $tags = null)
34+
public function __construct(
35+
public readonly PlatformInterface $platform = new StandardPlatform(),
36+
) {
37+
$this->factories = new TagFactory($platform->getTags());
38+
$this->tags = $this->createTagParser($this->factories);
39+
$this->descriptions = $this->createDescriptionParser($this->tags);
40+
$this->comments = $this->createCommentParser();
41+
}
42+
43+
protected function createTagParser(TagFactoryInterface $factories): TagParserInterface
4844
{
49-
$this->factories = new TagFactory($tags ?? self::createDefaultTags());
50-
$this->tags = new RegexTagParser($this->factories);
51-
$this->descriptions = new RegexDescriptionParser($this->tags);
52-
$this->comments = new RegexCommentParser();
45+
return new RegexTagParser($factories);
5346
}
5447

55-
/**
56-
* @return iterable<non-empty-string, TagFactoryInterface>
57-
*/
58-
private static function createDefaultTags(): iterable
48+
protected function createDescriptionParser(TagParserInterface $tags): DescriptionParserInterface
49+
{
50+
return new RegexDescriptionParser($tags);
51+
}
52+
53+
protected function createCommentParser(): CommentParserInterface
5954
{
60-
yield 'method' => new MethodTagFactory();
61-
yield 'param' => new ParamTagFactory();
62-
yield 'property' => new PropertyTagFactory();
63-
yield 'property-read' => new PropertyReadTagFactory();
64-
yield 'property-write' => new PropertyWriteTagFactory();
65-
yield 'return' => new ReturnTagFactory();
66-
yield 'throws' => new ThrowsTagFactory();
67-
yield 'var' => new VarTagFactory();
68-
yield 'template' => new TemplateTagFactory();
69-
yield 'template-implements' => $implements = new TemplateImplementsTagFactory();
70-
yield 'implements' => $implements;
71-
yield 'template-extends' => $extends = new TemplateExtendsTagFactory();
72-
yield 'extends' => $extends;
73-
yield 'template-covariant' => new TemplateCovariantTagFactory();
55+
return new RegexCommentParser();
7456
}
7557

7658
/**

Diff for: src/ParserInterface.php

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,12 @@
44

55
namespace TypeLang\PHPDoc;
66

7-
use JetBrains\PhpStorm\Language;
87
use TypeLang\PHPDoc\DocBlock\DocBlock;
98

109
interface ParserInterface
1110
{
1211
/**
1312
* @param string $docblock a string containing the DocBlock to parse
1413
*/
15-
public function parse(#[Language('PHP')] string $docblock): DocBlock;
14+
public function parse(string $docblock): DocBlock;
1615
}

Diff for: src/Platform/CompoundPlatform.php

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace TypeLang\PHPDoc\Platform;
6+
7+
final class CompoundPlatform implements PlatformInterface
8+
{
9+
/**
10+
* @var list<PlatformInterface>
11+
*/
12+
public readonly array $platforms;
13+
14+
/**
15+
* @param iterable<array-key, PlatformInterface> $platforms
16+
*/
17+
public function __construct(iterable $platforms = [])
18+
{
19+
$this->platforms = match (true) {
20+
$platforms instanceof \Traversable => \iterator_to_array($platforms, false),
21+
\array_is_list($platforms) => $platforms,
22+
default => \array_values($platforms),
23+
};
24+
}
25+
26+
public function getName(): string
27+
{
28+
if ($this->platforms === []) {
29+
return 'empty';
30+
}
31+
32+
$names = [];
33+
34+
foreach ($this->platforms as $platform) {
35+
$names[] = $platform->getName();
36+
}
37+
38+
return \implode(' & ', $names);
39+
}
40+
41+
public function getTags(): iterable
42+
{
43+
foreach ($this->platforms as $platform) {
44+
yield from $platform->getTags();
45+
}
46+
}
47+
}

Diff for: src/Platform/Platform.php

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace TypeLang\PHPDoc\Platform;
6+
7+
use TypeLang\Parser\Parser as TypesParser;
8+
use TypeLang\Parser\ParserInterface as TypesParserInterface;
9+
use TypeLang\PHPDoc\DocBlock\Tag\Factory\TagFactoryInterface;
10+
11+
abstract class Platform implements PlatformInterface
12+
{
13+
public function __construct(
14+
protected readonly TypesParserInterface $types = new TypesParser(tolerant: true),
15+
) {
16+
if ($this->types instanceof TypesParser && $this->types->tolerant === false) {
17+
throw new \InvalidArgumentException('Tolerant parser mode required');
18+
}
19+
}
20+
21+
public function getTags(): iterable
22+
{
23+
foreach ($this->load($this->types) as $tag => $factory) {
24+
if (\is_iterable($tag)) {
25+
foreach ($tag as $name) {
26+
yield $name => $factory;
27+
}
28+
} else {
29+
yield $tag => $factory;
30+
}
31+
}
32+
}
33+
34+
/**
35+
* @return iterable<non-empty-string|iterable<mixed, non-empty-string>, TagFactoryInterface>
36+
*/
37+
abstract protected function load(TypesParserInterface $types): iterable;
38+
}

Diff for: src/Platform/PlatformInterface.php

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace TypeLang\PHPDoc\Platform;
6+
7+
use TypeLang\PHPDoc\DocBlock\Tag\Factory\TagFactoryInterface;
8+
9+
interface PlatformInterface
10+
{
11+
/**
12+
* Platform name to display anywhere.
13+
*
14+
* @return non-empty-string
15+
*/
16+
public function getName(): string;
17+
18+
/**
19+
* Returns a list of registered tags for the specified platform.
20+
*
21+
* @return iterable<non-empty-string, TagFactoryInterface>
22+
*/
23+
public function getTags(): iterable;
24+
}

Diff for: src/Platform/StandardPlatform.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\Platform;
6+
7+
use TypeLang\Parser\ParserInterface as TypesParserInterface;
8+
use TypeLang\PHPDoc\DocBlock\Tag\MethodTag\MethodTagFactory;
9+
use TypeLang\PHPDoc\DocBlock\Tag\ParamTag\ParamTagFactory;
10+
use TypeLang\PHPDoc\DocBlock\Tag\PropertyTag\PropertyReadTagFactory;
11+
use TypeLang\PHPDoc\DocBlock\Tag\PropertyTag\PropertyTagFactory;
12+
use TypeLang\PHPDoc\DocBlock\Tag\PropertyTag\PropertyWriteTagFactory;
13+
use TypeLang\PHPDoc\DocBlock\Tag\ReturnTag\ReturnTagFactory;
14+
use TypeLang\PHPDoc\DocBlock\Tag\TemplateExtendsTag\TemplateExtendsTagFactory;
15+
use TypeLang\PHPDoc\DocBlock\Tag\TemplateExtendsTag\TemplateImplementsTagFactory;
16+
use TypeLang\PHPDoc\DocBlock\Tag\TemplateTag\TemplateCovariantTagFactory;
17+
use TypeLang\PHPDoc\DocBlock\Tag\TemplateTag\TemplateTagFactory;
18+
use TypeLang\PHPDoc\DocBlock\Tag\ThrowsTag\ThrowsTagFactory;
19+
use TypeLang\PHPDoc\DocBlock\Tag\VarTag\VarTagFactory;
20+
21+
final class StandardPlatform extends Platform
22+
{
23+
public function getName(): string
24+
{
25+
return 'standard';
26+
}
27+
28+
protected function load(TypesParserInterface $types): iterable
29+
{
30+
yield 'method' => new MethodTagFactory();
31+
yield 'param' => new ParamTagFactory();
32+
yield 'property' => new PropertyTagFactory();
33+
yield 'property-read' => new PropertyReadTagFactory();
34+
yield 'property-write' => new PropertyWriteTagFactory();
35+
yield 'return' => new ReturnTagFactory();
36+
yield 'throws' => new ThrowsTagFactory();
37+
yield 'var' => new VarTagFactory();
38+
yield 'template' => new TemplateTagFactory();
39+
yield ['template-implements', 'implements'] => new TemplateImplementsTagFactory();
40+
yield ['template-extends', 'extends'] => new TemplateExtendsTagFactory();
41+
yield 'template-covariant' => new TemplateCovariantTagFactory();
42+
}
43+
}

0 commit comments

Comments
 (0)