diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ac88a6b..df00f2a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## dev branch / next version (1.x.x) +## version 1.7.0 (2019-05-16) + - Added `wrapping.multiVar`, fixes [#355](https://github.com/HaxeCheckstyle/haxe-formatter/issues/355), fixes [#430](https://github.com/HaxeCheckstyle/haxe-formatter/issues/430) ([#422](https://github.com/HaxeCheckstyle/haxe-formatter/issues/422) + [#434](https://github.com/HaxeCheckstyle/haxe-formatter/issues/434)) - Added `emptylines.afterFieldsWithDocComments`, fixes [#385](https://github.com/HaxeCheckstyle/haxe-formatter/issues/385), fixes [#432](https://github.com/HaxeCheckstyle/haxe-formatter/issues/432) ([#425](https://github.com/HaxeCheckstyle/haxe-formatter/issues/425) + [#434](https://github.com/HaxeCheckstyle/haxe-formatter/issues/434)) - Added `lineEnds.anonTypeCurly`, `lineEnds.blockCurly`, `lineEnds.objectLiteralCurly`, `lineEnds.typedefCurly`, fixes [#346](https://github.com/HaxeCheckstyle/haxe-formatter/issues/346) ([#427](https://github.com/HaxeCheckstyle/haxe-formatter/issues/427) + [#434](https://github.com/HaxeCheckstyle/haxe-formatter/issues/434) + [#456](https://github.com/HaxeCheckstyle/haxe-formatter/issues/456)) @@ -9,6 +11,7 @@ - Added Java compilation and tests on TravisCI ([#456](https://github.com/HaxeCheckstyle/haxe-formatter/issues/456)) - Added browser JS compilation, fixes [#449](https://github.com/HaxeCheckstyle/haxe-formatter/issues/449) ([#456](https://github.com/HaxeCheckstyle/haxe-formatter/issues/456)) - Added cache for close tokens `]`, `)` and `}` ([#461](https://github.com/HaxeCheckstyle/haxe-formatter/issues/461)) +- Added `indentation.indentComplexValueExpressions`, fixes [#468](https://github.com/HaxeCheckstyle/haxe-formatter/issues/468) ([#469](https://github.com/HaxeCheckstyle/haxe-formatter/issues/469)) - Fixed missing empty lines in classes with conditionals, fixes [#419](https://github.com/HaxeCheckstyle/haxe-formatter/issues/419) ([#422](https://github.com/HaxeCheckstyle/haxe-formatter/issues/422)) - Fixed wrapping of concatenated strings ([#422](https://github.com/HaxeCheckstyle/haxe-formatter/issues/422) - Fixed ECheckType detection with cast, fixes [#374](https://github.com/HaxeCheckstyle/haxe-formatter/issues/374) ([#422](https://github.com/HaxeCheckstyle/haxe-formatter/issues/422)) diff --git a/haxelib.json b/haxelib.json index a429c5c3..97a3c705 100644 --- a/haxelib.json +++ b/haxelib.json @@ -8,8 +8,8 @@ "style" ], "description": "A code formatter for Haxe", - "version": "1.6.0", - "releasenote": "New --stdin CLI parameter and bugfixes - see CHANGELOG for details.", + "version": "1.7.0", + "releasenote": "Added wrapping for matrixes and multiple var declarations; added more curly line end options; bugfixes - see CHANGELOG for details.", "contributors": [ "AlexHaxe", "Gama11" diff --git a/package.json b/package.json index d9e5cc08..05bffc76 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "haxe-formatter", - "version": "1.6.0", + "version": "1.7.0", "description": "A code formatter for Haxe", "repository": { "type": "git", diff --git a/resources/default-hxformat.json b/resources/default-hxformat.json index 96b688fe..b5a4612b 100644 --- a/resources/default-hxformat.json +++ b/resources/default-hxformat.json @@ -111,6 +111,7 @@ "indentation": { "character": "tab", "conditionalPolicy": "aligned", + "indentComplexValueExpressions": false, "indentObjectLiteral": true, "tabWidth": 4, "trailingWhitespace": false diff --git a/resources/hxformat-schema.json b/resources/hxformat-schema.json index f844c65d..9bd0876d 100644 --- a/resources/hxformat-schema.json +++ b/resources/hxformat-schema.json @@ -1004,6 +1004,11 @@ "description": "adds trailing whitespace to empty lines by copying indentation from preceeding line", "type": "boolean", "default": false + }, + "indentComplexValueExpressions": { + "description": "indent complex value expressions: (true)\t\t\t\t\t\t(false) var a = if (true)\t\t\tvar a = if (true) 10;\t\t\t\t\t\t10; else\t\t\t\t\telse 20;\t\t\tvs.\t\t\t20; return if (true)\t\t\treturn if (true) 10;\t\t\t\t\t\t10; else\t\t\t\t\telse 20;\t\t\t\t\t\t20;", + "type": "boolean", + "default": false } }, "type": "object" diff --git a/src/formatter/config/IndentationConfig.hx b/src/formatter/config/IndentationConfig.hx index 19ee74c1..26bb34b9 100644 --- a/src/formatter/config/IndentationConfig.hx +++ b/src/formatter/config/IndentationConfig.hx @@ -26,6 +26,20 @@ typedef IndentationConfig = { @:default(false) @:optional var trailingWhitespace:Bool; @:default(true) @:optional var indentObjectLiteral:Bool; + + /** + indent complex value expressions: + (true) (false) + var a = if (true) var a = if (true) + 10; 10; + else else + 20; vs. 20; + return if (true) return if (true) + 10; 10; + else else + 20; 20; + **/ + @:default(false) @:optional var indentComplexValueExpressions:Bool; } @:enum diff --git a/src/formatter/marker/Indenter.hx b/src/formatter/marker/Indenter.hx index 8b22a2f3..7e281b5b 100644 --- a/src/formatter/marker/Indenter.hx +++ b/src/formatter/marker/Indenter.hx @@ -178,7 +178,7 @@ class Indenter { return token; } - function countLineBreaks(indentingTokensCandidates:Array):Int { + function countLineBreaks(indentingTokensCandidates:Array, indentComplexValueExpressions:Bool):Int { var count:Int = 0; var prevToken:Null = null; var currentToken:Null = null; @@ -199,23 +199,32 @@ class Indenter { if (prevToken.index == currentToken.index) { continue; } - if (parsedCode.tokenList.isSameLineBetween(currentToken, prevToken, false)) { - var elseTok:Null = prevToken.access().firstOf(Kwd(KwdElse)).token; - if (elseTok != null) { - if (parsedCode.tokenList.isSameLineBetween(prevToken, elseTok, false)) { - continue; + switch (currentToken.tok) { + case Binop(OpAssign): + if (indentComplexValueExpressions) { + mustIndent = true; } - mustIndent = true; - } - var brOpen:Null = prevToken.access().firstOf(BrOpen).token; - if (brOpen != null) { - var type:BrOpenType = TokenTreeCheckUtils.getBrOpenType(brOpen); - switch (type) { - case BLOCK: - continue; - default: + default: + if (parsedCode.tokenList.isSameLineBetween(currentToken, prevToken, false)) { + var elseTok:Null = prevToken.access().firstOf(Kwd(KwdElse)).token; + if (elseTok != null) { + if (parsedCode.tokenList.isSameLineBetween(prevToken, elseTok, false)) { + continue; + } + if (indentComplexValueExpressions) { + mustIndent = true; + } + } + var brOpen:Null = prevToken.access().firstOf(BrOpen).token; + if (brOpen != null) { + var type:BrOpenType = TokenTreeCheckUtils.getBrOpenType(brOpen); + switch (type) { + case BLOCK: + continue; + default: + } + } } - } } case Kwd(KwdElse): @@ -230,6 +239,10 @@ class Indenter { } case Kwd(KwdSwitch): switch (currentToken.tok) { + case Binop(op): + if (indentComplexValueExpressions) { + mustIndent = true; + } case POpen: var type:POpenType = TokenTreeCheckUtils.getPOpenType(currentToken); switch (type) { @@ -342,6 +355,27 @@ class Indenter { return count; } + function isFieldLevelVar(indentingTokensCandidates:Array):Bool { + var tokens:Array = indentingTokensCandidates.copy(); + tokens.reverse(); + for (token in tokens) { + switch (token.tok) { + case Kwd(KwdFunction): + return false; + case Kwd(KwdVar): + return true; + case Const(CIdent(MarkEmptyLines.FINAL)): + #if (haxe_ver >= 4.0) + case Kwd(KwdFinal): + #end + case Binop(OpAssign): + return true; + default: + } + } + return false; + } + function calcFromCandidates(token:TokenTree):Int { var indentingTokensCandidates:Array = findIndentingCandidates(token); #if debugIndent @@ -350,7 +384,16 @@ class Indenter { if (indentingTokensCandidates.length <= 0) { return 0; } - var count:Int = countLineBreaks(indentingTokensCandidates); + + var indentComplexValueExpressions:Bool = config.indentComplexValueExpressions; + if (isFieldLevelVar(indentingTokensCandidates)) { + indentComplexValueExpressions = true; + } + if (indentComplexValueExpressions) { + indentingTokensCandidates = compressElseIfCandidates(indentingTokensCandidates); + } + + var count:Int = countLineBreaks(indentingTokensCandidates, indentComplexValueExpressions); if (hasConditional(indentingTokensCandidates)) { switch (config.conditionalPolicy) { case AlignedDecrease: @@ -407,7 +450,10 @@ class Indenter { } } } + return indentingTokensCandidates; + } + function compressElseIfCandidates(indentingTokensCandidates:Array):Array { var compressedCandidates:Array = []; var state:IndentationCompressElseIf = Copy; for (token in indentingTokensCandidates) { diff --git a/test/TestSuite.hx b/test/TestSuite.hx index 5359dbc6..368eb0ca 100644 --- a/test/TestSuite.hx +++ b/test/TestSuite.hx @@ -1,5 +1,6 @@ import formatter.FormatStatsTest; import testcases.EmptyLinesTestCases; +import testcases.ExpressionLevelTestCases; import testcases.IndentationTestCases; import testcases.LineEndsTestCases; import testcases.MissingTestCases; @@ -19,6 +20,7 @@ class TestSuite extends massive.munit.TestSuite { } add(EmptyLinesTestCases); + add(ExpressionLevelTestCases); add(IndentationTestCases); add(LineEndsTestCases); add(MissingTestCases); diff --git a/test/testcases/indentation/issue_220_object_literal_if_else_chain.hxtest b/test/testcases/indentation/issue_220_object_literal_if_else_chain.hxtest index 982a983f..3428d52c 100644 --- a/test/testcases/indentation/issue_220_object_literal_if_else_chain.hxtest +++ b/test/testcases/indentation/issue_220_object_literal_if_else_chain.hxtest @@ -40,21 +40,21 @@ class Main { class Main { function loop(min, max) { return if (mid == min) - {line: mid, pos: pos - start + 1}; - else if (start > pos) - loop(min, mid); + {line: mid, pos: pos - start + 1}; + else if (start > pos) + loop(min, mid); return if (mid == min) - {line: mid, pos: pos - start + 1}; - else - loop(min, mid); + {line: mid, pos: pos - start + 1}; + else + loop(min, mid); return if (mid == min) - {line: mid, pos: pos - start + 1}; - else if (start > pos) - loop(min, mid); - else - loop(mid, max); + {line: mid, pos: pos - start + 1}; + else if (start > pos) + loop(min, mid); + else + loop(mid, max); return if (mid == min) { {line: mid, pos: pos - start + 1}; diff --git a/test/testcases/indentation/issue_304_expression_if_indentation_keep.hxtest b/test/testcases/indentation/issue_304_expression_if_indentation_keep.hxtest index a0785b1c..2a6ec05a 100644 --- a/test/testcases/indentation/issue_304_expression_if_indentation_keep.hxtest +++ b/test/testcases/indentation/issue_304_expression_if_indentation_keep.hxtest @@ -64,46 +64,46 @@ class Main { return if (true) 10; else 20; var a = if (true) 10; - else 20; + else 20; var a = if (true) 10 - else 20; + else 20; return if (true) 10 - else 20; + else 20; return if (true) 10; - else 20; + else 20; var a = if (true) - 10; - else - 20; + 10; + else + 20; var a = if (true) - 10 - else - 20; + 10 + else + 20; return if (true) - 10 - else - 20; + 10 + else + 20; return if (true) - 10; - else - 20; + 10; + else + 20; var a = if (true) - 10; - else - 20; + 10; + else + 20; var a = if (true) - 10 - else - 20; + 10 + else + 20; return if (true) - 10 - else - 20; + 10 + else + 20; return if (true) - 10; - else - 20; + 10; + else + 20; } } diff --git a/test/testcases/indentation/issue_304_expression_if_indentation_keep_indent_assignment_expr.hxtest b/test/testcases/indentation/issue_304_expression_if_indentation_keep_indent_assignment_expr.hxtest new file mode 100644 index 00000000..0cbce7bb --- /dev/null +++ b/test/testcases/indentation/issue_304_expression_if_indentation_keep_indent_assignment_expr.hxtest @@ -0,0 +1,112 @@ +{ + "indentation": { + "indentComplexValueExpressions": true + }, + "sameLine": { + "expressionIf": "keep" + } +} + +--- + +class Main { + public function new (){ + var a = if (true) 10; else 20; + var a = if (true) 10 else 20; + return if (true) 10 else 20; + return if (true) 10; else 20; + + var a = if (true) 10; + else 20; + var a = if (true) 10 + else 20; + return if (true) 10 + else 20; + return if (true) 10; + else 20; + + var a = if (true) + 10; + else 20; + var a = if (true) + 10 + else 20; + return if (true) + 10 + else 20; + return if (true) + 10; + else 20; + + var a = if (true) + 10; + else + 20; + var a = if (true) + 10 + else + 20; + return if (true) + 10 + else + 20; + return if (true) + 10; + else + 20; + } +} + +--- + +class Main { + public function new() { + var a = if (true) 10; else 20; + var a = if (true) 10 else 20; + return if (true) 10 else 20; + return if (true) 10; else 20; + + var a = if (true) 10; + else 20; + var a = if (true) 10 + else 20; + return if (true) 10 + else 20; + return if (true) 10; + else 20; + + var a = if (true) + 10; + else + 20; + var a = if (true) + 10 + else + 20; + return if (true) + 10 + else + 20; + return if (true) + 10; + else + 20; + + var a = if (true) + 10; + else + 20; + var a = if (true) + 10 + else + 20; + return if (true) + 10 + else + 20; + return if (true) + 10; + else + 20; + } +} diff --git a/test/testcases/indentation/issue_304_expression_if_indentation_next.hxtest b/test/testcases/indentation/issue_304_expression_if_indentation_next.hxtest index 463ca7a9..d56aa10d 100644 --- a/test/testcases/indentation/issue_304_expression_if_indentation_next.hxtest +++ b/test/testcases/indentation/issue_304_expression_if_indentation_next.hxtest @@ -59,71 +59,71 @@ class Main { class Main { public function new() { var a = if (true) - 10; - else - 20; + 10; + else + 20; var a = if (true) - 10 - else - 20; + 10 + else + 20; return if (true) - 10 - else - 20; + 10 + else + 20; return if (true) - 10; - else - 20; + 10; + else + 20; var a = if (true) - 10; - else - 20; + 10; + else + 20; var a = if (true) - 10 - else - 20; + 10 + else + 20; return if (true) - 10 - else - 20; + 10 + else + 20; return if (true) - 10; - else - 20; + 10; + else + 20; var a = if (true) - 10; - else - 20; + 10; + else + 20; var a = if (true) - 10 - else - 20; + 10 + else + 20; return if (true) - 10 - else - 20; + 10 + else + 20; return if (true) - 10; - else - 20; + 10; + else + 20; var a = if (true) - 10; - else - 20; + 10; + else + 20; var a = if (true) - 10 - else - 20; + 10 + else + 20; return if (true) - 10 - else - 20; + 10 + else + 20; return if (true) - 10; - else - 20; + 10; + else + 20; } } diff --git a/test/testcases/indentation/issue_304_expression_if_indentation_next_indent_assignment_expr.hxtest b/test/testcases/indentation/issue_304_expression_if_indentation_next_indent_assignment_expr.hxtest new file mode 100644 index 00000000..84d2fc9f --- /dev/null +++ b/test/testcases/indentation/issue_304_expression_if_indentation_next_indent_assignment_expr.hxtest @@ -0,0 +1,132 @@ +{ + "indentation": { + "indentComplexValueExpressions": true + }, + "sameLine": { + "expressionIf": "next" + } +} + +--- + +class Main { + public function new (){ + var a = if (true) 10; else 20; + var a = if (true) 10 else 20; + return if (true) 10 else 20; + return if (true) 10; else 20; + + var a = if (true) 10; + else 20; + var a = if (true) 10 + else 20; + return if (true) 10 + else 20; + return if (true) 10; + else 20; + + var a = if (true) + 10; + else 20; + var a = if (true) + 10 + else 20; + return if (true) + 10 + else 20; + return if (true) + 10; + else 20; + + var a = if (true) + 10; + else + 20; + var a = if (true) + 10 + else + 20; + return if (true) + 10 + else + 20; + return if (true) + 10; + else + 20; + } +} + +--- + +class Main { + public function new() { + var a = if (true) + 10; + else + 20; + var a = if (true) + 10 + else + 20; + return if (true) + 10 + else + 20; + return if (true) + 10; + else + 20; + + var a = if (true) + 10; + else + 20; + var a = if (true) + 10 + else + 20; + return if (true) + 10 + else + 20; + return if (true) + 10; + else + 20; + + var a = if (true) + 10; + else + 20; + var a = if (true) + 10 + else + 20; + return if (true) + 10 + else + 20; + return if (true) + 10; + else + 20; + + var a = if (true) + 10; + else + 20; + var a = if (true) + 10 + else + 20; + return if (true) + 10 + else + 20; + return if (true) + 10; + else + 20; + } +} diff --git a/test/testcases/indentation/issue_304_expression_if_indentation_same.hxtest b/test/testcases/indentation/issue_304_expression_if_indentation_same.hxtest index 2cc549d2..4ac045cc 100644 --- a/test/testcases/indentation/issue_304_expression_if_indentation_same.hxtest +++ b/test/testcases/indentation/issue_304_expression_if_indentation_same.hxtest @@ -69,37 +69,37 @@ class Main { return if (true) 10; else 20; var a = if (true) - 10; - else - 20; + 10; + else + 20; var a = if (true) - 10 - else - 20; + 10 + else + 20; return if (true) - 10 - else - 20; + 10 + else + 20; return if (true) - 10; - else - 20; + 10; + else + 20; var a = if (true) - 10; - else - 20; + 10; + else + 20; var a = if (true) - 10 - else - 20; + 10 + else + 20; return if (true) - 10 - else - 20; + 10 + else + 20; return if (true) - 10; - else - 20; + 10; + else + 20; } } diff --git a/test/testcases/indentation/issue_304_expression_if_indentation_same_indent_assignment_expr.hxtest b/test/testcases/indentation/issue_304_expression_if_indentation_same_indent_assignment_expr.hxtest new file mode 100644 index 00000000..662cb75c --- /dev/null +++ b/test/testcases/indentation/issue_304_expression_if_indentation_same_indent_assignment_expr.hxtest @@ -0,0 +1,108 @@ +{ + "indentation": { + "indentComplexValueExpressions": true + }, + "sameLine": { + "expressionIf": "same" + } +} + +--- + +class Main { + public function new (){ + var a = if (true) 10; else 20; + var a = if (true) 10 else 20; + return if (true) 10 else 20; + return if (true) 10; else 20; + + var a = if (true) 10; + else 20; + var a = if (true) 10 + else 20; + return if (true) 10 + else 20; + return if (true) 10; + else 20; + + var a = if (true) + 10; + else 20; + var a = if (true) + 10 + else 20; + return if (true) + 10 + else 20; + return if (true) + 10; + else 20; + + var a = if (true) + 10; + else + 20; + var a = if (true) + 10 + else + 20; + return if (true) + 10 + else + 20; + return if (true) + 10; + else + 20; + } +} + +--- + +class Main { + public function new() { + var a = if (true) 10; else 20; + var a = if (true) 10 else 20; + return if (true) 10 else 20; + return if (true) 10; else 20; + + var a = if (true) 10; else 20; + var a = if (true) 10 else 20; + return if (true) 10 else 20; + return if (true) 10; else 20; + + var a = if (true) + 10; + else + 20; + var a = if (true) + 10 + else + 20; + return if (true) + 10 + else + 20; + return if (true) + 10; + else + 20; + + var a = if (true) + 10; + else + 20; + var a = if (true) + 10 + else + 20; + return if (true) + 10 + else + 20; + return if (true) + 10; + else + 20; + } +} diff --git a/test/testcases/indentation/issue_334_complex_var_assignment_indent_value_expr.hxtest b/test/testcases/indentation/issue_334_complex_var_assignment_indent_value_expr.hxtest new file mode 100644 index 00000000..c06cc774 --- /dev/null +++ b/test/testcases/indentation/issue_334_complex_var_assignment_indent_value_expr.hxtest @@ -0,0 +1,24 @@ +{ + "indentation": { + "indentComplexValueExpressions": true + } +} + +--- + +class Main { + static var _mul:Int32->Int32->Int32 = untyped + if (Math.imul != null) + Math.imul + else + function(a:Int32, b:Int32):Int32 return clamp((a : Int) * ((b : Int) & 0xFFFF) + clamp((a : Int) * ((b : Int) >>> 16) << 16)); +} + +--- + +class Main { + static var _mul:Int32->Int32->Int32 = untyped if (Math.imul != null) + Math.imul + else + function(a:Int32, b:Int32):Int32 return clamp((a : Int) * ((b : Int) & 0xFFFF) + clamp((a : Int) * ((b : Int) >>> 16) << 16)); +} diff --git a/test/testcases/indentation/issue_468_return_if_else.hxtest b/test/testcases/indentation/issue_468_return_if_else.hxtest new file mode 100644 index 00000000..fc98ca80 --- /dev/null +++ b/test/testcases/indentation/issue_468_return_if_else.hxtest @@ -0,0 +1,30 @@ +{ +} + +--- + +class Main { + static function main() { + return if (foo) { + foo; + } else if (bar) { + bar; + } else { + foobar; + } + } +} + +--- + +class Main { + static function main() { + return if (foo) { + foo; + } else if (bar) { + bar; + } else { + foobar; + } + } +} diff --git a/test/testcases/lineends/expression_if_indent_assignment_expr.hxtest b/test/testcases/lineends/expression_if_indent_assignment_expr.hxtest new file mode 100644 index 00000000..18914831 --- /dev/null +++ b/test/testcases/lineends/expression_if_indent_assignment_expr.hxtest @@ -0,0 +1,58 @@ +{ + "indentation": { + "indentComplexValueExpressions": true + }, + "lineEnds": { + "leftCurly": "both", + "rightCurly": "both" + }, + "sameLine": { + "ifBody": "same", + "ifElse": "next", + "doWhile": "next", + "tryBody": "next", + "tryCatch": "next" + } +} + +--- + +class Main +{ + public function new() + { + fun.expr = if (fun.ret == null || switch (fun.ret) + { + case TPath (p): true; + default: false; + }) + { + macro throw "abstract method, must override"; + } + else + { + macro return throw "abstract method, must override"; + } + } +} + +--- + +class Main +{ + public function new() + { + fun.expr = if (fun.ret == null || switch (fun.ret) + { + case TPath(p): true; + default: false; + }) + { + macro throw "abstract method, must override"; + } + else + { + macro return throw "abstract method, must override"; + } + } +} diff --git a/test/testcases/lineends/issue_329_else_body_with_popen.hxtest b/test/testcases/lineends/issue_329_else_body_with_popen.hxtest index 1e1b1480..c69f4048 100644 --- a/test/testcases/lineends/issue_329_else_body_with_popen.hxtest +++ b/test/testcases/lineends/issue_329_else_body_with_popen.hxtest @@ -18,10 +18,10 @@ class Main { class Main { function getRevBits(n) { return if (n == 0) - 0 - else if (getBit()) - (1 << (n - 1)) | getRevBits(n - 1) - else - getRevBits(n - 1); + 0 + else if (getBit()) + (1 << (n - 1)) | getRevBits(n - 1) + else + getRevBits(n - 1); } } diff --git a/test/testcases/lineends/issue_329_else_body_with_popen_indent_value_expr.hxtest b/test/testcases/lineends/issue_329_else_body_with_popen_indent_value_expr.hxtest new file mode 100644 index 00000000..62e2db09 --- /dev/null +++ b/test/testcases/lineends/issue_329_else_body_with_popen_indent_value_expr.hxtest @@ -0,0 +1,31 @@ + { + "indentation": { + "indentComplexValueExpressions": true + } + } + +--- + +class Main { + function getRevBits(n) { + return if (n == 0) + 0 + else if (getBit()) + (1 << (n - 1)) | getRevBits(n - 1) + else + getRevBits(n - 1); + } +} + +--- + +class Main { + function getRevBits(n) { + return if (n == 0) + 0 + else if (getBit()) + (1 << (n - 1)) | getRevBits(n - 1) + else + getRevBits(n - 1); + } +} diff --git a/test/testcases/other/issue_261_multiline_string_interpolation_indent_assignment_expr.hxtest b/test/testcases/other/issue_261_multiline_string_interpolation_indent_assignment_expr.hxtest new file mode 100644 index 00000000..fc9285e5 --- /dev/null +++ b/test/testcases/other/issue_261_multiline_string_interpolation_indent_assignment_expr.hxtest @@ -0,0 +1,325 @@ +{ + "indentation": { + "indentComplexValueExpressions": true + } +} + +--- + +package memberapplet.feature.chat; + +import memberapplet.feature.chat.ChatRoom; +import memberapplet.feature.chat.translation.*; +import memberapplet.feature.chat.smileys.*; +import coconut.Ui.hxx; +import com.utils.UrlUtil; + +using com.utils.SignalUtil; +using com.utils.ObservableUtil; + +private typedef InputPolicy = { + @:optional var restrict(default, never):InputRestriction; + var maxChars(default, never):Int; +} + +private abstract InputRestriction(Null) from EReg { + + public inline function apply(to:String):String + return if (this == null) to else this.replace(to, ''); + + @:from static function ofString(s:String):InputRestriction + return new EReg('[^$s]', 'ig'); +} + +class Chat implements plumbum.Scope implements IChat +{ + var dependencies:{ + + var connectionStatus:Observable; + + var performerNick:Value;//TODO: this shouldn't be here I think ... it duplicates data from the chat room ... instead the chat room should have offline and connecting statuses and there should always be one defined to hold the performer's nick + var isFullscreen:Value; + var isRecommenderEnabled:Value; + var isPrivateInProgress:Value;//TODO: this shouldn't be here for the same reasons as performerNick + var isVipShowInProgress:Value;//TODO: this shouldn't be here for the same reasons as performerNick + + var upgrades:UserUpgrades; + + var imagePath:String; + var smileys:Value>; + + var storage:{ + var language(default, never):State; + var collapsed(default, never):State; + var height(default, never):State; + var fontSize(default, never):State; + } + + var inputPolicies:{ + var guest(default, never):InputPolicy; + var freeChat(default, never):InputPolicy; + var privateShow(default, never):InputPolicy; + } + + }; + + var model:ChatModel = new ChatModel( + tink.Anon.merge( + storage, + dependencies, + restrictInput = restrictInput, + allSmileys = smileys + ) + ); + + function restrictInput(input:String) + { + var policy = + if (isPrivateInProgress.value) inputPolicies.privateShow; + else if (model.me.kind == Guest) inputPolicies.guest; + else inputPolicies.freeChat; + + return policy.restrict.apply(input).substr(0, policy.maxChars); + } + + + public var messageSent:Signal = model.messageSent; + + public function setMarginTop(pixels:Float) + view.marginTop = pixels; + + public var view:ChatView = hxx(' + + '); + + public var currentInput:Observable = model.observables.currentInput; + public var hasFocus:Observable = model.observables.hasFocus; + public var effectiveHeight:Observable = Observable.auto(function () + return + if (model.collapsed || view.hidden) 0 + else model.height + ); + + public function addUi(ui:RenderResult, ?options:{ ?bottom:Bool }):Void + view.addUi(ui, options); + + public function addPlainMessage(type:MessageType, text:String):Void + model.observables.connectionStatus + .getNext(function (status) + return switch status { + case Online(room): Some(room); + default: None; + } + ) + .handle(function (room) + room.addMessage(new MessageModel({ + type: type, + richBody: [Text(text)] + })) + ); + + function new() + { + connectionStatus.toSignal().handle(function () model.currentInput = '');//TODO: find more elegant solution for this + isPrivateInProgress.bind(function (inProgress) if (inProgress) model.clear()); + isVipShowInProgress.bind(function (inProgress) if (inProgress) { + model.collapsed = false; + model.height = 1; + }); + } + + static function getLanguageOptions():List + return TranslationsHelper.avaiableLanguagesOrder; + + static var flags = TranslationsHelper.getLanguageFlags(); + + static function getFlag(imagePath:String, langTag:String) + return UrlUtil.getIconSource(imagePath, flags.get(langTag), 'flags'); +} + +--- + +package memberapplet.feature.chat; + +import memberapplet.feature.chat.ChatRoom; +import memberapplet.feature.chat.translation.*; +import memberapplet.feature.chat.smileys.*; +import coconut.Ui.hxx; +import com.utils.UrlUtil; + +using com.utils.SignalUtil; +using com.utils.ObservableUtil; + +private typedef InputPolicy = { + @:optional var restrict(default, never):InputRestriction; + var maxChars(default, never):Int; +} + +private abstract InputRestriction(Null) from EReg { + public inline function apply(to:String):String + return if (this == null) to else this.replace(to, ''); + + @:from static function ofString(s:String):InputRestriction + return new EReg('[^$s]', 'ig'); +} + +class Chat implements plumbum.Scope implements IChat { + var dependencies:{ + var connectionStatus:Observable; + var performerNick:Value; // TODO: this shouldn't be here I think ... it duplicates data from the chat room ... instead the chat room should have offline and connecting statuses and there should always be one defined to hold the performer's nick + var isFullscreen:Value; + var isRecommenderEnabled:Value; + var isPrivateInProgress:Value; // TODO: this shouldn't be here for the same reasons as performerNick + var isVipShowInProgress:Value; // TODO: this shouldn't be here for the same reasons as performerNick + var upgrades:UserUpgrades; + var imagePath:String; + var smileys:Value>; + var storage:{ + var language(default, never):State; + var collapsed(default, never):State; + var height(default, never):State; + var fontSize(default, never):State; + } + var inputPolicies:{ + var guest(default, never):InputPolicy; + var freeChat(default, never):InputPolicy; + var privateShow(default, never):InputPolicy; + } + }; + var model:ChatModel = new ChatModel(tink.Anon.merge(storage, dependencies, restrictInput = restrictInput, allSmileys = smileys)); + + function restrictInput(input:String) { + var policy = if (isPrivateInProgress.value) inputPolicies.privateShow; else if (model.me.kind == Guest) inputPolicies.guest; else + inputPolicies.freeChat; + + return policy.restrict.apply(input).substr(0, policy.maxChars); + } + + public var messageSent:Signal = model.messageSent; + + public function setMarginTop(pixels:Float) + view.marginTop = pixels; + + public var view:ChatView = hxx(' + + '); + public var currentInput:Observable = model.observables.currentInput; + public var hasFocus:Observable = model.observables.hasFocus; + public var effectiveHeight:Observable = Observable.auto(function() return if (model.collapsed || view.hidden) 0 else model.height); + + public function addUi(ui:RenderResult, ?options:{?bottom:Bool}):Void + view.addUi(ui, options); + + public function addPlainMessage(type:MessageType, text:String):Void + model.observables.connectionStatus.getNext(function(status) return switch status { + case Online(room): Some(room); + default: None; + }).handle(function(room) room.addMessage(new MessageModel({ + type: type, + richBody: [Text(text)] + }))); + + function new() { + connectionStatus.toSignal().handle(function() model.currentInput = ''); // TODO: find more elegant solution for this + isPrivateInProgress.bind(function(inProgress) if (inProgress) + model.clear()); + isVipShowInProgress.bind(function(inProgress) if (inProgress) { + model.collapsed = false; + model.height = 1; + }); + } + + static function getLanguageOptions():List + return TranslationsHelper.avaiableLanguagesOrder; + + static var flags = TranslationsHelper.getLanguageFlags(); + + static function getFlag(imagePath:String, langTag:String) + return UrlUtil.getIconSource(imagePath, flags.get(langTag), 'flags'); +} diff --git a/test/testcases/sameline/issue_257_return_same.hxtest b/test/testcases/sameline/issue_257_return_same.hxtest index eab39b3b..7e2b5447 100644 --- a/test/testcases/sameline/issue_257_return_same.hxtest +++ b/test/testcases/sameline/issue_257_return_same.hxtest @@ -55,8 +55,8 @@ class TimeUtil { "---------------------------------------------------------------------------------------------------------------------------------------------------------"; return if (remainingDays > 0) '${Std.string(remainingDays)} ${remainingDays == 1 ? L.DAY : L.DAYS}' - else if (remainingHours > 0) '${Std.string(remainingHours)} ${remainingHours == 1 ? L.HOUR : L.HOURS}' - else if (remainingMinutes > 0) '${Std.string(remainingMinutes)} ${remainingMinutes == 1 ? L.MINUTE : L.MINUTES}' - else L.LESS_THAN_A_MINUTE; + else if (remainingHours > 0) '${Std.string(remainingHours)} ${remainingHours == 1 ? L.HOUR : L.HOURS}' + else if (remainingMinutes > 0) '${Std.string(remainingMinutes)} ${remainingMinutes == 1 ? L.MINUTE : L.MINUTES}' + else L.LESS_THAN_A_MINUTE; } } diff --git a/test/testcases/sameline/issue_257_return_same_indent_value_expr.hxtest b/test/testcases/sameline/issue_257_return_same_indent_value_expr.hxtest new file mode 100644 index 00000000..84898799 --- /dev/null +++ b/test/testcases/sameline/issue_257_return_same_indent_value_expr.hxtest @@ -0,0 +1,65 @@ +{ + "indentation": { + "indentComplexValueExpressions": true + }, + "sameLine": { + "ifBody": "same", + "ifElse": "next", + "elseBody": "same", + "elseIf": "same", + "expressionIf": "keep", + "returnBody": "same" + } +} + +--- + +package com.utils; + +import languageprovider.LanguageTranslations.L; + +class TimeUtil +{ + public static function decorateRemainingTime(remainingTime:Float):String + { + var remainingMilliseconds:Float = remainingTime; + var remainingMinutes:Int = Math.floor(remainingMilliseconds / 1000 / 60); + var remainingHours:Int = Math.floor(remainingMinutes / 60); + var remainingDays:Int = Math.floor(remainingHours / 24); + + return 1; + + return "---------------------------------------------------------------------------------------------------------------------------------------------------------"; + + return + if (remainingDays > 0) '${Std.string(remainingDays)} ${remainingDays == 1 ? L.DAY : L.DAYS}' + else if (remainingHours > 0) '${Std.string(remainingHours)} ${remainingHours == 1 ? L.HOUR : L.HOURS}' + else if (remainingMinutes > 0) '${Std.string(remainingMinutes)} ${remainingMinutes == 1 ? L.MINUTE : L.MINUTES}' + else L.LESS_THAN_A_MINUTE; + } +} + +--- + +package com.utils; + +import languageprovider.LanguageTranslations.L; + +class TimeUtil { + public static function decorateRemainingTime(remainingTime:Float):String { + var remainingMilliseconds:Float = remainingTime; + var remainingMinutes:Int = Math.floor(remainingMilliseconds / 1000 / 60); + var remainingHours:Int = Math.floor(remainingMinutes / 60); + var remainingDays:Int = Math.floor(remainingHours / 24); + + return 1; + + return + "---------------------------------------------------------------------------------------------------------------------------------------------------------"; + + return if (remainingDays > 0) '${Std.string(remainingDays)} ${remainingDays == 1 ? L.DAY : L.DAYS}' + else if (remainingHours > 0) '${Std.string(remainingHours)} ${remainingHours == 1 ? L.HOUR : L.HOURS}' + else if (remainingMinutes > 0) '${Std.string(remainingMinutes)} ${remainingMinutes == 1 ? L.MINUTE : L.MINUTES}' + else L.LESS_THAN_A_MINUTE; + } +} diff --git a/test/testcases/sameline/issue_42_if_after_assign_with_blocks_indent_assignment_expr.hxtest b/test/testcases/sameline/issue_42_if_after_assign_with_blocks_indent_assignment_expr.hxtest new file mode 100644 index 00000000..b1809543 --- /dev/null +++ b/test/testcases/sameline/issue_42_if_after_assign_with_blocks_indent_assignment_expr.hxtest @@ -0,0 +1,29 @@ +{ + "indentation": { + "indentComplexValueExpressions": true + } +} + +--- + +class Main { + public static function main() { + var foo = if (bar) { + ""; + } else { + ""; + }; + } +} + +--- + +class Main { + public static function main() { + var foo = if (bar) { + ""; + } else { + ""; + }; + } +} diff --git a/test/testcases/wrapping/issue_136_object_literal_indent_assignment_expr.hxtest b/test/testcases/wrapping/issue_136_object_literal_indent_assignment_expr.hxtest new file mode 100644 index 00000000..1463a931 --- /dev/null +++ b/test/testcases/wrapping/issue_136_object_literal_indent_assignment_expr.hxtest @@ -0,0 +1,59 @@ +{ + "indentation": { + "indentComplexValueExpressions": true + } +} + +--- + +class Main { + public static function main() { + var action = if (relations.length == 0) { + { + command: { + title: title, + command: "", + arguments: [] + }, + range: range + }; + } else { + null; + } + var action = if (relations.length == 0) { + { + command:{title:title,command:"",arguments:[]}, + range:range + }; + } else { + {command:{title:title,command:"",arguments:[]},range:range}; + } + } +} + +--- + +class Main { + public static function main() { + var action = if (relations.length == 0) { + { + command: { + title: title, + command: "", + arguments: [] + }, + range: range + }; + } else { + null; + } + var action = if (relations.length == 0) { + { + command: {title: title, command: "", arguments: []}, + range: range + }; + } else { + {command: {title: title, command: "", arguments: []}, range: range}; + } + } +}