Skip to content

Commit

Permalink
[FEATURE] Introduce php case and backed enums
Browse files Browse the repository at this point in the history
  • Loading branch information
linawolf committed Dec 12, 2023
1 parent d28541f commit 8410239
Show file tree
Hide file tree
Showing 16 changed files with 345 additions and 4 deletions.
2 changes: 1 addition & 1 deletion phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ parameters:
ignoreErrors:
-
message: "#^Function phpDocumentor\\\\Guides\\\\DependencyInjection\\\\template not found\\.$#"
count: 10
count: 11
path: src/DependencyInjection/GuidesPhpDomainExtension.php

-
Expand Down
3 changes: 2 additions & 1 deletion resources/config/php-domain.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use phpDocumentor\Guides\RestructuredText\Parser\Productions\DirectiveContentRule;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

use T3Docs\GuidesPhpDomain\Directives\Php\CaseDirective;
use T3Docs\GuidesPhpDomain\Directives\Php\ClassDirective;
use T3Docs\GuidesPhpDomain\Directives\Php\ConstDirective;
use T3Docs\GuidesPhpDomain\Directives\Php\ExceptionDirective;
Expand Down Expand Up @@ -35,7 +36,7 @@
->bind('$startingRule', service(DirectiveContentRule::class))
->instanceof(BaseDirective::class)
->tag('phpdoc.guides.directive')
->set(ClassDirective::class)
->set(CaseDirective::class)
->set(ClassDirective::class)
->set(ConstDirective::class)
->set(EnumDirective::class)
Expand Down
7 changes: 7 additions & 0 deletions resources/template/html/body/directive/php/case.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<dl class="php case">
<dt class="sig sig-object php" id="{{ node.id }}">
<em class="property"><span class="pre">case</span></em>
{{ renderNode(node.memberName) }} : {% if node.backedValue -%}<span class="pre">{{ node.backedValue }}</span> {% endif -%}
</dt>
<dd>{{ renderNode(node.value) }}</dd>
</dl>
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
{{- renderNode(modifier) }}{{ ' ' -}}
{%- endfor -%}
<em class="property"><span class="pre">{{ node.type }}</span> </em>
{{ renderNode(node.name) }}
{{ renderNode(node.name) }} {%- if node.type == 'enum' and node.phpType -%}<span class="pre"> : {{ node.phpType }}</span> {% endif -%}
</dt>
<dd>
{{ renderNode(node.value) }}
Expand Down
3 changes: 3 additions & 0 deletions src/DependencyInjection/GuidesPhpDomainExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
use T3Docs\GuidesPhpDomain\Nodes\FullyQualifiedNameNode;
use T3Docs\GuidesPhpDomain\Nodes\MemberNameNode;
use T3Docs\GuidesPhpDomain\Nodes\MethodNameNode;
use T3Docs\GuidesPhpDomain\Nodes\PhpCaseNode;
use T3Docs\GuidesPhpDomain\Nodes\PhpComponentNode;
use T3Docs\GuidesPhpDomain\Nodes\PhpConstNode;
use T3Docs\GuidesPhpDomain\Nodes\PhpEnumNode;
use T3Docs\GuidesPhpDomain\Nodes\PhpGlobalNode;
use T3Docs\GuidesPhpDomain\Nodes\PhpMethodNode;
use T3Docs\GuidesPhpDomain\Nodes\PhpModifierNode;
Expand Down Expand Up @@ -44,6 +46,7 @@ public function prepend(ContainerBuilder $container): void
'base_template_paths' => [dirname(__DIR__, 2) . '/resources/template/html'],
'templates' => [
template(FullyQualifiedNameNode::class, 'body/directive/php/fullyQualifiedName.html.twig'),
template(PhpCaseNode::class, 'body/directive/php/case.html.twig'),
template(PhpComponentNode::class, 'body/directive/php/component.html.twig'),
template(PhpConstNode::class, 'body/directive/php/const.html.twig'),
template(PhpGlobalNode::class, 'body/directive/php/global.html.twig'),
Expand Down
57 changes: 57 additions & 0 deletions src/Directives/Php/CaseDirective.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

declare(strict_types=1);

namespace T3Docs\GuidesPhpDomain\Directives\Php;

use phpDocumentor\Guides\Nodes\CollectionNode;
use phpDocumentor\Guides\Nodes\Node;
use phpDocumentor\Guides\ReferenceResolvers\AnchorReducer;
use phpDocumentor\Guides\RestructuredText\Directives\SubDirective;
use phpDocumentor\Guides\RestructuredText\Parser\BlockContext;
use phpDocumentor\Guides\RestructuredText\Parser\Directive;
use phpDocumentor\Guides\RestructuredText\Parser\Productions\Rule;
use phpDocumentor\Guides\RestructuredText\TextRoles\GenericLinkProvider;
use Psr\Log\LoggerInterface;
use T3Docs\GuidesPhpDomain\Nodes\MemberNameNode;
use T3Docs\GuidesPhpDomain\Nodes\PhpCaseNode;
use T3Docs\GuidesPhpDomain\Nodes\PhpConstNode;
use T3Docs\GuidesPhpDomain\PhpDomain\ModifierService;

final class CaseDirective extends SubDirective
{
public function __construct(
Rule $startingRule,
GenericLinkProvider $genericLinkProvider,
private readonly AnchorReducer $anchorReducer,
) {
parent::__construct($startingRule);
$genericLinkProvider->addGenericLink($this->getName(), $this->getName());
}

public function getName(): string
{
return 'php:case';
}

protected function processSub(
BlockContext $blockContext,
CollectionNode $collectionNode,
Directive $directive,
): Node|null {
$name = new MemberNameNode(trim($directive->getData()));
$id = $this->anchorReducer->reduceAnchor($name->toString());

$value = null;
if ($directive->hasOption('value')) {
$value = $directive->getOption('value')->toString();
}

return new PhpCaseNode(
$id,
$name,
$collectionNode->getChildren(),
$value,
);
}
}
20 changes: 19 additions & 1 deletion src/Directives/Php/EnumDirective.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use phpDocumentor\Guides\RestructuredText\Parser\Directive;
use phpDocumentor\Guides\RestructuredText\Parser\Productions\Rule;
use phpDocumentor\Guides\RestructuredText\TextRoles\GenericLinkProvider;
use Psr\Log\LoggerInterface;
use T3Docs\GuidesPhpDomain\Nodes\PhpEnumNode;
use T3Docs\GuidesPhpDomain\PhpDomain\FullyQualifiedNameService;

Expand All @@ -22,6 +23,7 @@ public function __construct(
GenericLinkProvider $genericLinkProvider,
private readonly FullyQualifiedNameService $fullyQualifiedNameService,
private readonly AnchorReducer $anchorReducer,
private readonly LoggerInterface $logger,
) {
parent::__construct($startingRule);
$genericLinkProvider->addGenericLink($this->getName(), $this->getName());
Expand All @@ -38,17 +40,33 @@ protected function processSub(
Directive $directive,
): Node|null {
$name = trim($directive->getData());
$fqn = $this->fullyQualifiedNameService->getFullyQualifiedName($name, true);
$type = null;

if (str_contains($name, ':')) {
[$name, $type] = explode(':', $name, 2);
$type = trim($type);
$this->logger->warning('Passing the type of a backed enum directly with the name is deprecated. Use option :type: instead.', $blockContext->getDocumentParserContext()->getLoggerInformation());
}

$fqn = $this->fullyQualifiedNameService->getFullyQualifiedName(trim($name), true);

$id = $this->anchorReducer->reduceAnchor($fqn->toString());

if ($directive->hasOption('type')) {
if ($type != null) {
$this->logger->warning('The type of the backed enum was set twice. The type from the option will be prefered.', $blockContext->getDocumentParserContext()->getLoggerInformation());
}
$type = $directive->getOption('type')->toString();
}

return new PhpEnumNode(
$id,
$fqn,
$collectionNode->getChildren(),
null,
[],
[],
$type,
);
}
}
34 changes: 34 additions & 0 deletions src/Nodes/PhpCaseNode.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace T3Docs\GuidesPhpDomain\Nodes;

use phpDocumentor\Guides\Nodes\Node;

final class PhpCaseNode extends PhpMemberNode
{
private const TYPE = 'const';

/**
* @param Node[] $value
*/
public function __construct(
string $id,
private readonly MemberNameNode $memberName,
array $value = [],
private readonly string|null $backedValue = null,
) {
parent::__construct($id, self::TYPE, $memberName->toString(), $value);
}

public function getMemberName(): MemberNameNode
{
return $this->memberName;
}

public function getBackedValue(): ?string
{
return $this->backedValue;
}
}
6 changes: 6 additions & 0 deletions src/Nodes/PhpEnumNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,13 @@ public function __construct(
PhpNamespaceNode|null $namespace = null,
array $members = [],
array $modifiers = [],
private readonly ?string $phpType = null,
) {
parent::__construct($id, self::TYPE, $name, $value, $namespace, $members, $modifiers);
}

public function getPhpType(): ?string
{
return $this->phpType;
}
}
33 changes: 33 additions & 0 deletions tests/integration/enum-backed-with-cases/expected/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<!-- content start -->
<div class="section" id="php-enum-with-const">
<h1>PHP Enum with Const</h1>

