From 4c0e90f7a7333cd2d3b5e18aabad5d01f745a2db Mon Sep 17 00:00:00 2001 From: AlexHaxe Date: Sat, 1 Dec 2018 17:25:52 +0100 Subject: [PATCH] expanded whitespace options for parens and braces, fixes #251 (#282) * expanded whitespace options for parens and braces, fixes #251 * removed CompileTime.getAllClasses since it uses Context.onMacroContextReused (see https://github.com/HaxeFoundation/haxe/issues/5746) --- CHANGELOG.md | 2 + resources/default-hxformat.json | 70 ++++- resources/formatter-schema.json | 265 ++++++++++-------- src/formatter/config/WhitespaceConfig.hx | 109 +++++-- src/formatter/marker/MarkWhitespace.hx | 196 +++++++++---- test/TestSuite.hx | 25 +- .../indent_with_comment_body.hxtest | 8 +- ...ta_with_parameter_with_popen_before.hxtest | 12 +- ...issue_251_space_after_anon_function.hxtest | 25 ++ ...251_space_after_anon_function_empty.hxtest | 27 ++ .../whitespace/not_with_popen.hxtest | 9 +- .../whitespace/popen_in_metadata.hxtest | 25 +- .../whitespace/type_hint_around.hxtest | 9 +- .../whitespace_after_type_parameter.hxtest | 6 +- .../whitespace/whitespace_before_popen.hxtest | 19 +- 15 files changed, 588 insertions(+), 219 deletions(-) create mode 100644 test/testcases/whitespace/issue_251_space_after_anon_function.hxtest create mode 100644 test/testcases/whitespace/issue_251_space_after_anon_function_empty.hxtest diff --git a/CHANGELOG.md b/CHANGELOG.md index b49d63fe..f78cf357 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## dev branch / next version (1.x.x) +- **Breaking Change** replaced `whitespace.openingParenPolicy` and `whitespace.closingParenPolicy` settings with `whitespace.parenConfig` [#282](https://github.com/HaxeCheckstyle/haxe-formatter/issues/282) +- **Breaking Change** replaced `whitespace.openingBracePolicy` `whitespace.closingBracePolicy`, `whitespace.objectOpeningBracePolicy` and `whitespace.objectClosingBracePolicy` settings with `whitespace.bracesConfig` [#282](https://github.com/HaxeCheckstyle/haxe-formatter/issues/282) - Added check to prevent tokentree parser issues from deleting code [#281](https://github.com/HaxeCheckstyle/haxe-formatter/issues/281) - Fixed properties in anon types [#276](https://github.com/HaxeCheckstyle/haxe-formatter/issues/276) - Fixed empty lines between single line types with meta [#277](https://github.com/HaxeCheckstyle/haxe-formatter/issues/277) diff --git a/resources/default-hxformat.json b/resources/default-hxformat.json index bffc4b44..ba2abb4a 100644 --- a/resources/default-hxformat.json +++ b/resources/default-hxformat.json @@ -131,11 +131,36 @@ "whitespace": { "arrowFunctionsPolicy": "around", "binopPolicy": "around", + "bracesConfig": { + "anonTypeBraces": { + "openingPolicy": "before", + "closingPolicy": "onlyAfter", + "removeInnerWhenEmpty": true + }, + "blockBraces": { + "openingPolicy": "before", + "closingPolicy": "onlyAfter", + "removeInnerWhenEmpty": true + }, + "objectLiteralBraces": { + "openingPolicy": "before", + "closingPolicy": "onlyAfter", + "removeInnerWhenEmpty": true + }, + "typedefBraces": { + "openingPolicy": "before", + "closingPolicy": "onlyAfter", + "removeInnerWhenEmpty": true + }, + "unknownBraces": { + "openingPolicy": "before", + "closingPolicy": "onlyAfter", + "removeInnerWhenEmpty": true + } + }, "caseColonPolicy": "onlyAfter", "catchPolicy": "after", - "closingBracePolicy": "after", "closingBracketPolicy": "none", - "closingParenPolicy": "onlyAfter", "colonPolicy": "none", "commaPolicy": "onlyAfter", "compressSuccessiveParenthesis": true, @@ -147,12 +172,45 @@ "functionTypeHaxe4Policy": "around", "ifPolicy": "after", "intervalPolicy": "none", - "objectClosingBracePolicy": "onlyAfter", "objectFieldColonPolicy": "after", - "objectOpeningBracePolicy": "onlyBefore", - "openingBracePolicy": "before", "openingBracketPolicy": "noneAfter", - "openingParenPolicy": "noneAfter", + "parenConfig": { + "anonFuncParamParens": { + "closingPolicy": "onlyAfter", + "openingPolicy": "none", + "removeInnerWhenEmpty": true + }, + "callParens": { + "closingPolicy": "onlyAfter", + "openingPolicy": "none", + "removeInnerWhenEmpty": true + }, + "conditionParens": { + "openingPolicy": "noneAfter", + "closingPolicy": "onlyAfter", + "removeInnerWhenEmpty": true + }, + "expressionParens": { + "openingPolicy": "noneAfter", + "closingPolicy": "onlyAfter", + "removeInnerWhenEmpty": true + }, + "forLoopParens": { + "openingPolicy": "noneAfter", + "closingPolicy": "onlyAfter", + "removeInnerWhenEmpty": true + }, + "funcParamParens": { + "closingPolicy": "onlyAfter", + "openingPolicy": "none", + "removeInnerWhenEmpty": true + }, + "metadataParens": { + "closingPolicy": "onlyAfter", + "openingPolicy": "none", + "removeInnerWhenEmpty": true + } + }, "semicolonPolicy": "onlyAfter", "switchPolicy": "after", "ternaryPolicy": "around", diff --git a/resources/formatter-schema.json b/resources/formatter-schema.json index b6bf9f5e..171ead8b 100644 --- a/resources/formatter-schema.json +++ b/resources/formatter-schema.json @@ -194,6 +194,47 @@ }, "type": "object" }, + "OpenClosePolicy": { + "additionalProperties": false, + "properties": { + "closingPolicy": { + "description": "\")\"", + "type": "string", + "enum": [ + "none", + "before", + "noneBefore", + "onlyBefore", + "after", + "onlyAfter", + "noneAfter", + "around" + ], + "propertyOrder": 1 + }, + "removeInnerWhenEmpty": { + "description": "\"()\" or \"( )\" - if `openingPolicy` contains `After` or `closingPolicy` contains `Before`", + "type": "boolean", + "propertyOrder": 2 + }, + "openingPolicy": { + "description": "\"(\"", + "type": "string", + "enum": [ + "none", + "before", + "noneBefore", + "onlyBefore", + "after", + "onlyAfter", + "noneAfter", + "around" + ], + "propertyOrder": 0 + } + }, + "type": "object" + }, "EnumAbstractFieldsEmptyLinesConfig": { "additionalProperties": false, "properties": { @@ -269,6 +310,47 @@ }, "type": "object" }, + "ParenWhitespaceConfig": { + "additionalProperties": false, + "properties": { + "metadataParens": { + "description": "parens used for metadata", + "$ref": "#/definitions/OpenClosePolicy", + "propertyOrder": 0 + }, + "callParens": { + "description": "parens used for calls", + "$ref": "#/definitions/OpenClosePolicy", + "propertyOrder": 3 + }, + "forLoopParens": { + "description": "parens used for for loops", + "$ref": "#/definitions/OpenClosePolicy", + "propertyOrder": 5 + }, + "anonFuncParamParens": { + "description": "parens used for anon function parameters", + "$ref": "#/definitions/OpenClosePolicy", + "propertyOrder": 2 + }, + "conditionParens": { + "description": "parens used for conditions", + "$ref": "#/definitions/OpenClosePolicy", + "propertyOrder": 4 + }, + "expressionParens": { + "description": "parens used for expressions", + "$ref": "#/definitions/OpenClosePolicy", + "propertyOrder": 6 + }, + "funcParamParens": { + "description": "parens used for function parameters", + "$ref": "#/definitions/OpenClosePolicy", + "propertyOrder": 1 + } + }, + "type": "object" + }, "WrapRule": { "required": [ "conditions", @@ -526,6 +608,37 @@ }, "type": "object" }, + "BracesWhitespaceConfig": { + "additionalProperties": false, + "properties": { + "objectLiteralBraces": { + "description": "braces for object literals", + "$ref": "#/definitions/OpenClosePolicy", + "propertyOrder": 3 + }, + "unknownBraces": { + "description": "unknown braces", + "$ref": "#/definitions/OpenClosePolicy", + "propertyOrder": 4 + }, + "blockBraces": { + "description": "braces for blocks", + "$ref": "#/definitions/OpenClosePolicy", + "propertyOrder": 0 + }, + "typedefBraces": { + "description": "braces for typdefs", + "$ref": "#/definitions/OpenClosePolicy", + "propertyOrder": 1 + }, + "anonTypeBraces": { + "description": "braces for anon types", + "$ref": "#/definitions/OpenClosePolicy", + "propertyOrder": 2 + } + }, + "type": "object" + }, "ConditionalEmptyLinesConfig": { "additionalProperties": false, "properties": { @@ -643,21 +756,6 @@ "WhitespaceConfig": { "additionalProperties": false, "properties": { - "openingParenPolicy": { - "description": "\"(\"", - "type": "string", - "enum": [ - "none", - "before", - "noneBefore", - "onlyBefore", - "after", - "onlyAfter", - "noneAfter", - "around" - ], - "propertyOrder": 0 - }, "ternaryPolicy": { "type": "string", "enum": [ @@ -670,7 +768,7 @@ "noneAfter", "around" ], - "propertyOrder": 18 + "propertyOrder": 14 }, "typeParamClosePolicy": { "description": "\">\"", @@ -685,39 +783,9 @@ "noneAfter", "around" ], - "propertyOrder": 9 - }, - "caseColonPolicy": { - "type": "string", - "enum": [ - "none", - "before", - "noneBefore", - "onlyBefore", - "after", - "onlyAfter", - "noneAfter", - "around" - ], - "propertyOrder": 14 - }, - "closingBracePolicy": { - "description": "\"}\" except object literals", - "type": "string", - "enum": [ - "none", - "before", - "noneBefore", - "onlyBefore", - "after", - "onlyAfter", - "noneAfter", - "around" - ], "propertyOrder": 5 }, - "closingParenPolicy": { - "description": "\")\"", + "caseColonPolicy": { "type": "string", "enum": [ "none", @@ -729,7 +797,7 @@ "noneAfter", "around" ], - "propertyOrder": 1 + "propertyOrder": 10 }, "intervalPolicy": { "type": "string", @@ -743,7 +811,7 @@ "noneAfter", "around" ], - "propertyOrder": 28 + "propertyOrder": 24 }, "commaPolicy": { "type": "string", @@ -757,7 +825,7 @@ "noneAfter", "around" ], - "propertyOrder": 11 + "propertyOrder": 7 }, "typeCheckColonPolicy": { "type": "string", @@ -771,7 +839,7 @@ "noneAfter", "around" ], - "propertyOrder": 17 + "propertyOrder": 13 }, "typeParamOpenPolicy": { "description": "\"<\"", @@ -786,7 +854,7 @@ "noneAfter", "around" ], - "propertyOrder": 8 + "propertyOrder": 4 }, "openingBracketPolicy": { "description": "\"[\"", @@ -818,25 +886,15 @@ ], "propertyOrder": 3 }, + "bracesConfig": { + "description": "\"{\" + \"}\"", + "$ref": "#/definitions/BracesWhitespaceConfig", + "propertyOrder": 1 + }, "compressSuccessiveParenthesis": { "description": "should formatter compress spaces for successive parenthesis `( [ {` vs. `([{`", "type": "boolean", - "propertyOrder": 32 - }, - "objectOpeningBracePolicy": { - "description": "\"{\" in object literal", - "type": "string", - "enum": [ - "none", - "before", - "noneBefore", - "onlyBefore", - "after", - "onlyAfter", - "noneAfter", - "around" - ], - "propertyOrder": 6 + "propertyOrder": 28 }, "functionTypeHaxe3Policy": { "type": "string", @@ -850,22 +908,7 @@ "noneAfter", "around" ], - "propertyOrder": 30 - }, - "openingBracePolicy": { - "description": "\"{\" except object literals", - "type": "string", - "enum": [ - "none", - "before", - "noneBefore", - "onlyBefore", - "after", - "onlyAfter", - "noneAfter", - "around" - ], - "propertyOrder": 4 + "propertyOrder": 26 }, "arrowFunctionsPolicy": { "type": "string", @@ -879,7 +922,7 @@ "noneAfter", "around" ], - "propertyOrder": 29 + "propertyOrder": 25 }, "doPolicy": { "type": "string", @@ -893,7 +936,7 @@ "noneAfter", "around" ], - "propertyOrder": 21 + "propertyOrder": 17 }, "semicolonPolicy": { "type": "string", @@ -907,7 +950,7 @@ "noneAfter", "around" ], - "propertyOrder": 19 + "propertyOrder": 15 }, "forPolicy": { "type": "string", @@ -921,7 +964,12 @@ "noneAfter", "around" ], - "propertyOrder": 23 + "propertyOrder": 19 + }, + "parenConfig": { + "description": "\"(\" + \")\"", + "$ref": "#/definitions/ParenWhitespaceConfig", + "propertyOrder": 0 }, "objectFieldColonPolicy": { "type": "string", @@ -935,7 +983,7 @@ "noneAfter", "around" ], - "propertyOrder": 15 + "propertyOrder": 11 }, "colonPolicy": { "type": "string", @@ -949,22 +997,7 @@ "noneAfter", "around" ], - "propertyOrder": 13 - }, - "objectClosingBracePolicy": { - "description": "\"}\" in object literal", - "type": "string", - "enum": [ - "none", - "before", - "noneBefore", - "onlyBefore", - "after", - "onlyAfter", - "noneAfter", - "around" - ], - "propertyOrder": 7 + "propertyOrder": 9 }, "dotPolicy": { "type": "string", @@ -978,7 +1011,7 @@ "noneAfter", "around" ], - "propertyOrder": 12 + "propertyOrder": 8 }, "switchPolicy": { "type": "string", @@ -992,12 +1025,12 @@ "noneAfter", "around" ], - "propertyOrder": 24 + "propertyOrder": 20 }, "formatStringInterpolation": { "description": "should formatter try to format string interpolation expressions (e.g. '${x+3}' -> '${x + 3}')\n\t\tonly applies spaces, no newlines or wrapping", "type": "boolean", - "propertyOrder": 33 + "propertyOrder": 29 }, "typeExtensionPolicy": { "type": "string", @@ -1011,7 +1044,7 @@ "noneAfter", "around" ], - "propertyOrder": 10 + "propertyOrder": 6 }, "whilePolicy": { "type": "string", @@ -1025,7 +1058,7 @@ "noneAfter", "around" ], - "propertyOrder": 22 + "propertyOrder": 18 }, "typeHintColonPolicy": { "type": "string", @@ -1039,7 +1072,7 @@ "noneAfter", "around" ], - "propertyOrder": 16 + "propertyOrder": 12 }, "catchPolicy": { "type": "string", @@ -1053,7 +1086,7 @@ "noneAfter", "around" ], - "propertyOrder": 26 + "propertyOrder": 22 }, "binopPolicy": { "type": "string", @@ -1067,7 +1100,7 @@ "noneAfter", "around" ], - "propertyOrder": 27 + "propertyOrder": 23 }, "ifPolicy": { "type": "string", @@ -1081,7 +1114,7 @@ "noneAfter", "around" ], - "propertyOrder": 20 + "propertyOrder": 16 }, "functionTypeHaxe4Policy": { "type": "string", @@ -1095,7 +1128,7 @@ "noneAfter", "around" ], - "propertyOrder": 31 + "propertyOrder": 27 }, "tryPolicy": { "type": "string", @@ -1109,7 +1142,7 @@ "noneAfter", "around" ], - "propertyOrder": 25 + "propertyOrder": 21 } }, "type": "object" diff --git a/src/formatter/config/WhitespaceConfig.hx b/src/formatter/config/WhitespaceConfig.hx index f4ff67b4..39b3e220 100644 --- a/src/formatter/config/WhitespaceConfig.hx +++ b/src/formatter/config/WhitespaceConfig.hx @@ -2,14 +2,14 @@ package formatter.config; typedef WhitespaceConfig = { /** - "(" + "(" + ")" **/ - @:default(NoneAfter) @:optional var openingParenPolicy:WhitespacePolicy; + @:default(auto) @:optional var parenConfig:ParenWhitespaceConfig; /** - ")" + "{" + "}" **/ - @:default(OnlyAfter) @:optional var closingParenPolicy:WhitespacePolicy; + @:default(auto) @:optional var bracesConfig:BracesWhitespaceConfig; /** "[" @@ -21,26 +21,6 @@ typedef WhitespaceConfig = { **/ @:default(None) @:optional var closingBracketPolicy:WhitespacePolicy; - /** - "{" except object literals - **/ - @:default(Before) @:optional var openingBracePolicy:WhitespacePolicy; - - /** - "}" except object literals - **/ - @:default(After) @:optional var closingBracePolicy:WhitespacePolicy; - - /** - "{" in object literal - **/ - @:default(OnlyBefore) @:optional var objectOpeningBracePolicy:WhitespacePolicy; - - /** - "}" in object literal - **/ - @:default(OnlyAfter) @:optional var objectClosingBracePolicy:WhitespacePolicy; - /** "<" **/ @@ -84,3 +64,84 @@ typedef WhitespaceConfig = { **/ @:default(true) @:optional var formatStringInterpolation:Bool; } + +typedef ParenWhitespaceConfig = { + /** + parens used for metadata + **/ + @:default(auto) @:optional var metadataParens:OpenClosePolicy; + + /** + parens used for function parameters + **/ + @:default(auto) @:optional var funcParamParens:OpenClosePolicy; + + /** + parens used for anon function parameters + **/ + @:default(auto) @:optional var anonFuncParamParens:OpenClosePolicy; + + /** + parens used for calls + **/ + @:default(auto) @:optional var callParens:OpenClosePolicy; + + /** + parens used for conditions + **/ + @:default({openingPolicy: NoneAfter, closingPolicy: OnlyAfter, removeInnerWhenEmpty: true}) @:optional var conditionParens:OpenClosePolicy; + + /** + parens used for for loops + **/ + @:default({openingPolicy: NoneAfter, closingPolicy: OnlyAfter, removeInnerWhenEmpty: true}) @:optional var forLoopParens:OpenClosePolicy; + + /** + parens used for expressions + **/ + @:default({openingPolicy: NoneAfter, closingPolicy: OnlyAfter, removeInnerWhenEmpty: true}) @:optional var expressionParens:OpenClosePolicy; +} + +typedef BracesWhitespaceConfig = { + /** + braces for blocks + **/ + @:default({openingPolicy: Before, closingPolicy: OnlyAfter, removeInnerWhenEmpty: true}) @:optional var blockBraces:OpenClosePolicy; + + /** + braces for typdefs + **/ + @:default({openingPolicy: Before, closingPolicy: OnlyAfter, removeInnerWhenEmpty: true}) @:optional var typedefBraces:OpenClosePolicy; + + /** + braces for anon types + **/ + @:default({openingPolicy: Before, closingPolicy: OnlyAfter, removeInnerWhenEmpty: true}) @:optional var anonTypeBraces:OpenClosePolicy; + + /** + braces for object literals + **/ + @:default({openingPolicy: Before, closingPolicy: OnlyAfter, removeInnerWhenEmpty: true}) @:optional var objectLiteralBraces:OpenClosePolicy; + + /** + unknown braces + **/ + @:default({openingPolicy: Before, closingPolicy: OnlyAfter, removeInnerWhenEmpty: true}) @:optional var unknownBraces:OpenClosePolicy; +} + +typedef OpenClosePolicy = { + /** + "(" + **/ + @:default(None) @:optional var openingPolicy:WhitespacePolicy; + + /** + ")" + **/ + @:default(OnlyAfter) @:optional var closingPolicy:WhitespacePolicy; + + /** + "()" or "( )" - if `openingPolicy` contains `After` or `closingPolicy` contains `Before` + **/ + @:default(true) @:optional var removeInnerWhenEmpty:Bool; +} diff --git a/src/formatter/marker/MarkWhitespace.hx b/src/formatter/marker/MarkWhitespace.hx index a8bce5ae..b3a10c8f 100644 --- a/src/formatter/marker/MarkWhitespace.hx +++ b/src/formatter/marker/MarkWhitespace.hx @@ -55,11 +55,11 @@ class MarkWhitespace extends MarkerBase { case POpen: markPOpen(token); case PClose: - successiveParenthesis(token, true, config.whitespace.closingParenPolicy, config.whitespace.compressSuccessiveParenthesis); + markPClose(token); case BrOpen: - successiveParenthesis(token, false, config.whitespace.openingBracePolicy, config.whitespace.compressSuccessiveParenthesis); + markBrOpen(token); case BrClose: - successiveParenthesis(token, true, config.whitespace.closingBracePolicy, config.whitespace.compressSuccessiveParenthesis); + markBrClose(token); case BkOpen: successiveParenthesis(token, false, config.whitespace.openingBracketPolicy, config.whitespace.compressSuccessiveParenthesis); case BkClose: @@ -164,42 +164,41 @@ class MarkWhitespace extends MarkerBase { whitespace(token, policy); return; } - if (next != null) { - switch (next.token.tok) { - case BrClose: - var selfInfo:TokenInfo = getTokenInfo(token); - if (selfInfo.whitespaceAfter == Newline) { - return; - } - policy = policy.remove(After); - case POpen, PClose, BrOpen, BkOpen, BkClose: - if (token.is(PClose)) { - switch (TokenTreeCheckUtils.getPOpenType(token.parent)) { - case CONDITION: - policy = policy.add(After); - case PARAMETER: - policy = policy.add(After); - default: - policy = policy.remove(After); - } - } else { + if (closing) { + if (next != null) { + switch (next.token.tok) { + case BrClose: policy = policy.remove(After); - } - default: + case POpen, PClose, BrOpen, BkOpen, BkClose: + if (token.is(PClose)) { + switch (TokenTreeCheckUtils.getPOpenType(token.parent)) { + case CONDITION: + policy = policy.add(After); + case PARAMETER: + policy = policy.add(After); + default: + policy = policy.remove(After); + } + } else { + policy = policy.remove(After); + } + default: + } } - } - var prev:TokenInfo = getPreviousToken(token); - if (prev != null) { - switch (prev.token.tok) { - case POpen, BrOpen, BkOpen: - policy = policy.remove(Before); - case Binop(OpLt): - if (token.is(BrOpen)) { + } else { + var prev:TokenInfo = getPreviousToken(token); + if (prev != null) { + switch (prev.token.tok) { + case POpen, BrOpen, BkOpen: + policy = policy.remove(Before); + case Binop(OpLt): + if (token.is(BrOpen)) { + return; + } + case DblDot, Arrow: return; - } - case DblDot, Arrow: - return; - default: + default: + } } } whitespace(token, policy); @@ -394,37 +393,124 @@ class MarkWhitespace extends MarkerBase { } } - function markPOpen(token:TokenTree) { - var policy:WhitespacePolicy = config.whitespace.openingParenPolicy; + function determinePOpenPolicy(token:TokenTree):OpenClosePolicy { var type:POpenType = TokenTreeCheckUtils.getPOpenType(token); switch (type) { case AT: - policy = policy.remove(Before); + config.whitespace.parenConfig.metadataParens.openingPolicy = config.whitespace.parenConfig.metadataParens.openingPolicy.remove(Before); + return config.whitespace.parenConfig.metadataParens; case PARAMETER: + switch (token.parent.tok) { + case Const(CIdent(_)), Kwd(KwdNew): + return config.whitespace.parenConfig.funcParamParens; + default: + return config.whitespace.parenConfig.anonFuncParamParens; + } case CALL: + return config.whitespace.parenConfig.callParens; + case CONDITION: + return config.whitespace.parenConfig.conditionParens; case FORLOOP: - case CONDITION, EXPRESSION: - var parent:TokenTree = token.parent; - while ((parent != null) && (parent.tok != null)) { - switch (parent.tok) { - case Const(CIdent(_)): - case Dot: - case DblDot: - case Unop(_): - policy = policy.remove(Before); - break; - case At: - policy = policy.remove(Before); - break; - default: - break; + return config.whitespace.parenConfig.forLoopParens; + case EXPRESSION: + return config.whitespace.parenConfig.expressionParens; + } + return config.whitespace.parenConfig.expressionParens; + } + + function markPOpen(token:TokenTree) { + var openClosePolicy:OpenClosePolicy = determinePOpenPolicy(token); + var policy:WhitespacePolicy = openClosePolicy.openingPolicy; + var prev:TokenInfo = getPreviousToken(token); + if (prev != null) { + switch (prev.token.tok) { + case Unop(_): + policy = policy.remove(Before); + case Binop(_), Comment(_): + if (prev.spacesAfter > 0) { + policy = policy.add(Before); } - parent = parent.parent; + default: + } + } + if (openClosePolicy.removeInnerWhenEmpty) { + var next:TokenInfo = getNextToken(token); + if (next != null) { + switch (next.token.tok) { + case PClose: + policy = policy.remove(After); + default: } + } } successiveParenthesis(token, false, policy, config.whitespace.compressSuccessiveParenthesis); } + function markPClose(token:TokenTree) { + var openClosePolicy:OpenClosePolicy = determinePOpenPolicy(token.parent); + var policy:WhitespacePolicy = openClosePolicy.closingPolicy; + if (openClosePolicy.removeInnerWhenEmpty) { + var prev:TokenInfo = getPreviousToken(token); + if (prev != null) { + switch (prev.token.tok) { + case POpen: + policy = policy.remove(Before); + default: + } + } + } + successiveParenthesis(token, true, policy, config.whitespace.compressSuccessiveParenthesis); + } + + function determineBrOpenPolicy(token:TokenTree):OpenClosePolicy { + var type:BrOpenType = TokenTreeCheckUtils.getBrOpenType(token); + switch (type) { + case BLOCK: + return config.whitespace.bracesConfig.blockBraces; + case TYPEDEFDECL: + return config.whitespace.bracesConfig.typedefBraces; + case OBJECTDECL: + return config.whitespace.bracesConfig.objectLiteralBraces; + case ANONTYPE: + return config.whitespace.bracesConfig.anonTypeBraces; + case UNKNOWN: + return config.whitespace.bracesConfig.unknownBraces; + } + return config.whitespace.bracesConfig.unknownBraces; + } + + function markBrOpen(token:TokenTree) { + var openClosePolicy:OpenClosePolicy = determineBrOpenPolicy(token); + var policy:WhitespacePolicy = openClosePolicy.openingPolicy; + if (openClosePolicy.removeInnerWhenEmpty) { + var next:TokenInfo = getNextToken(token); + if (next != null) { + switch (next.token.tok) { + case BrClose: + policy = policy.remove(After); + default: + } + } + } + successiveParenthesis(token, false, policy, config.whitespace.compressSuccessiveParenthesis); + } + + function markBrClose(token:TokenTree) { + var openClosePolicy:OpenClosePolicy = determineBrOpenPolicy(token.parent); + var policy:WhitespacePolicy = openClosePolicy.closingPolicy; + if (openClosePolicy.removeInnerWhenEmpty) { + var prev:TokenInfo = getPreviousToken(token); + if (prev != null) { + switch (prev.token.tok) { + case BrOpen: + policy = policy.remove(Before); + default: + } + } + } + successiveParenthesis(token, true, policy, config.whitespace.compressSuccessiveParenthesis); + } + function markComment(token:TokenTree) { var policy:WhitespacePolicy = Around; var next:TokenInfo = getNextToken(token); diff --git a/test/TestSuite.hx b/test/TestSuite.hx index 49dd734e..680a5187 100644 --- a/test/TestSuite.hx +++ b/test/TestSuite.hx @@ -1,4 +1,12 @@ import formatter.FormatStatsTest; +import testcases.EmptyLinesTestCases; +import testcases.IndentationTestCases; +import testcases.LineEndsTestCases; +import testcases.MissingTestCases; +import testcases.Other; +import testcases.SameLineTestCases; +import testcases.WhitespaceTestCases; +import testcases.WrappingTestCases; class TestSuite extends massive.munit.TestSuite { public function new() { @@ -12,9 +20,18 @@ class TestSuite extends massive.munit.TestSuite { add(FormatStatsTest); } - var tests = CompileTime.getAllClasses(GoldBaseTest); - for (testClass in tests) { - add(testClass); - } + add(EmptyLinesTestCases); + add(IndentationTestCases); + add(LineEndsTestCases); + add(MissingTestCases); + add(Other); + add(SameLineTestCases); + add(WhitespaceTestCases); + add(WrappingTestCases); + // CompileTime.getAllClasses uses Context.onMacroContextReused which was removed from Haxe 4 (see https://github.com/HaxeFoundation/haxe/issues/5746) + // var tests = CompileTime.getAllClasses(GoldBaseTest); + // for (testClass in tests) { + // add(testClass); + // } } } diff --git a/test/testcases/indentation/indent_with_comment_body.hxtest b/test/testcases/indentation/indent_with_comment_body.hxtest index e477abf5..7cdb60dc 100644 --- a/test/testcases/indentation/indent_with_comment_body.hxtest +++ b/test/testcases/indentation/indent_with_comment_body.hxtest @@ -10,8 +10,12 @@ "whitespace": { "colonPolicy": "around", "typeHintColonPolicy": "around", - "openingParenPolicy": "before", - "openingBracketPolicy": "before" + "openingBracketPolicy": "before", + "parenConfig": { + "funcParamParens": { + "openingPolicy": "before" + } + } }, "sameLine": { "catchBody": "next", diff --git a/test/testcases/whitespace/issue_241_metadata_with_parameter_with_popen_before.hxtest b/test/testcases/whitespace/issue_241_metadata_with_parameter_with_popen_before.hxtest index 28f21db5..b9130a11 100644 --- a/test/testcases/whitespace/issue_241_metadata_with_parameter_with_popen_before.hxtest +++ b/test/testcases/whitespace/issue_241_metadata_with_parameter_with_popen_before.hxtest @@ -1,6 +1,16 @@ { "whitespace": { - "openingParenPolicy": "before" + "parenConfig": { + "anonFuncParamParens": { + "openingPolicy": "before" + }, + "funcParamParens": { + "openingPolicy": "before" + }, + "callParens": { + "openingPolicy": "before" + } + } } } diff --git a/test/testcases/whitespace/issue_251_space_after_anon_function.hxtest b/test/testcases/whitespace/issue_251_space_after_anon_function.hxtest new file mode 100644 index 00000000..fb19c7cc --- /dev/null +++ b/test/testcases/whitespace/issue_251_space_after_anon_function.hxtest @@ -0,0 +1,25 @@ +{ + "whitespace": { + "parenConfig": { + "anonFuncParamParens": { + "openingPolicy": "before" + } + } + } +} + +--- + +class Main { +function loadAndTrace() { + load().handle(function (res) trace(res)); +} +} + +--- + +class Main { + function loadAndTrace() { + load().handle(function (res) trace(res)); + } +} diff --git a/test/testcases/whitespace/issue_251_space_after_anon_function_empty.hxtest b/test/testcases/whitespace/issue_251_space_after_anon_function_empty.hxtest new file mode 100644 index 00000000..5f102fe2 --- /dev/null +++ b/test/testcases/whitespace/issue_251_space_after_anon_function_empty.hxtest @@ -0,0 +1,27 @@ +{ + "whitespace": { + "parenConfig": { + "anonFuncParamParens": { + "openingPolicy": "around", + "closingPolicy": "around", + "removeInnerWhenEmpty": false + } + } + } +} + +--- + +class Main { +function loadAndTrace() { + load().handle(function () trace(res)); +} +} + +--- + +class Main { + function loadAndTrace() { + load().handle(function ( ) trace(res)); + } +} diff --git a/test/testcases/whitespace/not_with_popen.hxtest b/test/testcases/whitespace/not_with_popen.hxtest index c773d27b..a07907f1 100644 --- a/test/testcases/whitespace/not_with_popen.hxtest +++ b/test/testcases/whitespace/not_with_popen.hxtest @@ -1,6 +1,13 @@ { "whitespace": { - "openingParenPolicy": "before" + "parenConfig": { + "funcParamParens": { + "openingPolicy": "before" + }, + "callParens": { + "openingPolicy": "before" + } + } } } diff --git a/test/testcases/whitespace/popen_in_metadata.hxtest b/test/testcases/whitespace/popen_in_metadata.hxtest index 8eb17522..058e4be9 100644 --- a/test/testcases/whitespace/popen_in_metadata.hxtest +++ b/test/testcases/whitespace/popen_in_metadata.hxtest @@ -3,9 +3,30 @@ "metadataType": "after" }, "whitespace": { - "openingParenPolicy": "before" + "parenConfig": { + "metadataParens": { + "openingPolicy": "before" + }, + "funcParamParens": { + "openingPolicy": "before" + }, + "anonFuncParamParens": { + "openingPolicy": "before" + }, + "callParens": { + "openingPolicy": "before" + }, + "conditionParens": { + "openingPolicy": "before" + }, + "forLoopParens": { + "openingPolicy": "before" + }, + "expressionParens": { + "openingPolicy": "before" + } + } } - } --- diff --git a/test/testcases/whitespace/type_hint_around.hxtest b/test/testcases/whitespace/type_hint_around.hxtest index bd11d8ca..44872000 100644 --- a/test/testcases/whitespace/type_hint_around.hxtest +++ b/test/testcases/whitespace/type_hint_around.hxtest @@ -1,7 +1,14 @@ { "whitespace" : { "typeHintColonPolicy" : "around", - "openingParenPolicy": "before" + "parenConfig": { + "funcParamParens": { + "openingPolicy": "before" + }, + "callParens": { + "openingPolicy": "before" + } + } } } diff --git a/test/testcases/whitespace/whitespace_after_type_parameter.hxtest b/test/testcases/whitespace/whitespace_after_type_parameter.hxtest index efc7f5eb..5b410f6f 100644 --- a/test/testcases/whitespace/whitespace_after_type_parameter.hxtest +++ b/test/testcases/whitespace/whitespace_after_type_parameter.hxtest @@ -1,6 +1,10 @@ { "whitespace": { - "openingParenPolicy": "before" + "parenConfig": { + "funcParamParens": { + "openingPolicy": "before" + } + } } } diff --git a/test/testcases/whitespace/whitespace_before_popen.hxtest b/test/testcases/whitespace/whitespace_before_popen.hxtest index 4eadb2c3..c1656b9e 100644 --- a/test/testcases/whitespace/whitespace_before_popen.hxtest +++ b/test/testcases/whitespace/whitespace_before_popen.hxtest @@ -1,10 +1,17 @@ { - "whitespace": { - "colonPolicy": "around", - "typeHintColonPolicy": "around", - "openingParenPolicy": "before", - "openingBracketPolicy": "before" - } + "whitespace": { + "colonPolicy": "around", + "typeHintColonPolicy": "around", + "parenConfig": { + "funcParamParens": { + "openingPolicy": "before" + }, + "callParens": { + "openingPolicy": "before" + } + }, + "openingBracketPolicy": "before" + } }