Skip to content

Commit 8af4b4a

Browse files
committed
Detect trailing whitespace within comments in TrailingWhitespace
1 parent 53f7d67 commit 8af4b4a

File tree

2 files changed

+107
-3
lines changed

2 files changed

+107
-3
lines changed

delphi-checks/src/main/java/au/com/integradev/delphi/checks/TrailingWhitespaceCheck.java

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@
2020

2121
import static java.util.regex.Pattern.compile;
2222

23+
import com.google.common.base.CharMatcher;
2324
import com.google.common.base.Splitter;
2425
import java.util.regex.Pattern;
25-
import org.apache.commons.lang3.StringUtils;
2626
import org.sonar.check.Rule;
2727
import org.sonar.plugins.communitydelphi.api.check.DelphiCheck;
2828
import org.sonar.plugins.communitydelphi.api.check.DelphiCheckContext;
@@ -36,9 +36,19 @@ public class TrailingWhitespaceCheck extends DelphiCheck {
3636
private static final String MESSAGE = "Remove this trailing whitespace.";
3737

3838
private static final Pattern NEW_LINE_DELIMITER = compile("\r\n?|\n");
39+
private static final Splitter NEW_LINE_SPLITTER = Splitter.on(NEW_LINE_DELIMITER);
40+
private static final CharMatcher WHITESPACE_MATCHER =
41+
CharMatcher.inRange((char) 0x00, (char) 0x20)
42+
.and(CharMatcher.isNot('\r'))
43+
.and(CharMatcher.isNot('\n'));
3944

4045
@Override
4146
public void visitToken(DelphiToken token, DelphiCheckContext context) {
47+
visitWhitespace(token, context);
48+
visitComment(token, context);
49+
}
50+
51+
private static void visitWhitespace(DelphiToken token, DelphiCheckContext context) {
4252
if (!token.isWhitespace()) {
4353
return;
4454
}
@@ -50,8 +60,8 @@ public void visitToken(DelphiToken token, DelphiCheckContext context) {
5060
int line = token.getBeginLine();
5161
int column = token.getBeginColumn();
5262

53-
String image = StringUtils.stripEnd(token.getImage(), " \t\f");
54-
var parts = Splitter.on(NEW_LINE_DELIMITER).split(image);
63+
String image = WHITESPACE_MATCHER.trimTrailingFrom(token.getImage());
64+
var parts = NEW_LINE_SPLITTER.split(image);
5565
for (String whitespace : parts) {
5666
if (!whitespace.isEmpty()) {
5767
context
@@ -64,4 +74,29 @@ public void visitToken(DelphiToken token, DelphiCheckContext context) {
6474
column = 0;
6575
}
6676
}
77+
78+
private static void visitComment(DelphiToken token, DelphiCheckContext context) {
79+
if (!token.isComment()) {
80+
return;
81+
}
82+
83+
var commentLines = NEW_LINE_SPLITTER.splitToList(token.getImage());
84+
85+
for (int i = 0; i < commentLines.size(); ++i) {
86+
String commentLine = commentLines.get(i);
87+
String trimmedCommentLine = WHITESPACE_MATCHER.trimTrailingFrom(commentLine);
88+
int whitespaceLength = commentLine.length() - trimmedCommentLine.length();
89+
90+
if (whitespaceLength > 0) {
91+
int line = token.getBeginLine() + i;
92+
int column = trimmedCommentLine.length();
93+
94+
context
95+
.newIssue()
96+
.onFilePosition(FilePosition.from(line, column, line, column + whitespaceLength))
97+
.withMessage(MESSAGE)
98+
.report();
99+
}
100+
}
101+
}
67102
}

delphi-checks/src/test/java/au/com/integradev/delphi/checks/TrailingWhitespaceCheckTest.java

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,73 @@ void testLeadingWhitespaceShouldNotAddIssue() {
7171
.onFile(new DelphiTestUnitBuilder().appendImpl("\t \t \t var Foo: TObject;"))
7272
.verifyNoIssues();
7373
}
74+
75+
@Test
76+
void testNoTrailingSpaceInLineCommentShouldNotAddIssue() {
77+
CheckVerifier.newVerifier()
78+
.withCheck(new TrailingWhitespaceCheck())
79+
.onFile(
80+
new DelphiTestUnitBuilder().appendImpl("// there is no trailing whitespace in here"))
81+
.verifyNoIssues();
82+
}
83+
84+
@Test
85+
void testTrailingSpaceInLineCommentShouldAddIssue() {
86+
CheckVerifier.newVerifier()
87+
.withCheck(new TrailingWhitespaceCheck())
88+
.onFile(
89+
new DelphiTestUnitBuilder()
90+
.appendImpl("// Noncompliant@+1")
91+
.appendImpl("// hey, there's a trailing spaces in here! "))
92+
.verifyIssues();
93+
}
94+
95+
@Test
96+
void testTrailingTabsInLineCommentShouldAddIssue() {
97+
CheckVerifier.newVerifier()
98+
.withCheck(new TrailingWhitespaceCheck())
99+
.onFile(
100+
new DelphiTestUnitBuilder()
101+
.appendImpl("// Noncompliant@+1")
102+
.appendImpl("// hey, there's a trailing tab in here!\t"))
103+
.verifyIssues();
104+
}
105+
106+
@Test
107+
void testNoTrailingSpaceInMultilineCommentShouldNotAddIssue() {
108+
CheckVerifier.newVerifier()
109+
.withCheck(new TrailingWhitespaceCheck())
110+
.onFile(
111+
new DelphiTestUnitBuilder()
112+
.appendImpl("{")
113+
.appendImpl(" there is no trailing whitespace in here")
114+
.appendImpl("}"))
115+
.verifyNoIssues();
116+
}
117+
118+
@Test
119+
void testTrailingSpaceInMultilineCommentShouldAddIssue() {
120+
CheckVerifier.newVerifier()
121+
.withCheck(new TrailingWhitespaceCheck())
122+
.onFile(
123+
new DelphiTestUnitBuilder()
124+
.appendImpl("// Noncompliant@+2")
125+
.appendImpl("{")
126+
.appendImpl(" hey, there's a trailing space in here! ")
127+
.appendImpl("}"))
128+
.verifyIssues();
129+
}
130+
131+
@Test
132+
void testTrailingTabInMultilineCommentShouldAddIssue() {
133+
CheckVerifier.newVerifier()
134+
.withCheck(new TrailingWhitespaceCheck())
135+
.onFile(
136+
new DelphiTestUnitBuilder()
137+
.appendImpl("// Noncompliant@+2")
138+
.appendImpl("{")
139+
.appendImpl(" hey, there's a trailing space in here!\t")
140+
.appendImpl("}"))
141+
.verifyIssues();
142+
}
74143
}

0 commit comments

Comments
 (0)