Skip to content

Commit 95245da

Browse files
authored
Add support for enums (#44)
* Add support for enums * Fix typos
1 parent fe8fd9d commit 95245da

8 files changed

Lines changed: 142 additions & 7 deletions

src/GenerateStubsCommand.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class GenerateStubsCommand extends Command
2929
['classes', StubsGenerator::CLASSES],
3030
['interfaces', StubsGenerator::INTERFACES],
3131
['traits', StubsGenerator::TRAITS],
32+
['enums', StubsGenerator::ENUMS],
3233
['documented-globals', StubsGenerator::DOCUMENTED_GLOBALS],
3334
['undocumented-globals', StubsGenerator::UNDOCUMENTED_GLOBALS],
3435
['globals', StubsGenerator::GLOBALS],
@@ -82,7 +83,7 @@ protected function interact(InputInterface $input, OutputInterface $output): voi
8283
}
8384

8485
$io = new SymfonyStyle($input, $output);
85-
$message = "The file '{$this->outFile}' already exists. Overwrite?";
86+
$message = "The file '{$this->outFile}' already exists. Overwrite?";
8687
if (!$input->getOption('force') && !$io->confirm($message, false)) {
8788
exit(1);
8889
}

src/NodeVisitor.php

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use PhpParser\Node\Stmt\ClassLike;
1717
use PhpParser\Node\Stmt\ClassMethod;
1818
use PhpParser\Node\Stmt\Const_;
19+
use PhpParser\Node\Stmt\Enum_;
1920
use PhpParser\Node\Stmt\Expression;
2021
use PhpParser\Node\Stmt\Function_;
2122
use PhpParser\Node\Stmt\If_;
@@ -47,6 +48,8 @@ class NodeVisitor extends NodeVisitorAbstract
4748
/** @var bool */
4849
private $needsInterfaces;
4950
/** @var bool */
51+
private $needsEnums;
52+
/** @var bool */
5053
private $needsDocumentedGlobals;
5154
/** @var bool */
5255
private $needsUndocumentedGlobals;
@@ -90,6 +93,7 @@ class NodeVisitor extends NodeVisitorAbstract
9093
'classes' => [],
9194
'interfaces' => [],
9295
'traits' => [],
96+
'enums' => [],
9397
'constants' => [],
9498
'globals' => [],
9599
];
@@ -105,6 +109,7 @@ public function init(int $symbols = StubsGenerator::DEFAULT, array $config = [])
105109
$this->needsClasses = ($symbols & StubsGenerator::CLASSES) !== 0;
106110
$this->needsTraits = ($symbols & StubsGenerator::TRAITS) !== 0;
107111
$this->needsInterfaces = ($symbols & StubsGenerator::INTERFACES) !== 0;
112+
$this->needsEnums = ($symbols & StubsGenerator::ENUMS) !== 0;
108113
$this->needsDocumentedGlobals = ($symbols & StubsGenerator::DOCUMENTED_GLOBALS) !== 0;
109114
$this->needsUndocumentedGlobals = ($symbols & StubsGenerator::UNDOCUMENTED_GLOBALS) !== 0;
110115
$this->needsConstants = ($symbols & StubsGenerator::CONSTANTS) !== 0;
@@ -133,6 +138,7 @@ public function enterNode(Node $node)
133138
if (($this->needsClasses && $node instanceof Class_)
134139
|| ($this->needsInterfaces && $node instanceof Interface_)
135140
|| ($this->needsTraits && $node instanceof Trait_)
141+
|| ($this->needsEnums && $node instanceof Enum_)
136142
) {
137143
// We'll need to parse all descendents of these nodes (if we plan to
138144
// include them in the stubs at all) so we get method, property, and
@@ -209,6 +215,7 @@ public function leaveNode(Node $node, bool $preserveStack = false)
209215
|| $node instanceof Class_
210216
|| $node instanceof Interface_
211217
|| $node instanceof Trait_
218+
|| $node instanceof Enum_
212219
|| $node instanceof Const_
213220
|| (
214221
$node instanceof Expression &&
@@ -224,7 +231,7 @@ public function leaveNode(Node $node, bool $preserveStack = false)
224231
if ($node instanceof If_) {
225232
// Replace the if statement with its set of children, but only those
226233
// that we want. Have to manually call leaveNode on each; it won't
227-
// be called automatically..
234+
// be called automatically.
228235
$stmts = [];
229236
foreach ($node->stmts as $stmt) {
230237
if ($this->leaveNode($stmt, true) !== NodeTraverser::REMOVE_NODE) {
@@ -248,11 +255,14 @@ public function leaveNode(Node $node, bool $preserveStack = false)
248255

249256
if ($parent && !($parent instanceof Namespace_)) {
250257
// Implies `$parent instanceof ClassLike`, which means $node is a
251-
// either a method, property, or constant, or its part of the
252-
// declaration itself (e.g., `extends`).
258+
// either a method, property, or constant, or enum case, or its part
259+
// of the declaration itself (e.g., `extends`).
253260

254-
if (!$this->includeInaccessibleClassNodes && $parent instanceof Class_ && ($node instanceof ClassMethod || $node instanceof ClassConst || $node instanceof Property)) {
255-
if ($node->isPrivate() || ($parent->isFinal() && $node->isProtected())) {
261+
if (!$this->includeInaccessibleClassNodes && ($parent instanceof Class_ || $parent instanceof Enum_) && ($node instanceof ClassMethod || $node instanceof ClassConst || $node instanceof Property)) {
262+
if ($node->isPrivate()
263+
|| ($parent instanceof Class_ && $parent->isFinal() && $node->isProtected())
264+
|| ($parent instanceof Enum_ && $node->isProtected())
265+
) {
256266
return NodeTraverser::REMOVE_NODE;
257267
}
258268
}
@@ -378,6 +388,12 @@ private function needsNode(Node $node, string $namespace): bool
378388
&& !trait_exists($fullyQualifiedName);
379389
}
380390

391+
if ($node instanceof Enum_) {
392+
return $this->needsEnums
393+
&& $this->count('enums', $fullyQualifiedName)
394+
&& !enum_exists($fullyQualifiedName);
395+
}
396+
381397
if ($this->needsConstants) {
382398
if ($node instanceof Const_) {
383399
$node->consts = \array_filter(

src/StubsGenerator.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,13 @@ class StubsGenerator
7373
*/
7474
public const CONSTANTS = 64;
7575

76+
/**
77+
* Enum symbol type.
78+
*
79+
* @var int
80+
*/
81+
public const ENUMS = 128;
82+
7683
/**
7784
* The default set of symbol types.
7885
*
@@ -85,7 +92,7 @@ class StubsGenerator
8592
*
8693
* @var int
8794
*/
88-
public const ALL = self::FUNCTIONS | self::CLASSES | self::TRAITS | self::INTERFACES | self::GLOBALS | self::CONSTANTS;
95+
public const ALL = self::FUNCTIONS | self::CLASSES | self::TRAITS | self::INTERFACES | self::ENUMS | self::GLOBALS | self::CONSTANTS;
8996

9097
/** @var int */
9198
private $symbols;

test/NodeVisitorTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ public function inputOutputProvider(): array
4747
'junk',
4848
'namespaces',
4949
'constants',
50+
'enums',
51+
['enums', 'enums-include-inaccessible-class-nodes', null, ['include_inaccessible_class_nodes' => true]],
52+
['enums', 'enums-default-symbols', StubsGenerator::DEFAULT],
5053
];
5154

5255
$baseDir = __DIR__ . '/files/';
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<?php
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
/** doc */
3+
enum A
4+
{
5+
case A;
6+
case B;
7+
8+
public const C = 'C';
9+
protected const D = 'D';
10+
private const E = 'E';
11+
12+
/** doc */
13+
public function a(): void
14+
{
15+
}
16+
17+
/** doc */
18+
protected function b(): void
19+
{
20+
}
21+
22+
/** doc */
23+
private function c(): void
24+
{
25+
}
26+
27+
/** doc */
28+
public static function d(): self
29+
{
30+
}
31+
32+
/** doc */
33+
protected static function e(): string
34+
{
35+
}
36+
37+
/** doc */
38+
private static function e(): void
39+
{
40+
}
41+
}

test/files/enums.in.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
/** doc */
3+
enum A
4+
{
5+
case A;
6+
case B;
7+
8+
public const C = 'C';
9+
protected const D = 'D';
10+
private const E = 'E';
11+
12+
/** doc */
13+
public function a(): void
14+
{
15+
return;
16+
}
17+
18+
/** doc */
19+
protected function b(): void
20+
{
21+
return;
22+
}
23+
24+
/** doc */
25+
private function c(): void
26+
{
27+
return;
28+
}
29+
30+
/** doc */
31+
public static function d(): self
32+
{
33+
return self::A;
34+
}
35+
36+
/** doc */
37+
protected static function e(): string
38+
{
39+
return self::D;
40+
}
41+
42+
/** doc */
43+
private static function e(): void
44+
{
45+
return;
46+
}
47+
}

test/files/enums.out.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
/** doc */
3+
enum A
4+
{
5+
case A;
6+
case B;
7+
8+
public const C = 'C';
9+
10+
/** doc */
11+
public function a(): void
12+
{
13+
}
14+
15+
/** doc */
16+
public static function d(): self
17+
{
18+
}
19+
}

0 commit comments

Comments
 (0)