Skip to content

Commit 05e9eed

Browse files
committed
add nowdoc
1 parent 0206f1b commit 05e9eed

File tree

3 files changed

+118
-19
lines changed

3 files changed

+118
-19
lines changed

src/Parser/TypeParser.php

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -944,12 +944,31 @@ private function parseObjectShapeItem(TokenIterator $tokens): Ast\Type\ObjectSha
944944
$startLine = $tokens->currentTokenLine();
945945
$startIndex = $tokens->currentTokenIndex();
946946

947+
// parse any comments above the item
948+
$comments = [];
949+
while (1) {
950+
if ($tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL)) {
951+
continue;
952+
} elseif ($tokens->currentTokenType() === Lexer::TOKEN_COMMENT) {
953+
$comments[] = new Ast\Comment($tokens->currentTokenValue(), $tokens->currentTokenLine(), $tokens->currentTokenIndex());
954+
$tokens->next();
955+
} else {
956+
break;
957+
}
958+
}
959+
947960
$key = $this->parseObjectShapeKey($tokens);
948961
$optional = $tokens->tryConsumeTokenType(Lexer::TOKEN_NULLABLE);
949962
$tokens->consumeTokenType(Lexer::TOKEN_COLON);
950963
$value = $this->parse($tokens);
951964

952-
return $this->enrichWithAttributes($tokens, new Ast\Type\ObjectShapeItemNode($key, $optional, $value), $startLine, $startIndex);
965+
return $this->enrichWithAttributes(
966+
$tokens,
967+
new Ast\Type\ObjectShapeItemNode($key, $optional, $value),
968+
$startLine,
969+
$startIndex,
970+
$comments
971+
);
953972
}
954973

955974
/**

tests/PHPStan/Parser/TypeParserTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1966,6 +1966,7 @@ public function provideParseData(): array
19661966
],
19671967
[
19681968
'object{
1969+
// a is for apple
19691970
a: int,
19701971
}',
19711972
new ObjectShapeNode([
@@ -1979,6 +1980,9 @@ public function provideParseData(): array
19791980
[
19801981
'object{
19811982
a: int,
1983+
/*
1984+
* b is for banana
1985+
*/
19821986
b: string,
19831987
}',
19841988
new ObjectShapeNode([

tests/PHPStan/Printer/PrinterTest.php

Lines changed: 94 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,41 @@
5252
use function count;
5353
use const PHP_EOL;
5454

55+
function nowdoc(string $str): string
56+
{
57+
$lines = \preg_split('/\\n/', $str);
58+
59+
if ($lines === false) {
60+
return '';
61+
}
62+
63+
if (\count($lines) <= 2) {
64+
return '';
65+
}
66+
67+
// Toss out the first line
68+
$lines = \array_slice($lines, 1, \count($lines) - 1);
69+
70+
// normalize any tabs to spaces
71+
$lines = array_map(static function($line) {
72+
return preg_replace_callback('/(\t+)/m', function ($matches) {
73+
$fixed = str_repeat(' ', strlen($matches[1]));
74+
return $fixed;
75+
}, $line);
76+
}, $lines);
77+
78+
// take the ws from the first line and subtract them from all lines
79+
$matches = [];
80+
\preg_match('/(^[ \t]+)/', $lines[0], $matches);
81+
82+
$numLines = \count($lines);
83+
for ($i = 0; $i < $numLines; ++$i) {
84+
$lines[$i] = \str_replace($matches[0], '', $lines[$i]);
85+
}
86+
87+
return \implode("\n", $lines);
88+
}
89+
5590
class PrinterTest extends TestCase
5691
{
5792

@@ -648,7 +683,7 @@ public function enterNode(Node $node)
648683
$changeCallableTypeIdentifier,
649684
];
650685

651-
$addItemsToArrayShape = new class extends AbstractNodeVisitor {
686+
$addKeylessItemsToArrayShape = new class extends AbstractNodeVisitor {
652687

653688
public function enterNode(Node $node)
654689
{
@@ -806,7 +841,7 @@ public function enterNode(Node $node)
806841
'/**
807842
* @return array{float, int, string}
808843
*/',
809-
$addItemsToArrayShape,
844+
$addKeylessItemsToArrayShape,
810845
];
811846

812847
yield [
@@ -816,7 +851,7 @@ public function enterNode(Node $node)
816851
'/**
817852
* @return array{float, int, Foo, string}
818853
*/',
819-
$addItemsToArrayShape,
854+
$addKeylessItemsToArrayShape,
820855
];
821856

822857
yield [
@@ -834,7 +869,7 @@ public function enterNode(Node $node)
834869
* string,
835870
* }
836871
*/',
837-
$addItemsToArrayShape,
872+
$addKeylessItemsToArrayShape,
838873
];
839874

840875
yield [
@@ -852,7 +887,7 @@ public function enterNode(Node $node)
852887
* string
853888
* }
854889
*/',
855-
$addItemsToArrayShape,
890+
$addKeylessItemsToArrayShape,
856891
];
857892

858893
yield [
@@ -870,7 +905,7 @@ public function enterNode(Node $node)
870905
* string
871906
* }
872907
*/',
873-
$addItemsToArrayShape,
908+
$addKeylessItemsToArrayShape,
874909
];
875910

876911
yield [
@@ -888,7 +923,7 @@ public function enterNode(Node $node)
888923
* string,
889924
* }
890925
*/',
891-
$addItemsToArrayShape,
926+
$addKeylessItemsToArrayShape,
892927
];
893928

