Skip to content

Commit da2ee67

Browse files
committed
Annotate the offending lines not the file
1 parent 436084e commit da2ee67

8 files changed

+105
-34
lines changed

Magento2/Sniffs/Html/HtmlClosingVoidTagsSniff.php

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ class HtmlClosingVoidTagsSniff implements Sniff
5353
'wbr',
5454
];
5555

56+
/** @var int */
57+
private int $lastPointer = 0;
58+
5659
/**
5760
* @inheritdoc
5861
*/
@@ -82,14 +85,29 @@ public function process(File $phpcsFile, $stackPtr): void
8285
if (preg_match_all('$<(\w{2,})\s?[^<]*\/>$', $html, $matches, PREG_SET_ORDER)) {
8386
foreach ($matches as $match) {
8487
if (in_array($match[1], self::HTML_VOID_ELEMENTS)) {
85-
$fix = $phpcsFile->addFixableWarning(
86-
sprintf(self::WARNING_MESSAGE, $match[0]),
87-
null,
88-
self::WARNING_CODE
89-
);
88+
$ptr = $this->findPointer($phpcsFile, $match[0]);
89+
if ($ptr) {
90+
$fix = $phpcsFile->addFixableWarning(
91+
sprintf(self::WARNING_MESSAGE, $match[0]),
92+
$ptr,
93+
self::WARNING_CODE
94+
);
9095

91-
if ($fix) {
92-
$this->fixClosingTag($phpcsFile, $match[0]);
96+
if ($fix) {
97+
$token = $phpcsFile->getTokens()[$ptr];
98+
$original = $match[0];
99+
$replacement = str_replace('/>', '>', $original);
100+
$phpcsFile->fixer->replaceToken(
101+
$ptr,
102+
str_replace($original, $replacement, $token['content'])
103+
);
104+
}
105+
} else {
106+
$phpcsFile->addWarning(
107+
sprintf(self::WARNING_MESSAGE, $match[0]),
108+
null,
109+
self::WARNING_CODE
110+
);
93111
}
94112
}
95113
}
@@ -101,22 +119,25 @@ public function process(File $phpcsFile, $stackPtr): void
101119
*
102120
* @param File $phpcsFile
103121
* @param string $needle
122+
* @return int|null
104123
*/
105-
public function fixClosingTag(File $phpcsFile, string $needle): void
124+
public function findPointer(File $phpcsFile, string $needle): ?int
106125
{
107126
foreach ($phpcsFile->getTokens() as $ptr => $token) {
127+
if ($ptr < $this->lastPointer) {
128+
continue;
129+
}
130+
108131
if ($token['code'] !== T_INLINE_HTML) {
109132
continue;
110133
}
111134

112135
if (str_contains($token['content'], $needle)) {
113-
$original = $needle;
114-
$replacement = str_replace('/>', '>', $original);
115-
116-
$phpcsFile->fixer->replaceToken($ptr, str_replace($original, $replacement, $token['content']));
117-
118-
break;
136+
$this->lastPointer = $ptr;
137+
return $ptr;
119138
}
120139
}
140+
141+
return null;
121142
}
122143
}

Magento2/Sniffs/Html/HtmlSelfClosingTagsSniff.php

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ class HtmlSelfClosingTagsSniff implements Sniff
3939
'wbr',
4040
];
4141