<dl class="php enum">
<dt class="sig sig-object php"
id="redsuit">
<em class="property"><span class="pre">enum</span> </em>
<span class="sig-name descname"><span class="pre">RedSuit</span></span>
<span class="pre"> : string</span> </dt>
<dd>
<p>In playing cards, a suit is one of the categories into which the
cards of a deck are divided.</p><dl class="php case">
<dt class="sig sig-object php" id="hearts">
<em class="property"><span class="pre">case</span></em>
<span class="sig-name descname"><span class="pre">Hearts</span></span>
: <span class="pre">&#039;H&#039;</span> </dt>
<dd><p>Hearts is one of the four suits in playing cards.</p></dd>
</dl>
<dl class="php case">
<dt class="sig sig-object php" id="diamonds">
<em class="property"><span class="pre">case</span></em>
<span class="sig-name descname"><span class="pre">Diamonds</span></span>
: <span class="pre">&#039;D&#039;</span> </dt>
<dd><p>Diamonds is one of the four suits in playing cards.</p></dd>
</dl>

</dd>
</dl>

</div>

<!-- content end -->
19 changes: 19 additions & 0 deletions tests/integration/enum-backed-with-cases/input/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
===================
PHP Enum with Const
===================

.. php:enum:: RedSuit
:type: string

