Skip to content

Commit 37887de

Browse files
HarfushaAdam Halfar
andauthored
Add support for multiline annotations (#345)
* Add support for multiline annotations * Fix possibly wrong valueNode type * Fix missing new line before break --------- Co-authored-by: Adam Halfar <[email protected]>
1 parent 4d627ff commit 37887de

File tree

4 files changed

+120
-1
lines changed

4 files changed

+120
-1
lines changed

src/Annotator/AbstractAnnotator.php

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,29 @@ protected function parseExistingAnnotations(File $file, int $closeTagIndex, arra
480480
/** @var \PHPStan\PhpDocParser\Ast\PhpDoc\InvalidTagValueNode|\PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode $valueNode */
481481
$valueNode = static::getValueNode($tokens[$i]['content'], $content);
482482
if ($valueNode instanceof InvalidTagValueNode) {
483-
continue;
483+
$multilineFixed = false;
484+
for ($p = $i + 3; $p < $closeTagIndex; $p++) {
485+
if ($tokens[$p]['type'] === 'T_DOC_COMMENT_TAG') {
486+
break;
487+
}
488+
489+
if ($tokens[$p]['type'] !== 'T_DOC_COMMENT_STRING') {
490+
continue;
491+
}
492+
493+
$content .= $tokens[$p]['content'];
494+
/** @var \PHPStan\PhpDocParser\Ast\PhpDoc\InvalidTagValueNode|\PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode $valueNode */
495+
$valueNode = static::getValueNode($tokens[$i]['content'], $content);
496+
if (!($valueNode instanceof InvalidTagValueNode)) {
497+
$multilineFixed = true;
498+
499+
break;
500+
}
501+
}
502+
503+
if (!$multilineFixed || $valueNode instanceof InvalidTagValueNode) {
504+
continue;
505+
}
484506
}
485507

486508
$returnTypes = $this->valueNodeParts($valueNode);

tests/TestCase/Annotator/TemplateAnnotatorTest.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,33 @@ public function testAnnotateWithShapedArray() {
438438
$this->assertTextContains(' -> 1 annotation added.', $output);
439439
}
440440

441+
/**
442+
* Tests that a multiline array is parsed completly.
443+
*
444+
* @return void
445+
*/
446+
public function testAnnotateWithMultilineArray() {
447+
$annotator = $this->_getAnnotatorMock([]);
448+
449+
$expectedContent = str_replace("\r\n", "\n", file_get_contents(TEST_FILES . 'templates/multiline.php'));
450+
$callback = function($value) use ($expectedContent) {
451+
$value = str_replace(["\r\n", "\r"], "\n", $value);
452+
if ($value !== $expectedContent) {
453+
$this->_displayDiff($expectedContent, $value);
454+
}
455+
456+
return $value === $expectedContent;
457+
};
458+
$annotator->expects($this->once())->method('storeFile')->with($this->anything(), $this->callback($callback));
459+
460+
$path = TEST_ROOT . 'templates/Foos/multiline.php';
461+
$annotator->annotate($path);
462+
463+
$output = $this->out->output();
464+
465+
$this->assertTextContains(' -> 1 annotation added.', $output);
466+
}
467+
441468
/**
442469
* @param array $params
443470
* @return \IdeHelper\Annotator\TemplateAnnotator|\PHPUnit\Framework\MockObject\MockObject
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
/**
3+
* @var \TestApp\View\AppView $this
4+
* @var array $x
5+
* @var array<int> $ints
6+
* @var array{
7+
* a: int,
8+
* b: string|null
9+
* }|null $shaped
10+
* @var array{
11+
* c: array{
12+
* d: int|string,
13+
* e: string|null
14+
* }
15+
* } $nested
16+
*/
17+
foreach ($x as $y) {
18+
echo $y;
19+
}
20+
foreach ($foo as $int) {
21+
echo $int;
22+
}
23+
?>
24+
<div>
25+
<?php foreach ($ints as $int) {
26+
echo $int;
27+
} ?>
28+
<?php foreach ($shaped as $x) {
29+
echo h($x);
30+
} ?>
31+
<?php foreach ($nested['c'] as $subArray) {
32+
echo h($x);
33+
} ?>
34+
</div>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
/**
3+
* @var \TestApp\View\AppView $this
4+
* @var array $x
5+
* @var array<int> $ints
6+
* @var array{
7+
* a: int,
8+
* b: string|null
9+
* }|null $shaped
10+
* @var array{
11+
* c: array{
12+
* d: int|string,
13+
* e: string|null
14+
* }
15+
* } $nested
16+
*
17+
* @var mixed $foo
18+
*/
19+
foreach ($x as $y) {
20+
echo $y;
21+
}
22+
foreach ($foo as $int) {
23+
echo $int;
24+
}
25+
?>
26+
<div>
27+
<?php foreach ($ints as $int) {
28+
echo $int;
29+
} ?>
30+
<?php foreach ($shaped as $x) {
31+
echo h($x);
32+
} ?>
33+
<?php foreach ($nested['c'] as $subArray) {
34+
echo h($x);
35+
} ?>
36+
</div>

0 commit comments

Comments
 (0)