Skip to content

Commit 71a83ad

Browse files
committed
Add more named tags
1 parent 65f8d04 commit 71a83ad

37 files changed

Lines changed: 1087 additions & 30 deletions
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace TypeLang\PhpDoc\DocBlock\Tag\CodingStandardsTag;
6+
7+
use TypeLang\PhpDoc\DocBlock\Tag\IdentifierTag;
8+
9+
/**
10+
* The "@codingStandards" tag names a coding standard for reference.
11+
*/
12+
final class CodingStandardsTag extends IdentifierTag {}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace TypeLang\PhpDoc\DocBlock\Tag\CodingStandardsTag;
6+
7+
use TypeLang\PhpDoc\DocBlock\Combinator\DescriptionCombinator;
8+
use TypeLang\PhpDoc\DocBlock\Combinator\NameCombinator;
9+
use TypeLang\PhpDoc\DocBlock\Description\DescriptionInterface;
10+
use TypeLang\PhpDoc\DocBlock\TagDefinition\Spec;
11+
use TypeLang\PhpDoc\DocBlock\TagDefinition\TagDefinition;
12+
use TypeLang\PhpDoc\DocBlock\TagDefinition\TagPayload;
13+
use TypeLang\PhpDoc\DocBlock\TagDefinition\TagPlacement;
14+
15+
/**
16+
* The "`@codingStandards`" tag names a coding standard for reference.
17+
*
18+
* ```
19+
* "@codingStandards" <Name> [ <Description> ]
20+
* ```
21+
*/
22+
final class CodingStandardsTagDefinition extends TagDefinition
23+
{
24+
public const string NAME = 'codingStandards';
25+
26+
public function __construct()
27+
{
28+
parent::__construct(
29+
name: self::NAME,
30+
spec: Spec::sequence(
31+
Spec::rule(NameCombinator::NAME, 'identifier'),
32+
Spec::maybe(
33+
Spec::rule(DescriptionCombinator::NAME, 'description'),
34+
),
35+
),
36+
placement: TagPlacement::Block,
37+
);
38+
}
39+
40+
public function create(string $name, TagPayload $result): CodingStandardsTag
41+
{
42+
/** @var non-empty-string $identifier */
43+
$identifier = $result->get('identifier');
44+
45+
/** @var DescriptionInterface|null $description */
46+
$description = $result->find('description');
47+
48+
return new CodingStandardsTag($name, $identifier, $description);
49+
}
50+
}

src/DocBlock/Tag/IdentifierTag.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace TypeLang\PhpDoc\DocBlock\Tag;
6+
7+
use TypeLang\PhpDoc\DocBlock\Description\DescriptionInterface;
8+
9+
/**
10+
* A tag whose body is a single name identifier, followed by an optional
11+
* description.
12+
*/
13+
abstract class IdentifierTag extends Tag
14+
{
15+
public function __construct(
16+
string $name,
17+
/**
18+
* The single identifier carried by the tag.
19+
*
20+
* @var non-empty-string
21+
*/
22+
public readonly string $identifier,
23+
?DescriptionInterface $description = null,
24+
) {
25+
parent::__construct($name, $description);
26+
}
27+
28+
#[\Override]
29+
public function __toString(): string
30+
{
31+
$result = \sprintf('@%s %s', $this->name, $this->identifier);
32+
33+
if ($this->description !== null) {
34+
$result .= ' ' . $this->description;
35+
}
36+
37+
return $result;
38+
}
39+
}

