Skip to content

Commit f3342d6

Browse files
committed
support comments in array shape
1 parent e540adc commit f3342d6

File tree

7 files changed

+2235
-2151
lines changed

7 files changed

+2235
-2151
lines changed

src/Ast/Type/ArrayShapeNode.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ public function __construct(array $items, bool $sealed = true, string $kind = se
3333
$this->kind = $kind;
3434
}
3535

36+
/**
37+
* @return array<ArrayShapeItemNode>
38+
*/
39+
public function items(): array {
40+
return array_filter($this->items, fn ($item) => $item instanceof ArrayShapeItemNode);
41+
}
3642

3743
public function __toString(): string
3844
{
@@ -42,7 +48,18 @@ public function __toString(): string
4248
$items[] = '...';
4349
}
4450

45-
return $this->kind . '{' . implode(', ', $items) . '}';
51+
$res = $this->kind . '{';
52+
foreach($items as $idx => $item) {
53+
$res .= $item;
54+
55+
if($item instanceof ArrayShapeItemNode && $idx < count($items) - 1) {
56+
$res .= ', ';
57+
}
58+
59+
}
60+
$res .= '}';
61+
62+
return $res;
4663
}
4764

4865
}

src/Lexer/Lexer.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ class Lexer
5050
public const TOKEN_NEGATED = 35;
5151
public const TOKEN_ARROW = 36;
5252

53+
public const TOKEN_COMMENT = 37;
54+
5355
public const TOKEN_LABELS = [
5456
self::TOKEN_REFERENCE => '\'&\'',
5557
self::TOKEN_UNION => '\'|\'',
@@ -65,6 +67,7 @@ class Lexer
6567
self::TOKEN_OPEN_CURLY_BRACKET => '\'{\'',
6668
self::TOKEN_CLOSE_CURLY_BRACKET => '\'}\'',
6769
self::TOKEN_COMMA => '\',\'',
70+
self::TOKEN_COMMENT => '\'//\'',
6871
self::TOKEN_COLON => '\':\'',
6972
self::TOKEN_VARIADIC => '\'...\'',
7073
self::TOKEN_DOUBLE_COLON => '\'::\'',
@@ -160,6 +163,7 @@ private function generateRegexp(): string
160163
self::TOKEN_CLOSE_CURLY_BRACKET => '\\}',
161164

162165
self::TOKEN_COMMA => ',',
166+
self::TOKEN_COMMENT => '//',
163167
self::TOKEN_VARIADIC => '\\.\\.\\.',
164168
self::TOKEN_DOUBLE_COLON => '::',
165169
self::TOKEN_DOUBLE_ARROW => '=>',

src/Parser/TokenIterator.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,10 +239,10 @@ public function joinUntil(int ...$tokenType): string
239239
}
240240

241241

242-
public function next(): void
242+
public function next(bool $skipIrrelevant = true): void
243243
{
244244
$this->index++;
245-
$this->skipIrrelevantTokens();
245+
$skipIrrelevant && $this->skipIrrelevantTokens();
246246
}
247247

248248

src/Parser/TypeParser.php

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,24 @@ private function parseArrayShape(TokenIterator $tokens, Ast\Type\TypeNode $type,
749749
$sealed = true;
750750

751751
do {
752-
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
752+
$tokens->pushSavePoint();
753+
$tokens->next();
754+
$tab = "\t";
755+
if($tokens->currentTokenType() == Lexer::TOKEN_CLOSE_CURLY_BRACKET) {
756+
$tab = '';
757+
}
758+
$tokens->rollback();
759+
if($tokens->currentTokenType() == Lexer::TOKEN_PHPDOC_EOL) {
760+
$startLine = $tokens->currentTokenLine();
761+
$startIndex = $tokens->currentTokenIndex();
762+
$items[] = $this->enrichWithAttributes(
763+
$tokens,
764+
new Ast\Type\IdentifierTypeNode("\n$tab"),
765+
$startLine,
766+
$startIndex
767+
);
768+
$tokens->next();
769+
}
753770

754771
if ($tokens->tryConsumeTokenType(Lexer::TOKEN_CLOSE_CURLY_BRACKET)) {
755772
return new Ast\Type\ArrayShapeNode($items, true, $kind);
@@ -761,6 +778,22 @@ private function parseArrayShape(TokenIterator $tokens, Ast\Type\TypeNode $type,
761778
break;
762779
}
763780

781+
if ($tokens->tryConsumeTokenType(Lexer::TOKEN_COMMENT)) {
782+
$items[] = $this->parseSimpleComment($tokens);
783+
}
784+
785+
if($tokens->currentTokenType() == Lexer::TOKEN_PHPDOC_EOL) {
786+
$startLine = $tokens->currentTokenLine();
787+
$startIndex = $tokens->currentTokenIndex();
788+
$items[] = $this->enrichWithAttributes(
789+
$tokens,
790+
new Ast\Type\IdentifierTypeNode("\n\t"),
791+
$startLine,
792+
$startIndex
793+
);
794+
$tokens->next();
795+
}
796+
764797
$items[] = $this->parseArrayShapeItem($tokens);
765798

766799
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
@@ -772,6 +805,25 @@ private function parseArrayShape(TokenIterator $tokens, Ast\Type\TypeNode $type,
772805
return new Ast\Type\ArrayShapeNode($items, $sealed, $kind);
773806
}
774807

808+
private function parseSimpleComment(TokenIterator $tokens): Ast\Type\CommentNode
809+
{
810+
$startLine = $tokens->currentTokenLine();
811+
$startIndex = $tokens->currentTokenIndex();
812+
813+
$text = '';
814+
815+
while($tokens->currentTokenType() != Lexer::TOKEN_PHPDOC_EOL) {
816+
$text .= $tokens->currentTokenValue();
817+
$tokens->next(false);
818+
}
819+
820+
return $this->enrichWithAttributes(
821+
$tokens,
822+
new Ast\Type\CommentNode($text),
823+
$startLine,
824+
$startIndex
825+
);
826+
}
775827

776828
/** @phpstan-impure */
777829
private function parseArrayShapeItem(TokenIterator $tokens): Ast\Type\ArrayShapeItemNode

src/Printer/Printer.php

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -339,15 +339,7 @@ private function printTagValue(PhpDocTagValueNode $node): string
339339
private function printType(TypeNode $node): string
340340
{
341341
if ($node instanceof ArrayShapeNode) {
342-
$items = array_map(function (ArrayShapeItemNode $item): string {
343-
return $this->printType($item);
344-
}, $node->items);
345-
346-
if (! $node->sealed) {
347-
$items[] = '...';
348-
}
349-
350-
return $node->kind . '{' . implode(', ', $items) . '}';
342+
return (string)$node;
351343
}
352344
if ($node instanceof ArrayShapeItemNode) {
353345
if ($node->keyName !== null) {

0 commit comments

Comments
 (0)