diff --git a/checkstyle.json b/checkstyle.json index f213ba54..9e53dd95 100644 --- a/checkstyle.json +++ b/checkstyle.json @@ -335,6 +335,19 @@ }, "type": "NestedTryDepth" }, + { + "props": { + "assignOpPolicy": "around", + "unaryOpPolicy": "none", + "arithmeticOpPolicy": "around", + "compareOpPolicy": "around", + "bitwiseOpPolicy": "around", + "boolOpPolicy": "around", + "intervalOpPolicy": "none", + "severity": "INFO" + }, + "type": "OperatorWhitespace" + }, { "props": { "tokens": [ diff --git a/resources/default-config.json b/resources/default-config.json index 939d44ce..8ff4136e 100644 --- a/resources/default-config.json +++ b/resources/default-config.json @@ -342,6 +342,19 @@ }, "type": "NullableParameter" }, + { + "props": { + "unaryOpPolicy": "none", + "boolOpPolicy": "around", + "intervalOpPolicy": "none", + "assignOpPolicy": "around", + "bitwiseOpPolicy": "around", + "arithmeticOpPolicy": "around", + "compareOpPolicy": "around", + "severity": "IGNORE" + }, + "type": "OperatorWhitespace" + }, { "props": { "tokens": [ diff --git a/src/checkstyle/Checker.hx b/src/checkstyle/Checker.hx index d131ce0f..1b8ca060 100644 --- a/src/checkstyle/Checker.hx +++ b/src/checkstyle/Checker.hx @@ -85,7 +85,7 @@ class Checker { function findLineSeparator() { var code = file.content; - for (i in 0 ... code.length) { + for (i in 0...code.length) { var char = code.charAt(i); if (char == "\r" || char == "\n") { lineSeparator = char; diff --git a/src/checkstyle/ChecksInfo.hx b/src/checkstyle/ChecksInfo.hx index 6344380d..e8144fdb 100644 --- a/src/checkstyle/ChecksInfo.hx +++ b/src/checkstyle/ChecksInfo.hx @@ -15,7 +15,7 @@ class ChecksInfo { for (cl in checksClasses) { if (ignoreClass(cl)) continue; var names:Array = getCheckNameFromClass(cl); - for (i in 0 ... names.length) { + for (i in 0...names.length) { var desc = getCheckDescription(cl); checkInfos[names[i]] = { name: names[i], diff --git a/src/checkstyle/checks/Check.hx b/src/checkstyle/checks/Check.hx index 93ad7309..cc27ff99 100644 --- a/src/checkstyle/checks/Check.hx +++ b/src/checkstyle/checks/Check.hx @@ -113,7 +113,7 @@ class Check { function isLineSuppressed(i:Int):Bool { var pos:Int = 0; - for (j in 0 ... i + 1) pos += checker.lines[j].length; + for (j in 0...i + 1) pos += checker.lines[j].length; return isCharPosSuppressed(pos); } diff --git a/src/checkstyle/checks/coding/DefaultComesLastCheck.hx b/src/checkstyle/checks/coding/DefaultComesLastCheck.hx index 358261e8..aeee79eb 100644 --- a/src/checkstyle/checks/coding/DefaultComesLastCheck.hx +++ b/src/checkstyle/checks/coding/DefaultComesLastCheck.hx @@ -21,7 +21,7 @@ class DefaultComesLastCheck extends Check { if (tokens[tokens.length - 1].is(Kwd(KwdDefault))) continue; var defaultExists = false; - for (i in 0 ... tokens.length) { + for (i in 0...tokens.length) { if (tokens[i].is(Kwd(KwdDefault)) && i < tokens.length - 1) { logPos("Default should be last label in the switch", token.pos); continue; diff --git a/src/checkstyle/checks/size/LineLengthCheck.hx b/src/checkstyle/checks/size/LineLengthCheck.hx index 12d9bb51..8b4d57a8 100644 --- a/src/checkstyle/checks/size/LineLengthCheck.hx +++ b/src/checkstyle/checks/size/LineLengthCheck.hx @@ -19,7 +19,7 @@ class LineLengthCheck extends Check { override function actualRun() { var ignoreRE = new EReg(ignorePattern, ""); - for (i in 0 ... checker.lines.length) { + for (i in 0...checker.lines.length) { var line = checker.lines[i]; if (line.length > max) { if (ignoreRE.match(line) || isLineSuppressed(i)) continue; diff --git a/src/checkstyle/checks/whitespace/EmptyLinesCheck.hx b/src/checkstyle/checks/whitespace/EmptyLinesCheck.hx index 03ab075b..36b558ce 100644 --- a/src/checkstyle/checks/whitespace/EmptyLinesCheck.hx +++ b/src/checkstyle/checks/whitespace/EmptyLinesCheck.hx @@ -35,7 +35,7 @@ class EmptyLinesCheck extends LineCheckBase { var start = 0; var end = 0; - for (i in 0 ... checker.lines.length) { + for (i in 0...checker.lines.length) { var line = checker.lines[i]; if (isMultineString(line)) continue; if (~/^\s*$/.match(line)) { diff --git a/src/checkstyle/checks/whitespace/IndentationCharacterCheck.hx b/src/checkstyle/checks/whitespace/IndentationCharacterCheck.hx index ded25cb4..f77a4ed8 100644 --- a/src/checkstyle/checks/whitespace/IndentationCharacterCheck.hx +++ b/src/checkstyle/checks/whitespace/IndentationCharacterCheck.hx @@ -16,7 +16,7 @@ class IndentationCharacterCheck extends LineCheckBase { override function actualRun() { var ignoreRE = new EReg(ignorePattern, ""); var re = (character == TAB) ? ~/^\t*(\S.*| \*.*)?$/ : ~/^ *(\S.*)?$/; - for (i in 0 ... checker.lines.length) { + for (i in 0...checker.lines.length) { var line = checker.lines[i]; if (ignoreRE.match(line) || isLineSuppressed(i)) continue; if (isMultineString(line)) continue; diff --git a/src/checkstyle/checks/whitespace/OperatorWhitespaceCheck.hx b/src/checkstyle/checks/whitespace/OperatorWhitespaceCheck.hx new file mode 100644 index 00000000..770ecc51 --- /dev/null +++ b/src/checkstyle/checks/whitespace/OperatorWhitespaceCheck.hx @@ -0,0 +1,232 @@ +package checkstyle.checks.whitespace; + +import checkstyle.Checker.LinePos; +import checkstyle.token.TokenTree; +import checkstyle.utils.TokenTreeCheckUtils; +import haxeparser.Data; +import haxe.macro.Expr; + +using checkstyle.utils.ArrayUtils; + +@name("OperatorWhitespace") +@desc("Checks that whitespace is present or absent around a operators.") +class OperatorWhitespaceCheck extends Check { + + // =, +=, -=, *=, /=, <<=, >>=, >>>=, &=, |=, ^= + public var assignOpPolicy:WhitespacePolicy; + // ++, --, ! + public var unaryOpPolicy:WhitespaceUnaryPolicy; + // +, -, *, /, % + public var arithmeticOpPolicy:WhitespacePolicy; + // ==, !=, <, <=, >, >= + public var compareOpPolicy:WhitespacePolicy; + // ~, &, |, ^, <<, >>, >>> + public var bitwiseOpPolicy:WhitespacePolicy; + // &&, || + public var boolOpPolicy:WhitespacePolicy; + // ... + public var intervalOpPolicy:WhitespacePolicy; + + public function new() { + super(TOKEN); + assignOpPolicy = AROUND; + unaryOpPolicy = NONE; + arithmeticOpPolicy = AROUND; + compareOpPolicy = AROUND; + bitwiseOpPolicy = AROUND; + boolOpPolicy = AROUND; + intervalOpPolicy = NONE; + + categories = [Category.STYLE, Category.CLARITY]; + } + + override function actualRun() { + var root:TokenTree = checker.getTokenTree(); + + checkAssignOps(root); + checkUnaryOps(root); + checkArithmeticOps(root); + checkCompareOps(root); + checkBitwiseOps(root); + checkBoolOps(root); + checkIntervalOps(root); + } + + function checkAssignOps(root:TokenTree) { + if ((assignOpPolicy == null) || (assignOpPolicy == IGNORE)) return; + var tokens:Array = root.filter([ + Binop(OpAssign), + Binop(OpAssignOp(OpAdd)), + Binop(OpAssignOp(OpSub)), + Binop(OpAssignOp(OpMult)), + Binop(OpAssignOp(OpDiv)), + Binop(OpAssignOp(OpMod)), + Binop(OpAssignOp(OpShl)), + Binop(OpAssignOp(OpShr)), + Binop(OpAssignOp(OpUShr)), + Binop(OpAssignOp(OpOr)), + Binop(OpAssignOp(OpAnd)), + Binop(OpAssignOp(OpXor)) + ], ALL); + + checkTokenList(tokens, assignOpPolicy); + } + + function checkUnaryOps(root:TokenTree) { + if ((unaryOpPolicy == null) || (unaryOpPolicy == IGNORE)) return; + var tokens:Array = root.filter([ + Unop(OpNot), + Unop(OpIncrement), + Unop(OpDecrement) + ], ALL); + + for (token in tokens) { + if (isPosSuppressed(token.pos)) continue; + checkUnaryWhitespace(token, unaryOpPolicy); + } + } + + function checkArithmeticOps(root:TokenTree) { + if ((arithmeticOpPolicy == null) || (arithmeticOpPolicy == IGNORE)) return; + var tokens:Array = root.filter([ + Binop(OpAdd), + Binop(OpSub), + Binop(OpMult), + Binop(OpDiv), + Binop(OpMod) + ], ALL); + checkTokenList(tokens, arithmeticOpPolicy); + } + + function checkCompareOps(root:TokenTree) { + if ((compareOpPolicy == null) || (compareOpPolicy == IGNORE)) return; + var tokens:Array = root.filter([ + Binop(OpGt), + Binop(OpLt), + Binop(OpGte), + Binop(OpLte), + Binop(OpEq), + Binop(OpNotEq) + ], ALL); + checkTokenList(tokens, compareOpPolicy); + } + + function checkBitwiseOps(root:TokenTree) { + if ((bitwiseOpPolicy == null) || (bitwiseOpPolicy == IGNORE)) return; + var tokens:Array = root.filter([ + Binop(OpAnd), + Binop(OpOr), + Binop(OpXor), + Binop(OpShl), + Binop(OpShr), + Binop(OpUShr) + ], ALL); + checkTokenList(tokens, bitwiseOpPolicy); + } + + function checkBoolOps(root:TokenTree) { + if ((boolOpPolicy == null) || (boolOpPolicy == IGNORE)) return; + var tokens:Array = root.filter([ + Binop(OpBoolAnd), + Binop(OpBoolOr) + ], ALL); + checkTokenList(tokens, boolOpPolicy); + } + + function checkIntervalOps(root:TokenTree) { + if ((intervalOpPolicy == null) || (intervalOpPolicy == IGNORE)) return; + var tokens:Array = root.filterCallback(function(token:TokenTree, depth:Int):FilterResult { + if (token.tok == null) return GO_DEEPER; + return switch (token.tok) { + case Binop(OpInterval): FOUND_SKIP_SUBTREE; + case IntInterval(_): FOUND_SKIP_SUBTREE; + default: GO_DEEPER; + } + }); + checkTokenList(tokens, intervalOpPolicy); + } + + function checkTokenList(tokens:Array, policy:WhitespacePolicy) { + for (token in tokens) { + if (isPosSuppressed(token.pos)) continue; + if (TokenTreeCheckUtils.isImportMult(token)) continue; + if (TokenTreeCheckUtils.isTypeParameter(token)) continue; + if (TokenTreeCheckUtils.filterOpSub(token)) continue; + checkWhitespace(token, policy); + } + } + + function checkWhitespace(tok:TokenTree, policy:WhitespacePolicy) { + var linePos:LinePos = checker.getLinePos(tok.pos.min); + var tokLen:Int = TokenDefPrinter.print(tok.tok).length; + if (tok.tok.match(IntInterval(_))) { + linePos = checker.getLinePos(tok.pos.max - 3); + tokLen = 3; + } + var line:String = checker.lines[linePos.line]; + var before:String = line.substr(0, linePos.ofs); + var after:String = line.substr(linePos.ofs + tokLen); + + var whitespaceBefore:Bool = ~/^(.*\s|)$/.match(before); + var whitespaceAfter:Bool = ~/^(\s.*|)$/.match(after); + + switch (policy) { + case BEFORE: + if (whitespaceBefore && !whitespaceAfter) return; + case AFTER: + if (!whitespaceBefore && whitespaceAfter) return; + case NONE: + if (!whitespaceBefore && !whitespaceAfter) return; + case AROUND: + if (whitespaceBefore && whitespaceAfter) return; + case IGNORE: + return; + default: + return; + } + logPos('OperatorWhitespace policy "$policy" violated by "${TokenDefPrinter.print(tok.tok)}"', tok.pos); + } + + function checkUnaryWhitespace(tok:TokenTree, policy:WhitespaceUnaryPolicy) { + var linePos:LinePos = checker.getLinePos(tok.pos.min); + var tokLen:Int = TokenDefPrinter.print(tok.tok).length; + var line:String = checker.lines[linePos.line]; + var before:String = line.substr(0, linePos.ofs); + var after:String = line.substr(linePos.ofs + tokLen); + + var whitespaceBefore:Bool = ~/^(.*\s|)$/.match(before); + var whitespaceAfter:Bool = ~/^(\s.*|)$/.match(after); + + var leftSide:Bool = TokenTreeCheckUtils.isUnaryLeftSided(tok); + + switch (policy) { + case INNER: + if (leftSide && whitespaceAfter) return; + if (!leftSide && whitespaceBefore) return; + case NONE: + if (leftSide && !whitespaceAfter) return; + if (!leftSide && !whitespaceBefore) return; + case IGNORE: + return; + default: + return; + } + logPos('OperatorWhitespace policy "$policy" violated by "${TokenDefPrinter.print(tok.tok)}"', tok.pos); + } +} + +@:enum +abstract WhitespacePolicy(String) { + var BEFORE = "before"; + var AFTER = "after"; + var AROUND = "around"; + var NONE = "none"; + var IGNORE = "ignore"; +} + +@:enum +abstract WhitespaceUnaryPolicy(String) { + var INNER = "inner"; + var NONE = "none"; + var IGNORE = "ignore"; +} \ No newline at end of file diff --git a/src/checkstyle/checks/whitespace/TabForAligningCheck.hx b/src/checkstyle/checks/whitespace/TabForAligningCheck.hx index 267482ed..55a14552 100644 --- a/src/checkstyle/checks/whitespace/TabForAligningCheck.hx +++ b/src/checkstyle/checks/whitespace/TabForAligningCheck.hx @@ -17,7 +17,7 @@ class TabForAligningCheck extends LineCheckBase { override function actualRun() { var ignoreRE = new EReg(ignorePattern, ""); var re = ~/^\s*\S[^\t]*\t/; - for (i in 0 ... checker.lines.length) { + for (i in 0...checker.lines.length) { var line = checker.lines[i]; if (ignoreRE.match(line)) continue; if (isMultineString(line)) continue; diff --git a/src/checkstyle/checks/whitespace/TrailingWhitespaceCheck.hx b/src/checkstyle/checks/whitespace/TrailingWhitespaceCheck.hx index eb6660e6..3de3682c 100644 --- a/src/checkstyle/checks/whitespace/TrailingWhitespaceCheck.hx +++ b/src/checkstyle/checks/whitespace/TrailingWhitespaceCheck.hx @@ -6,7 +6,7 @@ class TrailingWhitespaceCheck extends LineCheckBase { override function actualRun() { var re = ~/\s+$/; - for (i in 0 ... checker.lines.length) { + for (i in 0...checker.lines.length) { var line = checker.lines[i]; if (isMultineString(line)) continue; if (re.match(line)) log("Trailing whitespace", i + 1, line.length); diff --git a/src/checkstyle/utils/TokenTreeCheckUtils.hx b/src/checkstyle/utils/TokenTreeCheckUtils.hx index 6f5d082b..622b581c 100644 --- a/src/checkstyle/utils/TokenTreeCheckUtils.hx +++ b/src/checkstyle/utils/TokenTreeCheckUtils.hx @@ -56,4 +56,15 @@ class TokenTreeCheckUtils { default: false; } } + + public static function isUnaryLeftSided(tok:TokenTree):Bool { + var child:TokenTree = tok.getFirstChild(); + + if (child == null) return false; + return switch (child.tok) { + case Const(_): true; + case POpen: true; + default: false; + } + } } \ No newline at end of file diff --git a/test/TestMain.hx b/test/TestMain.hx index 320e5ccc..ee8b13d3 100644 --- a/test/TestMain.hx +++ b/test/TestMain.hx @@ -38,7 +38,7 @@ class TestMain { for (cls in classes) { var coverageData = [null]; var results:CoverageResult = cls.getResults(); - for (i in 1 ... results.l) coverageData[i] = 1; + for (i in 1...results.l) coverageData[i] = 1; var c = cls.name.replace(".", "/") + ".hx"; var missingStatements:Array = cls.getMissingStatements(); diff --git a/test/checks/whitespace/OperatorWhitespaceCheckTest.hx b/test/checks/whitespace/OperatorWhitespaceCheckTest.hx new file mode 100644 index 00000000..a46787d7 --- /dev/null +++ b/test/checks/whitespace/OperatorWhitespaceCheckTest.hx @@ -0,0 +1,368 @@ +package checks.whitespace; + +import checkstyle.checks.whitespace.OperatorWhitespaceCheck; + +class OperatorWhitespaceCheckTest extends CheckTestCase { + + static inline var MSG_EQUALS:String = 'OperatorWhitespace policy "around" violated by "="'; + static inline var MSG_EQUALS_BEFORE:String = 'OperatorWhitespace policy "before" violated by "="'; + static inline var MSG_EQUALS_AFTER:String = 'OperatorWhitespace policy "after" violated by "="'; + static inline var MSG_UNARY_NONE:String = 'OperatorWhitespace policy "none" violated by "++"'; + static inline var MSG_UNARY_INNER:String = 'OperatorWhitespace policy "inner" violated by "++"'; + static inline var MSG_INTERVAL_NONE:String = 'OperatorWhitespace policy "none" violated by "..."'; + static inline var MSG_INTERVAL_AROUND:String = 'OperatorWhitespace policy "around" violated by "..."'; + + public function testCorrectOperatorWhitespace() { + var check = new OperatorWhitespaceCheck(); + assertNoMsg(check, CORRECT_WHITESPACE_AROUND); + assertNoMsg(check, ISSUE_70); + assertNoMsg(check, ISSUE_71); + assertNoMsg(check, ISSUE_72); + assertNoMsg(check, ISSUE_77); + assertNoMsg(check, ISSUE_80); + assertNoMsg(check, ISSUE_81); + assertNoMsg(check, ISSUE_98); + assertNoMsg(check, MINUS_CONSTANT); + assertNoMsg(check, CONDITIONAL_STAR_IMPORT_ISSUE_160); + assertNoMsg(check, CONDITIONAL_ELSE_STAR_IMPORT); + assertNoMsg(check, CONDITIONAL_ELSEIF_STAR_IMPORT); + assertNoMsg(check, NEGATIVE_VARS); + assertNoMsg(check, NEGATIVE_NUMS); + assertNoMsg(check, OPGT); + } + + public function testIncorrectOperatorWhitespaceToken() { + var check = new OperatorWhitespaceCheck(); + assertMsg(check, ISSUE_59, MSG_EQUALS); + assertMsg(check, ISSUE_63, MSG_EQUALS); + assertMsg(check, NO_WHITESPACE_GT, MSG_EQUALS); + assertMsg(check, NO_WHITESPACE_OBJECT_DECL, MSG_EQUALS); + assertMsg(check, NO_WHITESPACE_TYPEDEF, MSG_EQUALS); + assertMsg(check, NO_WHITESPACE_VAR_INIT, MSG_EQUALS); + + assertNoMsg(check, CORRECT_WHITESPACE_AROUND); + } + + public function testWhitespaceBefore() { + var check = new OperatorWhitespaceCheck(); + check.assignOpPolicy = BEFORE; + assertNoMsg(check, ISSUE_63); + assertNoMsg(check, NO_WHITESPACE_TYPEDEF); + + assertMsg(check, CORRECT_WHITESPACE_AROUND, MSG_EQUALS_BEFORE); + assertMsg(check, ISSUE_59, MSG_EQUALS_BEFORE); + assertMsg(check, NO_WHITESPACE_GT, MSG_EQUALS_BEFORE); + assertMsg(check, NO_WHITESPACE_OBJECT_DECL, MSG_EQUALS_BEFORE); + assertMsg(check, NO_WHITESPACE_VAR_INIT, MSG_EQUALS_BEFORE); + } + + public function testWhitespaceAfter() { + var check = new OperatorWhitespaceCheck(); + check.assignOpPolicy = AFTER; + assertNoMsg(check, NO_WHITESPACE_GT); + + assertMsg(check, ISSUE_63, MSG_EQUALS_AFTER); + assertMsg(check, NO_WHITESPACE_TYPEDEF, MSG_EQUALS_AFTER); + assertMsg(check, CORRECT_WHITESPACE_AROUND, MSG_EQUALS_AFTER); + assertMsg(check, ISSUE_59, MSG_EQUALS_AFTER); + assertMsg(check, NO_WHITESPACE_OBJECT_DECL, MSG_EQUALS_AFTER); + assertMsg(check, NO_WHITESPACE_VAR_INIT, MSG_EQUALS_AFTER); + } + + public function testStarImport() { + var check = new OperatorWhitespaceCheck(); + assertNoMsg(check, ISSUE_70); + assertNoMsg(check, CONDITIONAL_STAR_IMPORT_ISSUE_160); + assertNoMsg(check, CONDITIONAL_ELSE_STAR_IMPORT); + assertNoMsg(check, CONDITIONAL_ELSEIF_STAR_IMPORT); + } + + public function testUnary() { + var check = new OperatorWhitespaceCheck(); + + assertNoMsg(check, UNARY_NO_WHITESPACE); + assertMsg(check, UNARY_INNER_WHITESPACE, MSG_UNARY_NONE); + + check.unaryOpPolicy = INNER; + assertMsg(check, UNARY_NO_WHITESPACE, MSG_UNARY_INNER); + assertNoMsg(check, UNARY_INNER_WHITESPACE); + } + + public function testInterval() { + var check = new OperatorWhitespaceCheck(); + + assertNoMsg(check, INTERVAL_NO_WHITESPACE); + assertMsg(check, INTERVAL_WHITESPACE, MSG_INTERVAL_NONE); + + check.intervalOpPolicy = AROUND; + assertMsg(check, INTERVAL_NO_WHITESPACE, MSG_INTERVAL_AROUND); + assertNoMsg(check, INTERVAL_WHITESPACE); + } + + public function testIgnore() { + var check = new OperatorWhitespaceCheck(); + check.assignOpPolicy = IGNORE; + check.unaryOpPolicy = IGNORE; + check.intervalOpPolicy = IGNORE; + + assertNoMsg(check, CORRECT_WHITESPACE_AROUND); + assertNoMsg(check, ISSUE_70); + assertNoMsg(check, ISSUE_71); + assertNoMsg(check, ISSUE_72); + assertNoMsg(check, ISSUE_77); + assertNoMsg(check, ISSUE_80); + assertNoMsg(check, ISSUE_81); + assertNoMsg(check, ISSUE_98); + assertNoMsg(check, MINUS_CONSTANT); + assertNoMsg(check, CONDITIONAL_STAR_IMPORT_ISSUE_160); + assertNoMsg(check, CONDITIONAL_ELSE_STAR_IMPORT); + assertNoMsg(check, CONDITIONAL_ELSEIF_STAR_IMPORT); + assertNoMsg(check, NEGATIVE_VARS); + assertNoMsg(check, NEGATIVE_NUMS); + assertNoMsg(check, OPGT); + assertNoMsg(check, ISSUE_59); + assertNoMsg(check, ISSUE_63); + assertNoMsg(check, NO_WHITESPACE_GT); + assertNoMsg(check, NO_WHITESPACE_OBJECT_DECL); + assertNoMsg(check, NO_WHITESPACE_TYPEDEF); + assertNoMsg(check, NO_WHITESPACE_VAR_INIT); + assertNoMsg(check, UNARY_NO_WHITESPACE); + assertNoMsg(check, UNARY_INNER_WHITESPACE); + assertNoMsg(check, INTERVAL_NO_WHITESPACE); + assertNoMsg(check, INTERVAL_WHITESPACE); + } +} + +@:enum +abstract OperatorWhitespaceCheckTests(String) to String { + var CORRECT_WHITESPACE_AROUND = " + import haxe.macro.*; + + class Test { + function test(param1:String, param2:String) { + var x = { x: 100, y: 100, + z: 20 * 10 + }; + var y:Array = []; + } + } + + typedef Test = { + x:Int, + y:Int, z:Int + } + + enum Test { + Monday; + Tuesday; + Wednesday; + Thursday; + Friday; Weekend(day:String); + }"; + + var NO_WHITESPACE_OBJECT_DECL = " + class Test { + function test(param1:String, param2:String) { + var x={ x: 100, y: 100,z: 20 }; + } + }"; + + var NO_WHITESPACE_TYPEDEF = " + typedef Test ={ + x:Int, + y:Int,z:Int + }"; + + var NO_WHITESPACE_VAR_INIT = " + class Test { + function test(param1:String, param2:String) { + var test:Array=[]; + } + }"; + + var NO_WHITESPACE_GT = " + class Test { + function test(param1:String, param2:String) { + var test:Array= []; + } + }"; + + var ISSUE_58 = " + class Test { + public function new() { + var x:Int, y:Int; + } + }"; + + var ISSUE_59 = " + typedef Test=Int + "; + + var ISSUE_63 = " + typedef Test =#if true Int #else String #end + "; + + var ISSUE_70 = " + import haxe.macro.*; + "; + + var ISSUE_71 = " + class Test { + function foo() { + trace((null : Array)); + } + }"; + + var ISSUE_72 = " + abstract Test(Array) {} + "; + + var ISSUE_77 = " + // comment + class Test // comment + { // comment + function foo() // comment + { // comment + switch ('Test') // comment + { // comment + } // comment + } // comment + } // comment + "; + + var ISSUE_80 = " + interface Test implements Dynamic {} + "; + + var ISSUE_81 = " + class Test { + function foo() { + do a++ while (true); + do ++a while (true); + } + }"; + + var ISSUE_98 = " + class Test { + // °öäüßÖÄÜ@łĸŋđđðſðæµ”“„¢«»Ø→↓←Ŧ¶€Ł}][{¬½¼³² + var test:Int = 0; + }"; + + var MINUS_CONSTANT = " + class Test { + function test() { + if (re.match(line) && line.indexOf('//') == -1) { + log('Tab after non-space character, Use space for aligning', i + 1, line.length, null, Reflect.field(SeverityLevel, severity)); + return -1; + } + a = 1 - -2; + b = 1.2 - -2.1; + return -1; + } + }"; + + var CONDITIONAL_STAR_IMPORT_ISSUE_160 = " + #if macro + import haxe.macro.*; + #end"; + + var CONDITIONAL_ELSEIF_STAR_IMPORT = " + #if macro + import haxe.macro.Type; + #elseif neko + import haxe.macro.*; + #elseif neko + import haxe.macro.*; + #else + #if linux + import haxe.macro.Type; + #else + import haxe.macro.*; + #end + #end + import haxe.macro.Type;"; + + var CONDITIONAL_ELSE_STAR_IMPORT = " + #if macro + import haxe.macro.Type; + #else + import haxe.macro.*; + #end + import haxe.macro.Type;"; + + var NEGATIVE_VARS = " + class Test { + function test() { + var rest = if (neg) { -noFractions; } + else { -noFractions; } + var rest = if (neg) -noFractions; + else -noFractions; + var x = neg ? -frag : -frag; + calc ([-width, -node.right, root], -node.left, {x : -x, y: -y}); + (-a); + (1 * -a); + do -a * 2 while(true); + for (a in [-1, -2]) -a + 2; + return -a; + } + }"; + + var NEGATIVE_NUMS = " + class Test { + function test() { + var rest = if (neg) { -8; } + else { -9; } + var rest = if (neg) -10; + else -11; + var x = neg ? -12 : -13; + calc ([-14, -node.right, root], -node.left, {x : -xi15x, y: -16}); + (-16); + (1 * -17); + do -18 * 2 while(true); + for (a in [-1, -2]) -18 + 2; + } + }"; + + var OPGT = " + class Test { + function test() { + if (a > b) return a >= b; + if (a >> b > c) return a >>= b; + if (a >>> b > c) return a >>>= b; + } + }"; + + var UNARY_NO_WHITESPACE = " + class Test { + function test() { + if (!test) return a++; + ++a; + return !(a++); + } + }"; + + var UNARY_INNER_WHITESPACE = " + class Test { + function test() { + if (! test) return a ++; + ++ a; + return ! (a ++); + } + }"; + + var INTERVAL_NO_WHITESPACE = " + class Test { + function test() { + for (i in 0...100) trace(i); + for (i in a...b) trace(i); + } + }"; + + var INTERVAL_WHITESPACE = " + class Test { + function test() { + for (i in 0 ... 100) trace(i); + for (i in a ... b) trace(i); + } + }"; +} \ No newline at end of file