Skip to content

Commit d2baf6b

Browse files
committed
Make handle @param duplicates and word boundaries correct
1 parent 96f6eda commit d2baf6b

File tree

3 files changed

+73
-7
lines changed

3 files changed

+73
-7
lines changed

src/TokenRunner/DocBlock/MalformWorker/ParamNameTypoMalformWorker.php

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,25 +37,27 @@ public function work(string $docContent, Tokens $tokens, int $position): string
3737

3838
$paramNames = $this->getParamNames($docContent);
3939

40+
$missArgumentNames = [];
4041
// remove correct params
4142
foreach ($argumentNames as $key => $argumentName) {
4243
if (in_array($argumentName, $paramNames, true)) {
4344
$paramPosition = array_search($argumentName, $paramNames, true);
4445
unset($paramNames[$paramPosition]);
45-
unset($argumentNames[$key]);
46+
} else {
47+
$missArgumentNames[$key] = $argumentName;
4648
}
4749
}
4850

4951
// nothing to edit, all arguments are correct or there are no more @param annotations
50-
if ($argumentNames === []) {
52+
if ($missArgumentNames === []) {
5153
return $docContent;
5254
}
5355

5456
if ($paramNames === []) {
5557
return $docContent;
5658
}
5759

58-
return $this->fixTypos($argumentNames, $paramNames, $docContent);
60+
return $this->fixTypos($argumentNames, $missArgumentNames, $paramNames, $docContent);
5961
}
6062

6163
/**
@@ -93,20 +95,36 @@ private function getAnnotationsOfType(string $docContent, string $type): array
9395

9496
/**
9597
* @param string[] $argumentNames
98+
* @param string[] $missArgumentNames
9699
* @param string[] $paramNames
97100
*/
98-
private function fixTypos(array $argumentNames, array $paramNames, string $docContent): string
101+
private function fixTypos(array $argumentNames, array $missArgumentNames, array $paramNames, string $docContent): string
99102
{
100-
foreach ($argumentNames as $key => $argumentName) {
103+
// A table of permuted params. initialized by $argumentName instead of $paramNames is correct
104+
$replacedParams = array_fill_keys($argumentNames, false);
105+
106+
foreach ($missArgumentNames as $key => $argumentName) {
101107
// 1. the same position
102108
if (! isset($paramNames[$key])) {
103109
continue;
104110
}
105111

106112
$typoName = $paramNames[$key];
107-
$replacePattern = '#@param(.*?)' . preg_quote($typoName, '#') . '#';
113+
$replacePattern = '#@param(.*?)(' . preg_quote($typoName, '#') . '\b)#';
114+
115+
$docContent = Strings::replace($docContent, $replacePattern, static function ($matched) use ($argumentName, &$replacedParams) {
116+
$paramName = $matched[2];
117+
118+
// 2. If the PHPDoc $paramName is one of the existing $argumentNames and has not already been replaced, it will be deferred
119+
if (isset($replacedParams[$paramName]) && ! $replacedParams[$paramName]) {
120+
$replacedParams[$paramName] = true;
121+
122+
return $matched[0];
123+
}
108124

109-
$docContent = Strings::replace($docContent, $replacePattern, '@param$1' . $argumentName);
125+
// 3. Otherwise, replace $paramName with $argumentName in the @param line
126+
return sprintf('@param%s%s', $matched[1], $argumentName);
127+
});
110128
}
111129

112130
return $docContent;
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
An existing @param is incorrectly duplicated.
2+
<?php
3+
4+
/**
5+
* @param string $one
6+
* @param string $one
7+
*/
8+
function someFunction($one, $two): void
9+
{
10+
}
11+
?>
12+
-----
13+
An existing @param is incorrectly duplicated.
14+
<?php
15+
16+
/**
17+
* @param string $one
18+
* @param string $two
19+
*/
20+
function someFunction($one, $two): void
21+
{
22+
}
23+
?>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
Wrong @param name is a substring of another param.
2+
<?php
3+
4+
/**
5+
* @param string $foooo
6+
* @param string $fooooo
7+
* @param string $foooooo
8+
*/
9+
function someFunction($foo, $fooo): void
10+
{
11+
}
12+
?>
13+
-----
14+
Wrong @param name is a substring of another param.
15+
<?php
16+
17+
/**
18+
* @param string $foo
19+
* @param string $fooo
20+
* @param string $foooooo
21+
*/
22+
function someFunction($foo, $fooo): void
23+
{
24+
}
25+
?>

0 commit comments

Comments
 (0)