Skip to content

Commit cba2183

Browse files
authored
Merge pull request #309 from seraku24/seraku24-fix-linecheckbase
Replace LineCheckBase line handling logic - Fixes #278
2 parents cff9b12 + c550e28 commit cba2183

File tree

7 files changed

+134
-32
lines changed

7 files changed

+134
-32
lines changed

src/checkstyle/Main.hx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,8 +286,9 @@ class Main {
286286
addAllChecks();
287287
var propsNotAllowed:Array<String> = [
288288
"moduleName", "severity", "type", "categories",
289-
"points", "desc", "quotesRE", "multilineStartRE",
290-
"escapeRE", "multilineStringStart"
289+
"points", "desc", "currentState", "skipOverStringStart",
290+
"commentStartRE", "commentBlockEndRE", "stringStartRE",
291+
"stringInterpolatedEndRE", "stringLiteralEndRE"
291292
];
292293
var config = getEmptyConfig();
293294
for (check in checker.checks) {

src/checkstyle/checks/whitespace/EmptyLinesCheck.hx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ class EmptyLinesCheck extends LineCheckBase {
3737

3838
for (i in 0...checker.lines.length) {
3939
var line = checker.lines[i];
40-
if (isMultineString(line)) continue;
40+
var ranges = getRanges(line);
41+
if (ranges.length == 1 && ranges[0].type != TEXT) continue;
42+
4143
if (~/^\s*$/.match(line)) {
4244
if (!inGroup) {
4345
inGroup = true;

src/checkstyle/checks/whitespace/IndentationCharacterCheck.hx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,13 @@ class IndentationCharacterCheck extends LineCheckBase {
2121
var re = (character == TAB) ? ~/^\t*(\S.*| \*.*)?$/ : ~/^ *(\S.*)?$/;
2222
for (i in 0...checker.lines.length) {
2323
var line = checker.lines[i];
24+
var ranges = getRanges(line);
25+
var startTextRange = ranges.filter(function(r):Bool return r.type == TEXT && r.start == 0)[0];
26+
if (startTextRange == null) continue;
27+
var startText = line.substring(startTextRange.start, startTextRange.end);
28+
2429
if (ignoreRE.match(line) || isLineSuppressed(i)) continue;
25-
if (isMultineString(line)) continue;
26-
if (line.length > 0 && !re.match(line)) log('Wrong indentation character (should be ${character})', i + 1, 0);
30+
if (!re.match(startText)) log('Wrong indentation character (should be ${character})', i + 1, 0);
2731
}
2832
}
2933
}

src/checkstyle/checks/whitespace/LineCheckBase.hx

Lines changed: 108 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,124 @@ package checkstyle.checks.whitespace;
33
@ignore("base class line based whitespace checks")
44
class LineCheckBase extends Check {
55

6-
var quotesRE:EReg;
7-
var multilineStartRE:EReg;
8-
var escapeRE:EReg;
9-
var multilineStringStart:Bool;
6+
var currentState:RangeType;
7+
var skipOverInitialQuote:Bool;
8+
9+
var commentStartRE:EReg;
10+
var commentBlockEndRE:EReg;
11+
var stringStartRE:EReg;
12+
var stringInterpolatedEndRE:EReg;
13+
var stringLiteralEndRE:EReg;
1014

1115
public function new() {
1216
super(LINE);
13-
quotesRE = ~/('|")/;
14-
multilineStartRE = null;
15-
escapeRE = null;
16-
multilineStringStart = false;
17+
18+
commentStartRE = ~/\/([\/*])/;
19+
commentBlockEndRE = ~/\*\//;
20+
stringStartRE = ~/['"]/;
21+
stringInterpolatedEndRE = ~/(?<!\\)'/;
22+
stringLiteralEndRE = ~/(?<!\\)"/;
1723
}
1824

1925
override public function run(checker:Checker):Array<CheckMessage> {
20-
multilineStringStart = false;
26+
currentState = TEXT;
27+
skipOverInitialQuote = false;
2128
return super.run(checker);
2229
}
2330

24-
function isMultineString(line:String):Bool {
25-
if (!multilineStringStart && quotesRE.match(line)) {
26-
var matched = quotesRE.matched(0);
27-
var matchedRight = quotesRE.matchedRight();
28-
multilineStartRE = new EReg(matched, "");
29-
escapeRE = new EReg("\\" + matched, "");
30-
multilineStringStart = !multilineStartRE.match(matchedRight) && !escapeRE.match(matchedRight);
31+
function getRanges(line:String):Array<Range> {
32+
var ranges = [];
33+
var currentStart = 0;
34+
while (currentStart < line.length) {
35+
currentStart = switch (currentState) {
36+
case TEXT: handleTextState(line, ranges, currentStart);
37+
case COMMENT(isBlock): handleCommentState(line, ranges, currentStart, isBlock);
38+
case STRING(isInterpolated): handleStringState(line, ranges, currentStart, isInterpolated);
39+
};
40+
}
41+
if (line.length == 0) ranges.push({ type: currentState, start: 0, end: 0 });
42+
return ranges;
43+
}
44+
45+
function handleTextState(line:String, ranges:Array<Range>, currentStart:Int):Int {
46+
var foundCommentStart = commentStartRE.matchSub(line, currentStart);
47+
var commentStart = foundCommentStart ? commentStartRE.matchedPos().pos : line.length;
48+
var foundStringStart = stringStartRE.matchSub(line, currentStart);
49+
var stringStart = foundStringStart ? stringStartRE.matchedPos().pos : line.length;
50+
51+
if (foundCommentStart && commentStart < stringStart) {
52+
if (commentStart > currentStart) {
53+
ranges.push({ type: currentState, start: currentStart, end: commentStart });
54+
}
55+
56+
currentState = COMMENT(commentStartRE.matched(1) == "*");
57+
return commentStart;
58+
}
59+
else if (foundStringStart && stringStart < commentStart) {
60+
if (stringStart > currentStart) {
61+
ranges.push({ type: currentState, start: currentStart, end: stringStart });
62+
}
63+
64+
skipOverInitialQuote = true;
65+
currentState = STRING(stringStartRE.matched(0) == "'");
66+
return stringStart;
67+
}
68+
else {
69+
ranges.push({ type: currentState, start: currentStart, end: line.length });
70+
71+
return line.length;
72+
}
73+
}
74+
75+
function handleCommentState(line:String, ranges:Array<Range>, currentStart:Int, isBlock:Bool):Int {
76+
if (isBlock && commentBlockEndRE.matchSub(line, currentStart)) {
77+
var commentEnd = commentBlockEndRE.matchedPos().pos + 2;
78+
ranges.push({ type: currentState, start: currentStart, end: commentEnd });
79+
80+
currentState = TEXT;
81+
return commentEnd;
82+
}
83+
else {
84+
ranges.push({ type: currentState, start: currentStart, end: line.length });
85+
86+
if (!isBlock) currentState = TEXT;
87+
return line.length;
88+
}
89+
}
90+
91+
function handleStringState(line:String, ranges:Array<Range>, currentStart:Int, isInterpolated:Bool):Int {
92+
var adjustedStart = currentStart + (skipOverInitialQuote ? 1 : 0);
93+
skipOverInitialQuote = false;
94+
if (isInterpolated && stringInterpolatedEndRE.matchSub(line, adjustedStart)) {
95+
var stringEnd = stringInterpolatedEndRE.matchedPos().pos + 1;
96+
ranges.push({ type: currentState, start: currentStart, end: stringEnd });
97+
98+
currentState = TEXT;
99+
return stringEnd;
100+
}
101+
else if (!isInterpolated && stringLiteralEndRE.matchSub(line, adjustedStart)) {
102+
var stringEnd = stringLiteralEndRE.matchedPos().pos + 1;
103+
ranges.push({ type: currentState, start: currentStart, end: stringEnd });
104+
105+
currentState = TEXT;
106+
return stringEnd;
31107
}
32-
else if (multilineStringStart && multilineStartRE != null && multilineStartRE.match(line) && !escapeRE.match(line)) {
33-
multilineStringStart = false;
34-
multilineStartRE = null;
35-
escapeRE = null;
108+
else {
109+
ranges.push({ type: currentState, start: currentStart, end: line.length });
110+
111+
return line.length;
36112
}
37-
return multilineStringStart;
38113
}
114+
}
115+
116+
enum RangeType {
117+
TEXT;
118+
COMMENT(isBlock:Bool);
119+
STRING(isInterpolated:Bool);
120+
}
121+
122+
typedef Range = {
123+
var type:RangeType;
124+
var start:Int;
125+
var end:Int;
39126
}

src/checkstyle/checks/whitespace/TabForAligningCheck.hx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,17 @@ class TabForAligningCheck extends LineCheckBase {
1717

1818
override function actualRun() {
1919
var ignoreRE = new EReg(ignorePattern, "");
20-
var re = ~/^\s*\S[^\t]*\t/;
2120
for (i in 0...checker.lines.length) {
2221
var line = checker.lines[i];
22+
var ranges = getRanges(line);
23+
2324
if (ignoreRE.match(line)) continue;
24-
if (isMultineString(line)) continue;
25-
if (re.match(line)) log("Tab after non-space character, use space for aligning", i + 1, line.length);
25+
26+
for (range in ranges.filter(function(r):Bool return r.type == TEXT)) {
27+
var re = range.start == 0 ? ~/\S[ ]*\t/ : ~/\t/;
28+
var rangeText = line.substring(range.start, range.end);
29+
if (re.match(rangeText)) log("Tab after non-space character, use space for aligning", i + 1, line.length);
30+
}
2631
}
2732
}
2833
}

src/checkstyle/checks/whitespace/TrailingWhitespaceCheck.hx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,12 @@ class TrailingWhitespaceCheck extends LineCheckBase {
1515
var re = ~/\s+$/;
1616
for (i in 0...checker.lines.length) {
1717
var line = checker.lines[i];
18-
if (isMultineString(line)) continue;
19-
if (re.match(line)) log("Trailing whitespace", i + 1, line.length);
18+
var ranges = getRanges(line);
19+
var endTextRange = ranges.filter(function(r):Bool return r.type == TEXT && r.end == line.length)[0];
20+
if (endTextRange == null) continue;
21+
var endText = line.substring(endTextRange.start, endTextRange.end);
22+
23+
if (re.match(endText)) log("Trailing whitespace", i + 1, line.length);
2024
}
2125
}
2226
}

test/checks/whitespace/SpacingCheckTest.hx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ abstract SpacingCheckTests(String) to String {
103103
}
104104
}";
105105

106-
107106
var TEST2 =
108107
"class Test {
109108
public function test() {

0 commit comments

Comments
 (0)