In playing cards, a suit is one of the categories into which the
cards of a deck are divided.

.. php:case:: Hearts
:value: 'H'

Hearts is one of the four suits in playing cards.

.. php:case:: Diamonds
:value: 'D'

Diamonds is one of the four suits in playing cards.
48 changes: 48 additions & 0 deletions tests/integration/enum-with-cases/expected/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<!-- content start -->
<div class="section" id="php-enum-with-const">
<h1>PHP Enum with Const</h1>

<dl class="php enum">
<dt class="sig sig-object php"
id="suit">
<em class="property"><span class="pre">enum</span> </em>
<span class="sig-name descname"><span class="pre">Suit</span></span>

</dt>
<dd>
<p>In playing cards, a suit is one of the categories into which the
cards of a deck are divided.</p><dl class="php case">
<dt class="sig sig-object php" id="hearts">
<em class="property"><span class="pre">case</span></em>
<span class="sig-name descname"><span class="pre">Hearts</span></span>
: </dt>
<dd><p>Hearts is one of the four suits in playing cards.</p></dd>
</dl>
<dl class="php case">
<dt class="sig sig-object php" id="diamonds">
<em class="property"><span class="pre">case</span></em>
<span class="sig-name descname"><span class="pre">Diamonds</span></span>
: </dt>
<dd><p>Diamonds is one of the four suits in playing cards.</p></dd>
</dl>
<dl class="php case">
<dt class="sig sig-object php" id="clubs">
<em class="property"><span class="pre">case</span></em>
<span class="sig-name descname"><span class="pre">Clubs</span></span>
: </dt>
<dd><p>Clubs is one of the four suits in playing cards.</p></dd>
</dl>
<dl class="php case">
<dt class="sig sig-object php" id="spades">
<em class="property"><span class="pre">case</span></em>
<span class="sig-name descname"><span class="pre">Spades</span></span>
: </dt>
<dd><p>Spades is one of the four suits in playing cards.</p></dd>
</dl>

</dd>
</dl>

</div>

<!-- content end -->
24 changes: 24 additions & 0 deletions tests/integration/enum-with-cases/input/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
===================
PHP Enum with Const
===================

.. php:enum:: Suit
In playing cards, a suit is one of the categories into which the
cards of a deck are divided.

.. php:case:: Hearts
Hearts is one of the four suits in playing cards.

.. php:case:: Diamonds
Diamonds is one of the four suits in playing cards.

.. php:case:: Clubs
Clubs is one of the four suits in playing cards.

.. php:case:: Spades
Spades is one of the four suits in playing cards.
Loading

0 comments on commit 8410239

Please sign in to comment.