42+
/** @var int */
43+
private int $lastPointer = 0;
44+
4245
/**
4346
* @inheritDoc
4447
*/
@@ -68,15 +71,32 @@ public function process(File $phpcsFile, $stackPtr)
6871
if (preg_match_all('$<(\w{2,})\s?[^<]*\/>$', $html, $matches, PREG_SET_ORDER)) {
6972
foreach ($matches as $match) {
7073
if (!in_array($match[1], self::HTML_VOID_ELEMENTS)) {
71-
$fix = $phpcsFile->addFixableError(
72-
'Avoid using self-closing tag with non-void html element'
73-
. ' - "' . $match[0] . PHP_EOL,
74-
null,
75-
'HtmlSelfClosingNonVoidTag'
76-
);
74+
$ptr = $this->findPointer($phpcsFile, $match[0]);
75+
if ($ptr) {
76+
$fix = $phpcsFile->addFixableError(
77+
'Avoid using self-closing tag with non-void html element'
78+
. ' - "' . $match[0] . PHP_EOL,
79+
$ptr,
80+
'HtmlSelfClosingNonVoidTag'
81+
);
82+
83+
if ($fix) {
84+
$token = $phpcsFile->getTokens()[$ptr];
85+
$original = $match[0];
86+
$replacement = str_replace('/>', '></' . $match[1] . '>', $original);
87+
$phpcsFile->fixer->replaceToken(
88+
$ptr,
89+
str_replace($original, $replacement, $token['content'])
90+
);
7791

78-
if ($fix) {
79-
$this->fixClosingTag($phpcsFile, $match);
92+
}
93+
} else {
94+
$phpcsFile->addError(
95+
'Avoid using self-closing tag with non-void html element'
96+
. ' - "' . $match[0] . PHP_EOL,
97+
null,
98+
'HtmlSelfClosingNonVoidTag'
99+
);
80100
}
81101
}
82102
}
@@ -86,24 +106,27 @@ public function process(File $phpcsFile, $stackPtr)
86106
/**
87107
* Apply a fix for the detected issue
88108
*
89-
* @param File $phpcsFile
90-
* @param array $match
109+
* @param File $phpcsFile
110+
* @param string $needle
111+
* @return int|null
91112
*/
92-
private function fixClosingTag(File $phpcsFile, array $match): void
113+
private function findPointer(File $phpcsFile, string $needle): ?int
93114
{
94115
foreach ($phpcsFile->getTokens() as $ptr => $token) {
95-
if ($token['code'] !== T_INLINE_HTML) {
116+
if ($ptr < $this->lastPointer) {
96117
continue;
97118
}
98119

99-
if (str_contains($token['content'], $match[0])) {
100-
$original = $match[0];
101-
$replacement = str_replace('/>', '></' . $match[1] . '>', $original);
102-
103-
$phpcsFile->fixer->replaceToken($ptr, str_replace($original, $replacement, $token['content']));
120+
if ($token['code'] !== T_INLINE_HTML) {
121+
continue;
122+
}
104123

105-
return;
124+
if (str_contains($token['content'], $needle)) {
125+
$this->lastPointer = $ptr;
126+
return $ptr;
106127
}
107128
}
129+
130+
return null;
108131
}
109132
}

Magento2/Tests/Html/HtmlClosingVoidTagsUnitTest.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,6 @@
2929
<track src=""/>
3030
</video>
3131
<wbr/>
32+
<hr/>
3233
</body>
3334
</html>

Magento2/Tests/Html/HtmlClosingVoidTagsUnitTest.inc.fixed

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,6 @@
2929
<track src="">
3030
</video>
3131
<wbr>
32+
<hr>
3233
</body>
3334
</html>

Magento2/Tests/Html/HtmlClosingVoidTagsUnitTest.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,21 @@ public function getErrorList()
2323
public function getWarningList()
2424
{
2525
return [
26-
1 => 14,
26+
10 => 1,
27+
11 => 1,
28+
14 => 1,
29+
15 => 1,
30+
18 => 1,
31+
21 => 1,
32+
22 => 1,
33+
23 => 1,
34+
24 => 1,
35+
25 => 1,
36+
26 => 1,
37+
28 => 1,
38+
29 => 1,
39+
31 => 1,
40+
32 => 1,
2741
];
2842
}
2943
}

Magento2/Tests/Html/HtmlSelfClosingTagsUnitTest.1.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,6 @@
3939
<each/>
4040
<translate/>
4141
<scope/>
42+
<span/>
4243
</body>
4344
</html>

Magento2/Tests/Html/HtmlSelfClosingTagsUnitTest.1.inc.fixed

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,6 @@
3939
<each></each>
4040
<translate></translate>
4141
<scope></scope>
42+
<span></span>
4243
</body>
4344
</html>

Magento2/Tests/Html/HtmlSelfClosingTagsUnitTest.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,16 @@ class HtmlSelfClosingTagsUnitTest extends AbstractSniffUnitTest
1515
public function getErrorList()
1616
{
1717
return [
18-
1 => 9,
18+
33 => 1,
19+
34 => 1,
20+
35 => 1,
21+
36 => 1,
22+
37 => 1,
23+
38 => 1,
24+
39 => 1,
25+
40 => 1,
26+
41 => 1,
27+
42 => 1,
1928
];
2029
}
2130

0 commit comments

Comments
 (0)