Skip to content

Commit 19f578a

Browse files
committed
add more tests for array shape comments
1 parent 85b06ad commit 19f578a

File tree

5 files changed

+633
-95
lines changed

5 files changed

+633
-95
lines changed

src/Printer/Printer.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,7 @@ private function isMultiline(int $initialIndex, array $nodes, TokenIterator $ori
749749

750750
$c = preg_match_all('~\n(?<before>[\\x09\\x20]*)\*(?<after>\\x20*)~', $allText, $matches, PREG_SET_ORDER);
751751
if ($c === 0) {
752-
return [$isMultiline, '', ''];
752+
return [$isMultiline, ' ', ' '];
753753
}
754754

755755
$before = '';
@@ -765,6 +765,9 @@ private function isMultiline(int $initialIndex, array $nodes, TokenIterator $ori
765765
$after = $match['after'];
766766
}
767767

768+
$before = strlen($before) === 0 ? ' ' : $before;
769+
$after = strlen($after) === 0 ? ' ' : $after;
770+
768771
return [$isMultiline, $before, $after];
769772
}
770773

Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\PhpDocParser\Printer;
4+
5+
use PHPStan\PhpDocParser\Ast\AbstractNodeVisitor;
6+
use PHPStan\PhpDocParser\Ast\Node;
7+
use PHPStan\PhpDocParser\Ast\NodeTraverser;
8+
use PHPStan\PhpDocParser\Ast\NodeVisitor;
9+
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocNode;
10+
use PHPStan\PhpDocParser\Ast\Type\ArrayShapeItemNode;
11+
use PHPStan\PhpDocParser\Ast\Type\ArrayShapeNode;
12+
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
13+
use PHPStan\PhpDocParser\Lexer\Lexer;
14+
use PHPStan\PhpDocParser\Parser\TokenIterator;
15+
use function array_splice;
16+
use function array_unshift;
17+
use function count;
18+
19+
class PrintArrayShapeWithBlockCommentTest extends PrinterTestBase
20+
{
21+
22+
/**
23+
* @return iterable<array{string, string}>
24+
*/
25+
public function dataPrintArrayFormatPreservingAddFront(): iterable
26+
{
27+
yield [
28+
self::nowdoc('
29+
/**
30+
* @param array{} $foo
31+
*/'),
32+
self::nowdoc('
33+
/**
34+
* @param array{float} $foo
35+
*/'),
36+
];
37+
38+
yield [
39+
self::nowdoc('
40+
/**
41+
* @param array{string} $foo
42+
*/'),
43+
self::nowdoc('
44+
/**
45+
* @param array{/* A fractional number
46+
* can often
47+
* be just what you need
48+
* */
49+
* float,
50+
* string} $foo
51+
*/'),
52+
];
53+
54+
yield [
55+
self::nowdoc('
56+
/**
57+
* @param array{
58+
* string,int} $foo
59+
*/'),
60+
self::nowdoc('
61+
/**
62+
* @param array{
63+
* /* A fractional number
64+
* can often
65+
* be just what you need
66+
* */
67+
* float,
68+
* string,int} $foo
69+
*/'),
70+
];
71+
72+
yield [
73+
self::nowdoc('
74+
/**
75+
* @param array{
76+
* string,
77+
* int
78+
* } $foo
79+
*/'),
80+
self::nowdoc('
81+
/**
82+
* @param array{
83+
* /* A fractional number
84+
* can often
85+
* be just what you need
86+
* */
87+
* float,
88+
* string,
89+
* int
90+
* } $foo
91+
*/'),
92+
];
93+
}
94+
95+
/**
96+
* @dataProvider dataPrintArrayFormatPreservingAddFront
97+
*/
98+
public function testPrintFormatPreservingSingleLineAddFront(string $phpDoc, string $expectedResult): void
99+
{
100+
$visitor = new class extends AbstractNodeVisitor {
101+
102+
public function enterNode(Node $node)
103+
{
104+
if ($node instanceof ArrayShapeNode) {
105+
array_unshift($node->items, PrinterTestBase::withComment(
106+
new ArrayShapeItemNode(null, false, new IdentifierTypeNode('float')),
107+
PrinterTestBase::nowdoc('
108+
/* A fractional number
109+
can often
110+
be just what you need
111+
*/')
112+
));
113+
}
114+
115+
return $node;
116+
}
117+
118+
};
119+
120+
$lexer = new Lexer(true);
121+
$tokens = new TokenIterator($lexer->tokenize($phpDoc));
122+
$phpDocNode = $this->phpDocParser->parse($tokens);
123+
$cloningTraverser = new NodeTraverser([new NodeVisitor\CloningVisitor()]);
124+
$newNodes = $cloningTraverser->traverse([$phpDocNode]);
125+
126+
$changingTraverser = new NodeTraverser([$visitor]);
127+
128+
/** @var PhpDocNode $newNode */
129+
[$newNode] = $changingTraverser->traverse($newNodes);
130+
131+
$printer = new Printer();
132+
$actualResult = $printer->printFormatPreserving($newNode, $phpDocNode, $tokens);
133+
$this->assertSame($expectedResult, $actualResult);
134+
135+
$this->assertEquals(
136+
$this->unsetAttributes($newNode),
137+
$this->unsetAttributes($this->phpDocParser->parse(new TokenIterator($lexer->tokenize($actualResult))))
138+
);
139+
}
140+
141+
142+
/**
143+
* @return iterable<array{string, string}>
144+
*/
145+
public function dataPrintArrayFormatPreservingAddMiddle(): iterable
146+
{
147+
yield [
148+
self::nowdoc('
149+
/**
150+
* @param array{} $foo
151+
*/'),
152+
self::nowdoc('
153+
/**
154+
* @param array{float} $foo
155+
*/'),
156+
];
157+
158+
yield [
159+
self::nowdoc('
160+
/**
161+
* @param array{string} $foo
162+
*/'),
163+
self::nowdoc('
164+
/**
165+
* @param array{string,
166+
* /* A fractional number
167+
* can often
168+
* be just what you need
169+
* */
170+
* float} $foo
171+
*/'),
172+
];
173+
174+
yield [
175+
self::nowdoc('
176+
/**
177+
* @param array{
178+
* string,int} $foo
179+
*/'),
180+
self::nowdoc('
181+
/**
182+
* @param array{
183+
* string,
184+
* /* A fractional number
185+
* can often
186+
* be just what you need
187+
* */
188+
* float,int} $foo
189+
*/'),
190+
];
191+
192+
yield [
193+
self::nowdoc('
194+
/**
195+
* @param array{
196+
* string,
197+
* int
198+
* } $foo
199+
*/'),
200+
self::nowdoc('
201+
/**
202+
* @param array{
203+
* string,
204+
* /* A fractional number
205+
* can often
206+
* be just what you need
207+
* */
208+
* float,
209+
* int
210+
* } $foo
211+
*/'),
212+
];
213+
}
214+
215+
/**
216+
* @dataProvider dataPrintArrayFormatPreservingAddMiddle
217+
*/
218+
public function testPrintFormatPreservingSingleLineAddMiddle(string $phpDoc, string $expectedResult): void
219+
{
220+
$visitor = new class extends AbstractNodeVisitor {
221+
222+
public function enterNode(Node $node)
223+
{
224+
$newItem = PrinterTestBase::withComment(
225+
new ArrayShapeItemNode(null, false, new IdentifierTypeNode('float')),
226+
PrinterTestBase::nowdoc('
227+
/* A fractional number
228+
can often
229+
be just what you need
230+
*/')
231+
);
232+
233+
if ($node instanceof ArrayShapeNode) {
234+
if (count($node->items) === 0) {
235+
$node->items[] = $newItem;
236+
} else {
237+
array_splice($node->items, 1, 0, [$newItem]);
238+
}
239+
}
240+
241+
return $node;
242+
}
243+
244+
};
245+
246+
$lexer = new Lexer(true);
247+
$tokens = new TokenIterator($lexer->tokenize($phpDoc));
248+
$phpDocNode = $this->phpDocParser->parse($tokens);
249+
$cloningTraverser = new NodeTraverser([new NodeVisitor\CloningVisitor()]);
250+
$newNodes = $cloningTraverser->traverse([$phpDocNode]);
251+
252+
$changingTraverser = new NodeTraverser([$visitor]);
253+
254+
/** @var PhpDocNode $newNode */
255+
[$newNode] = $changingTraverser->traverse($newNodes);
256+
257+
$printer = new Printer();
258+
$actualResult = $printer->printFormatPreserving($newNode, $phpDocNode, $tokens);
259+
$this->assertSame($expectedResult, $actualResult);
260+
261+
$this->assertEquals(
262+
$this->unsetAttributes($newNode),
263+
$this->unsetAttributes($this->phpDocParser->parse(new TokenIterator($lexer->tokenize($actualResult))))
264+
);
265+
}
266+
267+
}

0 commit comments

Comments
 (0)