894929
yield [
@@ -906,7 +941,7 @@ public function enterNode(Node $node)
906941
* string
907942
* }
908943
*/',
909-
$addItemsToArrayShape,
944+
$addKeylessItemsToArrayShape,
910945
];
911946

912947
yield [
@@ -924,7 +959,7 @@ public function enterNode(Node $node)
924959
* string
925960
* }
926961
*/',
927-
$addItemsToArrayShape,
962+
$addKeylessItemsToArrayShape,
928963
];
929964

930965
$addItemsToObjectShape = new class extends AbstractNodeVisitor {
@@ -941,25 +976,66 @@ public function enterNode(Node $node)
941976
};
942977

943978
yield [
944-
'/**
945-
* @return object{}
946-
*/',
947-
'/**
948-
* @return object{foo: int}
949-
*/',
979+
nowdoc('
980+
/**
981+
* @return object{}
982+
*/'),
983+
nowdoc('
984+
/**
985+
* @return object{foo: int}
986+
*/'),
950987
$addItemsToObjectShape,
951988
];
952989

990+
yield [
991+
nowdoc('
992+
/**
993+
* @return object{bar: string}
994+
*/'),
995+
nowdoc('
996+
/**
997+
* @return object{bar: string, foo: int}
998+
*/'),
999+
$addItemsToObjectShape,
1000+
];
1001+
1002+
yield [
1003+
nowdoc('
1004+
/**
1005+
* @return object{bar: string}
1006+
*/'),
1007+
nowdoc('
1008+
/**
1009+
* @return object{bar: string, foo: int}
1010+
*/'),
1011+
$addItemsToObjectShape,
1012+
];
1013+
$addCommentedItemsToMultilineObjectShape = new class extends AbstractNodeVisitor {
1014+
1015+
public function enterNode(Node $node)
1016+
{
1017+
if ($node instanceof ObjectShapeNode) {
1018+
$node = new ObjectShapeItemNode(new IdentifierTypeNode('foo'), false, new IdentifierTypeNode('int'));
1019+
$node->setAttribute(Attribute::COMMENTS, [new Comment('// bar')]);
1020+
$node->items[] = $node;
1021+
}
1022+
1023+
return $node;
1024+
}
1025+
};
1026+
9531027
yield [
9541028
'/**
955-
* @return object{bar: string}
1029+
* @return object{}
9561030
*/',
9571031
'/**
958-
* @return object{bar: string, foo: int}
1032+
* @return object{foo: int}
9591033
*/',
960-
$addItemsToObjectShape,
1034+
$addCommentedItemsToMultilineObjectShape,
9611035
];
9621036

1037+
1038+
9631039
$addItemsToConstExprArray = new class extends AbstractNodeVisitor {
9641040

9651041
public function enterNode(Node $node)

0 commit comments

Comments
 (0)