src/DocBlock/Tag/IssueListTag.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace TypeLang\PhpDoc\DocBlock\Tag;
6+
7+
use TypeLang\PhpDoc\DocBlock\Description\DescriptionInterface;
8+
9+
/**
10+
* A tag whose body is a comma-separated list of issue identifiers, followed by
11+
* an optional description.
12+
*/
13+
abstract class IssueListTag extends Tag
14+
{
15+
public function __construct(
16+
string $name,
17+
/**
18+
* The identifiers of the diagnostics being listed.
19+
*
20+
* @var non-empty-list<non-empty-string>
21+
*/
22+
public readonly array $issues,
23+
?DescriptionInterface $description = null,
24+
) {
25+
parent::__construct($name, $description);
26+
}
27+
28+
#[\Override]
29+
public function __toString(): string
30+
{
31+
$result = \sprintf('@%s %s', $this->name, \implode(', ', $this->issues));
32+
33+
if ($this->description !== null) {
34+
$result .= ' ' . $this->description;
35+
}
36+
37+
return $result;
38+
}
39+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace TypeLang\PhpDoc\DocBlock\Tag\LanguageTag;
6+
7+
use TypeLang\PhpDoc\DocBlock\Tag\IdentifierTag;
8+
9+
/**
10+
* The "@language" tag injects a foreign-language grammar — such as SQL,
11+
* HTML or a regular expression — into a string literal, so an IDE can
12+
* apply the right highlighting and completion inside it.
13+
*/
14+
final class LanguageTag extends IdentifierTag {}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace TypeLang\PhpDoc\DocBlock\Tag\LanguageTag;
6+
7+
use TypeLang\PhpDoc\DocBlock\Combinator\DescriptionCombinator;
8+
use TypeLang\PhpDoc\DocBlock\Combinator\NameCombinator;
9+
use TypeLang\PhpDoc\DocBlock\Description\DescriptionInterface;
10+
use TypeLang\PhpDoc\DocBlock\TagDefinition\Spec;
11+
use TypeLang\PhpDoc\DocBlock\TagDefinition\TagDefinition;
12+
use TypeLang\PhpDoc\DocBlock\TagDefinition\TagPayload;
13+
use TypeLang\PhpDoc\DocBlock\TagDefinition\TagPlacement;
14+
15+
/**
16+
* The "`@language`" tag injects a foreign-language grammar — such as
17+
* SQL, HTML or a regular expression — into a string literal, so an IDE
18+
* can apply the right highlighting and completion inside it.
19+
*
20+
* ```
21+
* "@language" <Name> [ <Description> ]
22+
* ```
23+
*/
24+
final class LanguageTagDefinition extends TagDefinition
25+
{
26+
public const string NAME = 'language';
27+
28+
public function __construct()
29+
{
30+
parent::__construct(
31+
name: self::NAME,
32+
spec: Spec::sequence(
33+
Spec::rule(NameCombinator::NAME, 'identifier'),
34+
Spec::maybe(
35+
Spec::rule(DescriptionCombinator::NAME, 'description'),
36+
),
37+
),
38+
placement: TagPlacement::Block,
39+
);
40+
}
41+
42+
public function create(string $name, TagPayload $result): LanguageTag
43+
{
44+
/** @var non-empty-string $identifier */
45+
$identifier = $result->get('identifier');
46+
47+
/** @var DescriptionInterface|null $description */
48+
$description = $result->find('description');
49+
50+
return new LanguageTag($name, $identifier, $description);
51+
}
52+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace TypeLang\PhpDoc\DocBlock\Tag\NoinspectionTag;
6+
7+
use TypeLang\PhpDoc\DocBlock\Tag\IdentifierTag;
8+
9+
/**
10+
* The "@noinspection" tag suppresses the named IDE inspection for the
11+
* element that follows it.
12+
*/
13+
final class NoinspectionTag extends IdentifierTag {}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace TypeLang\PhpDoc\DocBlock\Tag\NoinspectionTag;
6+
7+
use TypeLang\PhpDoc\DocBlock\Combinator\DescriptionCombinator;
8+
use TypeLang\PhpDoc\DocBlock\Combinator\NameCombinator;
9+
use TypeLang\PhpDoc\DocBlock\Description\DescriptionInterface;
10+
use TypeLang\PhpDoc\DocBlock\TagDefinition\Spec;
11+
use TypeLang\PhpDoc\DocBlock\TagDefinition\TagDefinition;
12+
use TypeLang\PhpDoc\DocBlock\TagDefinition\TagPayload;
13+
use TypeLang\PhpDoc\DocBlock\TagDefinition\TagPlacement;
14+
15+
/**
16+
* The "`@noinspection`" tag suppresses the named IDE inspection for the
17+
* element that follows it.
18+
*
19+
* ```
20+
* "@noinspection" <Name> [ <Description> ]
21+
* ```
22+
*/
23+
final class NoinspectionTagDefinition extends TagDefinition
24+
{
25+
public const string NAME = 'noinspection';
26+
27+
public function __construct()
28+
{
29+
parent::__construct(
30+
name: self::NAME,
31+
spec: Spec::sequence(
32+
Spec::rule(NameCombinator::NAME, 'identifier'),
33+
Spec::maybe(
34+
Spec::rule(DescriptionCombinator::NAME, 'description'),
35+
),
36+
),
37+
placement: TagPlacement::Block,
38+
);
39+
}
40+
41+
public function create(string $name, TagPayload $result): NoinspectionTag
42+
{
43+
/** @var non-empty-string $identifier */
44+
$identifier = $result->get('identifier');
45+
46+
/** @var DescriptionInterface|null $description */
47+
$description = $result->find('description');
48+
49+
return new NoinspectionTag($name, $identifier, $description);
50+
}
51+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace TypeLang\PhpDoc\DocBlock\Tag\PhanFileSuppressTag;
6+
7+
use TypeLang\PhpDoc\DocBlock\Tag\IssueListTag;
8+
9+
/**
10+
* The `@phan-file-suppress` tag silences the listed issue types for the
11+
* whole file it appears in, rather than just a single element or line.
12+
*/
13+
final class PhanFileSuppressTag extends IssueListTag {}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace TypeLang\PhpDoc\DocBlock\Tag\PhanFileSuppressTag;
6+
7+
use TypeLang\PhpDoc\DocBlock\Combinator\DescriptionCombinator;
8+
use TypeLang\PhpDoc\DocBlock\Combinator\IssueNameCombinator;
9+
use TypeLang\PhpDoc\DocBlock\Description\DescriptionInterface;
10+
use TypeLang\PhpDoc\DocBlock\TagDefinition\Spec;
11+
use TypeLang\PhpDoc\DocBlock\TagDefinition\TagDefinition;
12+
use TypeLang\PhpDoc\DocBlock\TagDefinition\TagPayload;
13+
use TypeLang\PhpDoc\DocBlock\TagDefinition\TagPlacement;
14+
15+
/**
16+
* The `@phan-file-suppress` tag silences the listed issue types for the
17+
* whole file it appears in, rather than just a single element or line.
18+
*
19+
* ```
20+
* "@phan-file-suppress" <IssueName> { "," <IssueName> } [ <Description> ]
21+
* ```
22+
*/
23+
final class PhanFileSuppressTagDefinition extends TagDefinition
24+
{
25+
public const string NAME = 'phan-file-suppress';
26+
27+
public function __construct()
28+
{
29+
parent::__construct(
30+
name: self::NAME,
31+
spec: Spec::sequence(
32+
Spec::rule(IssueNameCombinator::NAME, 'issue'),
33+
Spec::repeat(
34+
Spec::sequence(
35+
Spec::literal(','),
36+
Spec::rule(IssueNameCombinator::NAME, 'issue'),
37+
),
38+
),
39+
Spec::maybe(
40+
Spec::rule(DescriptionCombinator::NAME, 'description'),
41+
),
42+
),
43+
placement: TagPlacement::Block,
44+
);
45+
}
46+
47+
public function create(string $name, TagPayload $result): PhanFileSuppressTag
48+
{
49+
/** @var non-empty-list<non-empty-string> $issues */
50+
$issues = $result->getAll('issue');
51+
52+
/** @var DescriptionInterface|null $description */
53+
$description = $result->find('description');
54+
55+
return new PhanFileSuppressTag($name, $issues, $description);
56+
}
57+
}

0 commit comments

Comments
 (0)