From 81c5eadd06453c939c3d26bd8eee701e596ec9bd Mon Sep 17 00:00:00 2001 From: AlexHaxe Date: Mon, 7 May 2018 10:16:58 +0200 Subject: [PATCH 1/2] added conditionalPolicy fixed NPE in C++ after parser failures --- CHANGES.md | 17 +++-- README.md | 6 ++ resources/default-config.json | 3 +- src/checkstyle/Checker.hx | 5 +- .../checks/block/RightCurlyCheck.hx | 33 +++++++- .../checks/whitespace/IndentationCheck.hx | 75 +++++++++++++++---- .../checks/whitespace/IndentationCheckTest.hx | 26 +++++++ 7 files changed, 141 insertions(+), 24 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 457bced4..5ab5da1b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,24 +1,27 @@ ## dev branch / next version (2.x.x) - 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)) - New experimental command line option `-detect ` 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) +- Added `conditionalPolicy` to Indentation check - Fixed sort order of detected checkstyle configuration [#410](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/410) +- Fixed null pointer exception when parsing fails on C++ +- Improved detection rate for `RightCurlyCheck` - Refactored indentation check messages [#409](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/409) ## version 2.2.2 - Fixed handling of default setters/getters in indentation check [#391](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/391) -- Fixed token tree structure for Sharp(If) inside Kwd(KwdCase) [#394](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/394) +- Fixed token tree structure for `Sharp(If)` inside `Kwd(KwdCase)` [#394](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/394) - Fixed comments in function parameters [#395](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/395) - 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)) -- Fixed BkOpen childs in token tree parser [#398](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/398) +- Fixed `BkOpen` childs in token tree parser [#398](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/398) - Fixed bad offset crash with C++ build on Windows 10 [#398](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/398) - Fixed object declaration handling [#399](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/399) - Fixed false positives for files with UTF-8 characters when running as vscode-checkstyle [#402](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/402) - Fixed comments in typedefs [#404](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/404) + [#405](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/405) -- 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) -- Added unittests for ParserQueue and CheckerPool [#393](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/393) +- 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) +- Added unittests for `ParserQueue` and `CheckerPool` [#393](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/393) - Added unittests for TokenTree structure verification [#400](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/400) -- Removed `.` from default settings in SeparatorWrapCheck [#400](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/400) +- Removed `.` from default settings in `SeparatorWrapCheck` [#400](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/400) - Improved wrapped code detection [#392](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/392) + [#403](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/403) ## version 2.2.1 @@ -27,7 +30,7 @@ - New CHANGES.md - Added a reset function for checks ([#279](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/279)) - Added unittest for [#78](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/78) -- Fixed XMLReporter output after introducing multithreading in 2.2.0 [#389](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/389) +- Fixed `XMLReporter` output after introducing multithreading in 2.2.0 [#389](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/389) - Updated formula for number of pre-parsed files [#386](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/386) - Removed conditional section for unittest [#181](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/181) @@ -39,7 +42,7 @@ * use `-nothreads` to turn off threads and use old behaviour * use `numberOfCheckerThreads` in config file to set number of checker threads (see `resources/default-conmfig.json`) - 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)) -- Fixed altering position info in RightCurlyCheck ([#367](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/367)) +- Fixed altering position info in `RightCurlyCheck` ([#367](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/367)) - Fixed multiple metadatas infront of statement ([#369](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/369)) - Fixed C++ compilation ([#376](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/376)) - Fixed coverage ([#378](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/378)) diff --git a/README.md b/README.md index b52e150b..d6c9083e 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,12 @@ haxelib install checkstyle haxelib run checkstyle -s src ``` +### Automatic detection of your coding style (experimental) + +``` +haxelib run checkstyle -s src -detect detectedCheckstyle.json +``` + ### Reference [More information and reference](http://haxecheckstyle.github.io/docs). diff --git a/resources/default-config.json b/resources/default-config.json index 70f0ce38..6c5aa923 100644 --- a/resources/default-config.json +++ b/resources/default-config.json @@ -140,7 +140,8 @@ "character": "tab", "wrapPolicy": "larger", "ignoreComments": true, - "ignoreConditionals": false + "ignoreConditionals": false, + "conditionalPolicy": "aligned" }, "type": "Indentation" }, diff --git a/src/checkstyle/Checker.hx b/src/checkstyle/Checker.hx index 1b63aea7..61d55547 100644 --- a/src/checkstyle/Checker.hx +++ b/src/checkstyle/Checker.hx @@ -124,7 +124,9 @@ class Checker { } function makeASTs() { - asts = [makeAST(baseDefines)]; + asts = []; + var res = makeAST(baseDefines); + if (res != null) asts.push(res); for (combination in defineCombinations) { var res = makeAST(combination.concat(baseDefines)); if (res != null) asts.push(res); @@ -195,6 +197,7 @@ class Checker { makePosIndices(); makeTokens(); makeASTs(); + if (asts.length <= 0) return false; getTokenTree(); } catch (e:Any) { diff --git a/src/checkstyle/checks/block/RightCurlyCheck.hx b/src/checkstyle/checks/block/RightCurlyCheck.hx index 37addb30..59f7ae4a 100644 --- a/src/checkstyle/checks/block/RightCurlyCheck.hx +++ b/src/checkstyle/checks/block/RightCurlyCheck.hx @@ -162,10 +162,39 @@ class RightCurlyCheck extends Check { override public function detectableInstances():DetectableInstances { return [{ - fixed: [], + fixed: [{ + propertyName: "tokens", + value: [ + CLASS_DEF, + ENUM_DEF, + ABSTRACT_DEF, + TYPEDEF_DEF, + INTERFACE_DEF, + OBJECT_DECL, + FUNCTION, + FOR, + IF, + WHILE, + SWITCH, + TRY, + CATCH + ] + }], properties: [{ propertyName: "option", - values: [SAME, ALONE, ALONE_OR_SINGLELINE] + values: [ALONE_OR_SINGLELINE, ALONE, SAME] + }] + }, + { + fixed: [{ + propertyName: "tokens", + value: [ + OBJECT_DECL + ] + }], + properties: [{ + propertyName: "option", + values: [ALONE_OR_SINGLELINE, ALONE, SAME] }] }]; } diff --git a/src/checkstyle/checks/whitespace/IndentationCheck.hx b/src/checkstyle/checks/whitespace/IndentationCheck.hx index fadcf6ed..14325565 100644 --- a/src/checkstyle/checks/whitespace/IndentationCheck.hx +++ b/src/checkstyle/checks/whitespace/IndentationCheck.hx @@ -6,6 +6,7 @@ class IndentationCheck extends Check { public var character:IndentationCheckCharacter; public var ignoreConditionals:Bool; + public var conditionalPolicy:ConditionalIndentationPolicy; public var ignoreComments:Bool; public var wrapPolicy:WrappedIndentationPolicy; @@ -15,6 +16,7 @@ class IndentationCheck extends Check { ignoreConditionals = false; ignoreComments = true; wrapPolicy = LARGER; + conditionalPolicy = ALIGNED; categories = [Category.STYLE, Category.CLARITY]; } @@ -23,6 +25,9 @@ class IndentationCheck extends Check { var wrappedStatements:Array = calcWrapStatements(); var tolerateViolations:Array = calcIgnoreLineIndentation(); + var ignoreCond:Bool = ignoreConditionals; + if (conditionalPolicy == IGNORE) ignoreCond = true; + correctWrappedIndentation(lineIndentation, wrappedStatements); var splitChar:String = character; @@ -34,7 +39,7 @@ class IndentationCheck extends Check { // skip empty lines if (~/^\s*$/.match(line)) continue; // skip conditionals - if (ignoreConditionals && ~/^\s*#/.match(line)) continue; + if (ignoreCond && ~/^\s*#/.match(line)) continue; var e = ~/^(\s*)/; e.match(line); @@ -87,17 +92,6 @@ class IndentationCheck extends Check { lineIndentation[i]++; } } - var currentIndent:Int = 0; - for (i in 0...lineIndentation.length) { - var newIndent = lineIndentation[i]; - if (newIndent == currentIndent) continue; - if (newIndent > currentIndent) { - currentIndent++; - lineIndentation[i] = currentIndent; - continue; - } - currentIndent = newIndent; - } } function calcLineIndentation():Array { @@ -106,6 +100,11 @@ class IndentationCheck extends Check { var searchFor:Array = [ BrOpen, BkOpen, + Sharp("if"), + Sharp("else"), + Sharp("elseif"), + Sharp("end"), + Sharp("error"), Kwd(KwdIf), Kwd(KwdElse), Kwd(KwdFor), @@ -138,6 +137,8 @@ class IndentationCheck extends Check { // getter/setter 'default' has no childs if (child == null) continue; increaseRangeIndent(child.getPos(), lineIndentation); + case Sharp(_): + calcLineIndentationSharp(token, lineIndentation); default: } } @@ -161,6 +162,39 @@ class IndentationCheck extends Check { } } + function calcLineIndentationSharp(token:TokenTree, lineIndentation:Array) { + + var linePos:LinePos = checker.getLinePos(token.pos.min); + var line:String = checker.lines[linePos.line]; + var prefix:String = line.substr(0, linePos.ofs + 1); + var isFirst:Bool = ~/^\s*#$/.match(prefix); + + switch (conditionalPolicy) { + case IGNORE: return; + case FIXED_ZERO: + if (!isFirst) return; + lineIndentation[linePos.line] = 0; + return; + case ALIGNED: return; + case ALIGNED_INCREASE: + } + + switch (token.tok) { + case Sharp("if"), Sharp("else"), Sharp("elseif"): + for (child in token.children) { + switch (child.tok) { + case Sharp(_): + increaseIndentBetween(token, child, lineIndentation); + return; + default: + } + } + case Sharp("end"): + case Sharp("error"): + default: + } + } + function calcLineIndentationLoops(token:TokenTree, lineIndentation:Array) { switch (token.tok) { case Kwd(KwdFor): @@ -242,7 +276,10 @@ class IndentationCheck extends Check { } function increaseBlockIndent(blockStart:TokenTree, lineIndentation:Array) { - var blockEnd:TokenTree = blockStart.getLastChild(); + increaseIndentBetween(blockStart, blockStart.getLastChild(), lineIndentation); + } + + function increaseIndentBetween(blockStart:TokenTree, blockEnd:TokenTree, lineIndentation:Array) { var start:Int = checker.getLinePos(blockStart.pos.min).line + 1; var end:Int = checker.getLinePos(blockEnd.pos.min).line; increaseIndent(lineIndentation, start, end); @@ -289,6 +326,10 @@ class IndentationCheck extends Check { ONE_SPACE ] }, + { + propertyName: "conditionalPolicy", + values: [FIXED_ZERO, ALIGNED, ALIGNED_INCREASE, IGNORE] + }, { propertyName: "ignoreConditionals", values: [true, false] @@ -312,6 +353,14 @@ abstract WrappedIndentationPolicy(String) { var LARGER = "larger"; } +@:enum +abstract ConditionalIndentationPolicy(String) { + var IGNORE = "ignore"; + var FIXED_ZERO = "fixed_zero"; + var ALIGNED = "aligned"; + var ALIGNED_INCREASE = "aligned_increase"; +} + @:enum abstract IndentationCheckCharacter(String) to String { var TAB = "tab"; diff --git a/test/checks/whitespace/IndentationCheckTest.hx b/test/checks/whitespace/IndentationCheckTest.hx index 51b68d5b..38c4b669 100644 --- a/test/checks/whitespace/IndentationCheckTest.hx +++ b/test/checks/whitespace/IndentationCheckTest.hx @@ -31,6 +31,24 @@ class IndentationCheckTest extends CheckTestCase { check.ignoreConditionals = true; assertNoMsg(check, WRONG_CONDITIONAL); assertNoMsg(check, CORRECT_TAB_INDENT); + check.ignoreConditionals = false; + + check.conditionalPolicy = IGNORE; + assertNoMsg(check, WRONG_CONDITIONAL); + assertNoMsg(check, CORRECT_TAB_INDENT); + + check.conditionalPolicy = FIXED_ZERO; + assertNoMsg(check, WRONG_CONDITIONAL); + assertMsg(check, CORRECT_TAB_INDENT, 'Indentation mismatch: expected: no indentation, actual: "\\t\\t\\t"[3]'); + + check.conditionalPolicy = ALIGNED; + assertMsg(check, WRONG_CONDITIONAL, 'Indentation mismatch: expected: "\\t"[1], actual: no indentation'); + assertNoMsg(check, CORRECT_TAB_INDENT); + + check.conditionalPolicy = ALIGNED_INCREASE; + assertMsg(check, WRONG_CONDITIONAL, 'Indentation mismatch: expected: "\\t"[1], actual: no indentation'); + assertNoMsg(check, CONDITIONAL_INCREASE); + assertMsg(check, CORRECT_TAB_INDENT, 'Indentation mismatch: expected: "\\t\\t\\t\\t\\t"[5], actual: "\\t\\t\\t\\t"[4]'); } @Test @@ -208,6 +226,14 @@ class Test { public function new() {} }"; + var CONDITIONAL_INCREASE = " +class Test { + #if php + var a:Int; + #end + public function new() {} +}"; + var LARGER_WRAPPED_PARAMS = " class Test { public function new(param1:Int, From 9c4afb299bb4ca601bd1b5d3383f96e97bfbf034 Mon Sep 17 00:00:00 2001 From: AlexHaxe Date: Mon, 7 May 2018 10:20:17 +0200 Subject: [PATCH 2/2] updated CHANGES.md --- CHANGES.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 5ab5da1b..fe0d0887 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,10 +1,10 @@ ## dev branch / next version (2.x.x) - 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)) - New experimental command line option `-detect ` 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) -- Added `conditionalPolicy` to Indentation check +- Added `conditionalPolicy` to Indentation check [#411](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/411) - Fixed sort order of detected checkstyle configuration [#410](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/410) -- Fixed null pointer exception when parsing fails on C++ -- Improved detection rate for `RightCurlyCheck` +- Fixed null pointer exception when parsing fails on C++ [#411](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/411) +- Improved detection rate for `RightCurlyCheck` [#411](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/411) - Refactored indentation check messages [#409](https://github.com/HaxeCheckstyle/haxe-checkstyle/issues/409) ## version 2.2.2