Skip to content

Commit 3a28f04

Browse files
author
Kirill Nesmeyanov
committed
Improve phpdoc parser readers
1 parent acd2f56 commit 3a28f04

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1287
-747
lines changed

src/Description/DescriptionFactory.php

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@
77
use TypeLang\PhpDocParser\DocBlock\Description;
88
use TypeLang\PhpDocParser\DocBlock\Tag\TagInterface;
99
use TypeLang\PhpDocParser\DocBlock\TagFactoryInterface;
10+
use TypeLang\PhpDocParser\Exception\InvalidTagNameException;
1011

11-
final class DescriptionFactory implements DescriptionFactoryInterface
12+
abstract class DescriptionFactory implements DescriptionFactoryInterface
1213
{
1314
/**
1415
* @param TagFactoryInterface<TagInterface> $tags
@@ -34,12 +35,17 @@ public function create(string $contents): Description
3435
}
3536

3637
if (\str_starts_with($chunk, '@')) {
37-
$tags[] = $this->tags->create($chunk);
38-
$description .= $this->createTagDescriptionChunk(++$tagIdentifier);
38+
try {
39+
$tags[] = $this->tags->create($chunk);
40+
$description .= $this->createDescriptionChunkPlaceholder(++$tagIdentifier);
41+
} catch (InvalidTagNameException) {
42+
$description .= "{{$chunk}}";
43+
}
44+
3945
continue;
4046
}
4147

42-
$description .= $this->formatDescriptionChunk($chunk);
48+
$description .= $this->escapeDescriptionChunk($chunk);
4349
}
4450

4551
return new Description($description, $tags);
@@ -50,18 +56,12 @@ public function create(string $contents): Description
5056
*
5157
* @return non-empty-string
5258
*/
53-
private function createTagDescriptionChunk(int $tagId): string
54-
{
55-
return "%{$tagId}\$s";
56-
}
59+
abstract protected function createDescriptionChunkPlaceholder(int $tagId): string;
5760

5861
/**
5962
* @return ($chunk is non-empty-string ? non-empty-string : string)
6063
*/
61-
private function formatDescriptionChunk(string $chunk): string
62-
{
63-
return \str_replace('%', '%%', $chunk);
64-
}
64+
abstract protected function escapeDescriptionChunk(string $chunk): string;
6565

6666
/**
6767
* @return list<non-empty-string>
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\PhpDocParser\Description;
6+
7+
final class SprintfDescriptionFactory extends DescriptionFactory
8+
{
9+
/**
10+
* @param int<0, max> $tagId
11+
*
12+
* @return non-empty-string
13+
*/
14+
protected function createDescriptionChunkPlaceholder(int $tagId): string
15+
{
16+
return "%{$tagId}\$s";
17+
}
18+
19+
/**
20+
* @return ($chunk is non-empty-string ? non-empty-string : string)
21+
*/
22+
protected function escapeDescriptionChunk(string $chunk): string
23+
{
24+
return \str_replace('%', '%%', $chunk);
25+
}
26+
}

src/DocBlock/Extractor/TagNameExtractor.php

Lines changed: 0 additions & 87 deletions
This file was deleted.

src/DocBlock/Extractor/TagTypeExtractor.php

Lines changed: 0 additions & 81 deletions
This file was deleted.

src/DocBlock/Extractor/TagVariableExtractor.php

Lines changed: 0 additions & 51 deletions
This file was deleted.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace TypeLang\PhpDocParser\DocBlock\Reader;
6+
7+
use TypeLang\Parser\Node\Stmt\TypeStatement;
8+
use TypeLang\Parser\Parser;
9+
10+
/**
11+
* @template-extends Reader<TypeStatement>
12+
*/
13+
final class OptionalTypeReader extends Reader
14+
{
15+
public function __construct(
16+
private readonly Parser $parser,
17+
) {}
18+
19+
/**
20+
* @return Sequence<TypeStatement>|null
21+
*/
22+
public function read(string $content): ?Sequence
23+
{
24+
try {
25+
$type = $this->parser->parse($content);
26+
} catch (\Throwable) {
27+
return null;
28+
}
29+
30+
if ($type instanceof TypeStatement) {
31+
$offset = $this->parser->lastProcessedTokenOffset;
32+
33+
return new Sequence($type, $offset);
34+
}
35+
36+
return null;
37+
}
38+
}

0 commit comments

Comments
 (0)