Skip to content

Commit b7050d0

Browse files
fain182claude
andcommitted
Fix @throws dependency line numbers to point to the tag, not the method
The startLine attribute was incorrectly set to the method's start line. Now uses the docblock start line combined with the relative line of each @throws tag (from ParserConfig lines=true) to compute the correct absolute line in the file. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent fbcd94c commit b7050d0

File tree

4 files changed

+24
-11
lines changed

4 files changed

+24
-11
lines changed

src/Analyzer/Docblock.php

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,21 @@ public function getReturnTagTypes(): array
4444
return array_filter($returnTypes);
4545
}
4646

47+
/**
48+
* @return array<array{type: string, line: int}>
49+
*/
4750
public function getThrowTagsTypes(): array
4851
{
49-
$throwTypes = array_map(
50-
fn (ThrowsTagValueNode $throwTag) => $this->getType($throwTag->type),
51-
$this->phpDocNode->getThrowsTagValues()
52-
);
52+
$throwTypes = [];
5353

54-
// remove null values
55-
return array_filter($throwTypes);
54+
foreach ($this->phpDocNode->getThrowsTagValues() as $throwTag) {
55+
$type = $this->getType($throwTag->type);
56+
if (null !== $type) {
57+
$throwTypes[] = ['type' => $type, 'line' => $throwTag->getAttribute('startLine') ?? 0];
58+
}
59+
}
60+
61+
return $throwTypes;
5662
}
5763

5864
public function getVarTagTypes(): array

src/Analyzer/DocblockTypesResolver.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,16 +188,18 @@ private function resolveThrowsValueType(Node $node, Docblock $docblock): void
188188
return;
189189
}
190190

191+
$docblockStartLine = $node->getDocComment() ? $node->getDocComment()->getStartLine() : $node->getStartLine();
192+
191193
$throwsTypesResolved = [];
192194

193-
foreach ($throwValues as $throwValue) {
195+
foreach ($throwValues as ['type' => $throwValue, 'line' => $relativeLine]) {
194196
if (str_starts_with($throwValue, '\\')) {
195197
$name = new FullyQualified(substr($throwValue, 1));
196198
} else {
197199
$name = $this->resolveName(new Name($throwValue), Stmt\Use_::TYPE_NORMAL);
198200
}
199201

200-
$name->setAttribute('startLine', $node->getStartLine());
202+
$name->setAttribute('startLine', $docblockStartLine + $relativeLine - 1);
201203

202204
$throwsTypesResolved[] = $name;
203205
}

tests/Unit/Analyzer/DocblockParserTest.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,12 @@ public function test_it_should_extract_types_from_throws_tag(): void
114114

115115
$varTags = $db->getThrowTagsTypes();
116116
self::assertCount(3, $varTags);
117-
self::assertEquals('\Exception', $varTags[0]);
118-
self::assertEquals('\Domain\Foo\FooException', $varTags[1]);
119-
self::assertEquals('BarException', $varTags[2]);
117+
self::assertEquals('\Exception', $varTags[0]['type']);
118+
self::assertEquals('\Domain\Foo\FooException', $varTags[1]['type']);
119+
self::assertEquals('BarException', $varTags[2]['type']);
120+
self::assertEquals(2, $varTags[0]['line']);
121+
self::assertEquals(3, $varTags[1]['line']);
122+
self::assertEquals(4, $varTags[2]['line']);
120123
}
121124

122125
public function test_it_should_extract_doctrine_like_annotations(): void

tests/Unit/Analyzer/DocblockTypesResolverTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,9 @@ public function myMethod2(array $aParam, array $users): array
104104
self::assertEquals('Application\Model\Product', $dep[6]->getFQCN()->toString());
105105
self::assertEquals('Domain\Foo\MyOtherClass', $dep[7]->getFQCN()->toString());
106106
self::assertEquals('Domain\Foo\FooException', $dep[8]->getFQCN()->toString());
107+
self::assertEquals(55, $dep[8]->getLine());
107108
self::assertEquals('Domain\Foo\BarException', $dep[9]->getFQCN()->toString());
109+
self::assertEquals(56, $dep[9]->getLine());
108110
self::assertEquals('Application\Model\User', $dep[10]->getFQCN()->toString());
109111
}
110112
}

0 commit comments

Comments
 (0)