Skip to content

Commit 145865e

Browse files
authored
added conditionalPolicy (#411)
* added conditionalPolicy * fixed NPE in C++ after parser failures
1 parent 26f3e3b commit 145865e

File tree

7 files changed

+141
-24
lines changed

7 files changed

+141
-24
lines changed

CHANGES.md

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,27 @@
11
## dev branch / next version (2.x.x)
22
- New `extendsConfigPath` field to config files fixes [#401](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/401) ([#407](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/407) + [#408](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/408))
33
- New experimental command line option `-detect <filename>` to generate a checkstyle configuration file based on a source folder [#409](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/409) + [#410](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/410)
4+
- Added `conditionalPolicy` to Indentation check [#411](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/411)
45
- Fixed sort order of detected checkstyle configuration [#410](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/410)
6+
- Fixed null pointer exception when parsing fails on C++ [#411](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/411)
7+
- Improved detection rate for `RightCurlyCheck` [#411](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/411)
58
- Refactored indentation check messages [#409](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/409)
69

710
## version 2.2.2
811

912
- Fixed handling of default setters/getters in indentation check [#391](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/391)
10-
- Fixed token tree structure for Sharp(If) inside Kwd(KwdCase) [#394](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/394)
13+
- Fixed token tree structure for `Sharp(If)` inside `Kwd(KwdCase)` [#394](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/394)
1114
- Fixed comments in function parameters [#395](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/395)
1215
- Fixed parser errors when handling block and object declarations, fixes [#396](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/396) ([#397](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/397))
13-
- Fixed BkOpen childs in token tree parser [#398](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/398)
16+
- Fixed `BkOpen` childs in token tree parser [#398](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/398)
1417
- Fixed bad offset crash with C++ build on Windows 10 [#398](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/398)
1518
- Fixed object declaration handling [#399](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/399)
1619
- Fixed false positives for files with UTF-8 characters when running as vscode-checkstyle [#402](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/402)
1720
- Fixed comments in typedefs [#404](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/404) + [#405](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/405)
18-
- Refactored content handling to use Bytes instead of String (should fix [#98](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/98)) [#402](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/402)
19-
- Added unittests for ParserQueue and CheckerPool [#393](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/393)
21+
- Refactored content handling to use `Bytes` instead of `String` (should fix [#98](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/98)) [#402](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/402)
22+
- Added unittests for `ParserQueue` and `CheckerPool` [#393](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/393)
2023
- Added unittests for TokenTree structure verification [#400](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/400)
21-
- Removed `.` from default settings in SeparatorWrapCheck [#400](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/400)
24+
- Removed `.` from default settings in `SeparatorWrapCheck` [#400](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/400)
2225
- Improved wrapped code detection [#392](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/392) + [#403](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/403)
2326

2427
## version 2.2.1
@@ -27,7 +30,7 @@
2730
- New CHANGES.md
2831
- Added a reset function for checks ([#279](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/279))
2932
- Added unittest for [#78](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/78)
30-
- Fixed XMLReporter output after introducing multithreading in 2.2.0 [#389](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/389)
33+
- Fixed `XMLReporter` output after introducing multithreading in 2.2.0 [#389](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/389)
3134
- Updated formula for number of pre-parsed files [#386](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/386)
3235
- Removed conditional section for unittest [#181](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/181)
3336

@@ -39,7 +42,7 @@
3942
* use `-nothreads` to turn off threads and use old behaviour
4043
* use `numberOfCheckerThreads` in config file to set number of checker threads (see `resources/default-conmfig.json`)
4144
- Fixed allow same regex logic for "all" excludes, fixes [#361](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/361) ([#362](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/362))
42-
- Fixed altering position info in RightCurlyCheck ([#367](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/367))
45+
- Fixed altering position info in `RightCurlyCheck` ([#367](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/367))
4346
- Fixed multiple metadatas infront of statement ([#369](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/369))
4447
- Fixed C++ compilation ([#376](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/376))
4548
- Fixed coverage ([#378](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/378))

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ haxelib install checkstyle
4444
haxelib run checkstyle -s src
4545
```
4646

47+
### Automatic detection of your coding style (experimental)
48+
49+
```
50+
haxelib run checkstyle -s src -detect detectedCheckstyle.json
51+
```
52+
4753
### Reference
4854

4955
[More information and reference](http://haxecheckstyle.github.io/docs).

resources/default-config.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@
140140
"character": "tab",
141141
"wrapPolicy": "larger",
142142
"ignoreComments": true,
143-
"ignoreConditionals": false
143+
"ignoreConditionals": false,
144+
"conditionalPolicy": "aligned"
144145
},
145146
"type": "Indentation"
146147
},

src/checkstyle/Checker.hx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,9 @@ class Checker {
124124
}
125125

126126
function makeASTs() {
127-
asts = [makeAST(baseDefines)];
127+
asts = [];
128+
var res = makeAST(baseDefines);
129+
if (res != null) asts.push(res);
128130
for (combination in defineCombinations) {
129131
var res = makeAST(combination.concat(baseDefines));
130132
if (res != null) asts.push(res);
@@ -195,6 +197,7 @@ class Checker {
195197
makePosIndices();
196198
makeTokens();
197199
makeASTs();
200+
if (asts.length <= 0) return false;
198201
getTokenTree();
199202
}
200203
catch (e:Any) {

src/checkstyle/checks/block/RightCurlyCheck.hx

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,10 +162,39 @@ class RightCurlyCheck extends Check {
162162

163163
override public function detectableInstances():DetectableInstances {
164164
return [{
165-
fixed: [],
165+
fixed: [{
166+
propertyName: "tokens",
167+
value: [
168+
CLASS_DEF,
169+
ENUM_DEF,
170+
ABSTRACT_DEF,
171+
TYPEDEF_DEF,
172+
INTERFACE_DEF,
173+
OBJECT_DECL,
174+
FUNCTION,
175+
FOR,
176+
IF,
177+
WHILE,
178+
SWITCH,
179+
TRY,
180+
CATCH
181+
]
182+
}],
166183
properties: [{
167184
propertyName: "option",
168-
values: [SAME, ALONE, ALONE_OR_SINGLELINE]
185+
values: [ALONE_OR_SINGLELINE, ALONE, SAME]
186+
}]
187+
},
188+
{
189+
fixed: [{
190+
propertyName: "tokens",
191+
value: [
192+
OBJECT_DECL
193+
]
194+
}],
195+
properties: [{
196+
propertyName: "option",
197+
values: [ALONE_OR_SINGLELINE, ALONE, SAME]
169198
}]
170199
}];
171200
}

src/checkstyle/checks/whitespace/IndentationCheck.hx

Lines changed: 62 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ class IndentationCheck extends Check {
66

77
public var character:IndentationCheckCharacter;
88
public var ignoreConditionals:Bool;
9+
public var conditionalPolicy:ConditionalIndentationPolicy;
910
public var ignoreComments:Bool;
1011
public var wrapPolicy:WrappedIndentationPolicy;
1112

@@ -15,6 +16,7 @@ class IndentationCheck extends Check {
1516
ignoreConditionals = false;
1617
ignoreComments = true;
1718
wrapPolicy = LARGER;
19+
conditionalPolicy = ALIGNED;
1820
categories = [Category.STYLE, Category.CLARITY];
1921
}
2022

@@ -23,6 +25,9 @@ class IndentationCheck extends Check {
2325
var wrappedStatements:Array<Bool> = calcWrapStatements();
2426
var tolerateViolations:Array<Bool> = calcIgnoreLineIndentation();
2527

28+
var ignoreCond:Bool = ignoreConditionals;
29+
if (conditionalPolicy == IGNORE) ignoreCond = true;
30+
2631
correctWrappedIndentation(lineIndentation, wrappedStatements);
2732

2833
var splitChar:String = character;
@@ -34,7 +39,7 @@ class IndentationCheck extends Check {
3439
// skip empty lines
3540
if (~/^\s*$/.match(line)) continue;
3641
// skip conditionals
37-
if (ignoreConditionals && ~/^\s*#/.match(line)) continue;
42+
if (ignoreCond && ~/^\s*#/.match(line)) continue;
3843

3944
var e = ~/^(\s*)/;
4045
e.match(line);
@@ -87,17 +92,6 @@ class IndentationCheck extends Check {
8792
lineIndentation[i]++;
8893
}
8994
}
90-
var currentIndent:Int = 0;
91-
for (i in 0...lineIndentation.length) {
92-
var newIndent = lineIndentation[i];
93-
if (newIndent == currentIndent) continue;
94-
if (newIndent > currentIndent) {
95-
currentIndent++;
96-
lineIndentation[i] = currentIndent;
97-
continue;
98-
}
99-
currentIndent = newIndent;
100-
}
10195
}
10296

10397
function calcLineIndentation():Array<Int> {
@@ -106,6 +100,11 @@ class IndentationCheck extends Check {
106100
var searchFor:Array<TokenDef> = [
107101
BrOpen,
108102
BkOpen,
103+
Sharp("if"),
104+
Sharp("else"),
105+
Sharp("elseif"),
106+
Sharp("end"),
107+
Sharp("error"),
109108
Kwd(KwdIf),
110109
Kwd(KwdElse),
111110
Kwd(KwdFor),
@@ -138,6 +137,8 @@ class IndentationCheck extends Check {
138137
// getter/setter 'default' has no childs
139138
if (child == null) continue;
140139
increaseRangeIndent(child.getPos(), lineIndentation);
140+
case Sharp(_):
141+
calcLineIndentationSharp(token, lineIndentation);
141142
default:
142143
}
143144
}
@@ -161,6 +162,39 @@ class IndentationCheck extends Check {
161162
}
162163
}
163164

165+
function calcLineIndentationSharp(token:TokenTree, lineIndentation:Array<Int>) {
166+
167+
var linePos:LinePos = checker.getLinePos(token.pos.min);
168+
var line:String = checker.lines[linePos.line];
169+
var prefix:String = line.substr(0, linePos.ofs + 1);
170+
var isFirst:Bool = ~/^\s*#$/.match(prefix);
171+
172+
switch (conditionalPolicy) {
173+
case IGNORE: return;
174+
case FIXED_ZERO:
175+
if (!isFirst) return;
176+
lineIndentation[linePos.line] = 0;
177+
return;
178+
case ALIGNED: return;
179+
case ALIGNED_INCREASE:
180+
}
181+
182+
switch (token.tok) {
183+
case Sharp("if"), Sharp("else"), Sharp("elseif"):
184+
for (child in token.children) {
185+
switch (child.tok) {
186+
case Sharp(_):
187+
increaseIndentBetween(token, child, lineIndentation);
188+
return;
189+
default:
190+
}
191+
}
192+
case Sharp("end"):
193+
case Sharp("error"):
194+
default:
195+
}
196+
}
197+
164198
function calcLineIndentationLoops(token:TokenTree, lineIndentation:Array<Int>) {
165199
switch (token.tok) {
166200
case Kwd(KwdFor):
@@ -242,7 +276,10 @@ class IndentationCheck extends Check {
242276
}
243277

244278
function increaseBlockIndent(blockStart:TokenTree, lineIndentation:Array<Int>) {
245-
var blockEnd:TokenTree = blockStart.getLastChild();
279+
increaseIndentBetween(blockStart, blockStart.getLastChild(), lineIndentation);
280+
}
281+
282+
function increaseIndentBetween(blockStart:TokenTree, blockEnd:TokenTree, lineIndentation:Array<Int>) {
246283
var start:Int = checker.getLinePos(blockStart.pos.min).line + 1;
247284
var end:Int = checker.getLinePos(blockEnd.pos.min).line;
248285
increaseIndent(lineIndentation, start, end);
@@ -289,6 +326,10 @@ class IndentationCheck extends Check {
289326
ONE_SPACE
290327
]
291328
},
329+
{
330+
propertyName: "conditionalPolicy",
331+
values: [FIXED_ZERO, ALIGNED, ALIGNED_INCREASE, IGNORE]
332+
},
292333
{
293334
propertyName: "ignoreConditionals",
294335
values: [true, false]
@@ -312,6 +353,14 @@ abstract WrappedIndentationPolicy(String) {
312353
var LARGER = "larger";
313354
}
314355

356+
@:enum
357+
abstract ConditionalIndentationPolicy(String) {
358+
var IGNORE = "ignore";
359+
var FIXED_ZERO = "fixed_zero";
360+
var ALIGNED = "aligned";
361+
var ALIGNED_INCREASE = "aligned_increase";
362+
}
363+
315364
@:enum
316365
abstract IndentationCheckCharacter(String) to String {
317366
var TAB = "tab";

test/checks/whitespace/IndentationCheckTest.hx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,24 @@ class IndentationCheckTest extends CheckTestCase<IndentationCheckTests> {
3131
check.ignoreConditionals = true;
3232
assertNoMsg(check, WRONG_CONDITIONAL);
3333
assertNoMsg(check, CORRECT_TAB_INDENT);
34+
check.ignoreConditionals = false;
35+
36+
check.conditionalPolicy = IGNORE;
37+
assertNoMsg(check, WRONG_CONDITIONAL);
38+
assertNoMsg(check, CORRECT_TAB_INDENT);
39+
40+
check.conditionalPolicy = FIXED_ZERO;
41+
assertNoMsg(check, WRONG_CONDITIONAL);
42+
assertMsg(check, CORRECT_TAB_INDENT, 'Indentation mismatch: expected: no indentation, actual: "\\t\\t\\t"[3]');
43+
44+
check.conditionalPolicy = ALIGNED;
45+
assertMsg(check, WRONG_CONDITIONAL, 'Indentation mismatch: expected: "\\t"[1], actual: no indentation');
46+
assertNoMsg(check, CORRECT_TAB_INDENT);
47+
48+
check.conditionalPolicy = ALIGNED_INCREASE;
49+
assertMsg(check, WRONG_CONDITIONAL, 'Indentation mismatch: expected: "\\t"[1], actual: no indentation');
50+
assertNoMsg(check, CONDITIONAL_INCREASE);
51+
assertMsg(check, CORRECT_TAB_INDENT, 'Indentation mismatch: expected: "\\t\\t\\t\\t\\t"[5], actual: "\\t\\t\\t\\t"[4]');
3452
}
3553

3654
@Test
@@ -208,6 +226,14 @@ class Test {
208226
public function new() {}
209227
}";
210228

229+
var CONDITIONAL_INCREASE = "
230+
class Test {
231+
#if php
232+
var a:Int;
233+
#end
234+
public function new() {}
235+
}";
236+
211237
var LARGER_WRAPPED_PARAMS = "
212238
class Test {
213239
public function new(param1:Int,

0 commit comments

Comments
 (0)