diff --git a/README.md b/README.md index fc53863..d2cb219 100644 --- a/README.md +++ b/README.md @@ -36,10 +36,11 @@ found in .editorconfig files. * **--max_line_length**: See **max_line_length** below * **--soft_max_line_length**: See **dfmt_soft_max_line_length** below * **--outdent_attributes**: See **dfmt_outdent_attributes** below -* **--outdent_labels**: See **dfmt_outdent_labels** below * **--space_after_cast**: See **dfmt_space_after_cast** below * **--split_operator_at_line_end**: See **dfmt_split_operator_at_line_end** below * **--tab_width**: See **tab_width** below +* **--selective_import_space**: See **dfmt_selective_import_space** below +* **--compact_labeled_statements**: See **dfmt_compact_labeled_statements** below ### Example ``` @@ -47,6 +48,28 @@ dfmt --inplace --space_after_cast=false --max_line_length=80 \ --soft_max_line_length=70 --brace_style=otbs file.d ``` +## Disabling formatting +Formatting can be temporarily disabled by placing the comments ```// dfmt off``` +and ```// dfmt on``` around code that you do not want formatted. + +```d +void main(string[] args) +{ + bool optionOne, optionTwo, optionThree; + + // dfmt has no way of knowing that "getopt" is special, so it wraps the + // argument list normally + getopt(args, "optionOne", &optionOne, "optionTwo", &optionTwo, "optionThree", &optionThree); + + // dfmt off + getopt(args, + "optionOne", &optionOne, + "optionTwo", &optionTwo, + "optionThree", &optionThree); + // dfmt on +} +``` + ## Configuration **dfmt** uses [EditorConfig](http://editorconfig.org/) configuration files. **dfmt**-specific properties are prefixed with *dfmt_*. @@ -66,12 +89,13 @@ Property Name | Allowed Values | Default Value | Description --------------|----------------|---------------|------------ dfmt_brace_style | `allman`, `otbs`, or `stroustrup` | `allman` | [See Wikipedia](https://en.wikipedia.org/wiki/Brace_style) dfmt_soft_max_line_length | positive integers | `80` | The formatting process will usually keep lines below this length, but they may be up to max_line_length columns long. -dfmt_outdent_labels (Not yet implemented) | `true`, `false` | `true` | Decrease the indentation of labels dfmt_align_switch_statements (Not yet implemented) | `true`, `false` | `true` | Align labels, cases, and defaults with their enclosing switch dfmt_outdent_attributes (Not yet implemented) | `true`, `false` | `true` | Decrease the indentation level of attributes dfmt_split_operator_at_line_end | `true`, `false` | `false` | Place operators on the end of the previous line when splitting lines dfmt_space_after_cast | `true`, `false` | `false` | Insert space after the closing paren of a `cast` expression dfmt_space_after_keywords (Not yet implemented) | `true`, `false` | `true` | Insert space after `if`, `while`, `foreach`, etc, and before the `(` +dfmt_selective_import_space | `true`, `false` | `true` | Insert space after the module name and before the `:` for selective imports +dfmt_compact_labeled_statements | `true`, `false` | `true` | Place labels on the same line as the labeled `switch`, `for`, `foreach`, or `while` statement ## Terminology * Braces - `{` and `}` diff --git a/dub.json b/dub.json index f801a6d..64a709c 100644 --- a/dub.json +++ b/dub.json @@ -1,7 +1,7 @@ { "name": "dfmt", "description": "Dfmt is a formatter for D source code", - "version": "0.3.5", + "version": "0.4.0-beta", "targetType": "executable", "license": "BSL-1.0", "dependencies": { diff --git a/src/dfmt/config.d b/src/dfmt/config.d index c54f0c1..f83f656 100644 --- a/src/dfmt/config.d +++ b/src/dfmt/config.d @@ -29,8 +29,6 @@ struct Config /// OptionalBoolean dfmt_outdent_attributes; /// - OptionalBoolean dfmt_outdent_labels; - /// int dfmt_soft_max_line_length = -1; /// OptionalBoolean dfmt_space_after_cast; @@ -38,6 +36,10 @@ struct Config OptionalBoolean dfmt_space_after_keywords; /// OptionalBoolean dfmt_split_operator_at_line_end; + /// + OptionalBoolean dfmt_selective_import_space; + /// + OptionalBoolean dfmt_compact_labeled_statements; mixin StandardEditorConfigFields; @@ -57,11 +59,12 @@ struct Config dfmt_align_switch_statements = OptionalBoolean.t; dfmt_brace_style = BraceStyle.allman; dfmt_outdent_attributes = OptionalBoolean.t; - dfmt_outdent_labels = OptionalBoolean.t; dfmt_soft_max_line_length = 80; dfmt_space_after_cast = OptionalBoolean.t; dfmt_space_after_keywords = OptionalBoolean.t; dfmt_split_operator_at_line_end = OptionalBoolean.f; + dfmt_selective_import_space = OptionalBoolean.t; + dfmt_compact_labeled_statements = OptionalBoolean.t; } /** @@ -74,7 +77,8 @@ struct Config if (dfmt_soft_max_line_length > max_line_length) { - stderr.writeln("Column hard limit must be greater than or equal to column soft limit"); + stderr.writefln("Column hard limit (%d) must be greater than or equal to column soft limit (%d)", + max_line_length, dfmt_soft_max_line_length); return false; } return true; diff --git a/src/dfmt/formatter.d b/src/dfmt/formatter.d index 312d55e..d4f228c 100644 --- a/src/dfmt/formatter.d +++ b/src/dfmt/formatter.d @@ -32,7 +32,7 @@ void format(OutputRange)(string source_desc, ubyte[] buffer, OutputRange output, astInformation.cleanup(); auto tokens = byToken(buffer, config, &cache).array(); auto depths = generateDepthInfo(tokens); - auto tokenFormatter = TokenFormatter!OutputRange(tokens, depths, output, + auto tokenFormatter = TokenFormatter!OutputRange(buffer, tokens, depths, output, &astInformation, formatterConfig); tokenFormatter.format(); } @@ -74,9 +74,10 @@ struct TokenFormatter(OutputRange) * astInformation = information about the AST used to inform formatting * decisions. */ - this(const(Token)[] tokens, immutable short[] depths, OutputRange output, - ASTInformation* astInformation, Config* config) + this(const ubyte[] rawSource, const(Token)[] tokens, immutable short[] depths, + OutputRange output, ASTInformation* astInformation, Config* config) { + this.rawSource = rawSource; this.tokens = tokens; this.depths = depths; this.output = output; @@ -105,6 +106,9 @@ private: /// Output to write output to OutputRange output; + /// Used for skipping parts of the file with `dfmt off` and `dfmt on` comments + const ubyte[] rawSource; + /// Tokens being formatted const Token[] tokens; @@ -234,8 +238,43 @@ private: writeToken(); } + string commentText(size_t i) + { + import std.string : strip; + assert(tokens[i].type == tok!"comment"); + string commentText = tokens[i].text; + if (commentText[0 ..2] == "//") + commentText = commentText[2 .. $]; + else + commentText = commentText[2 .. $ - 2]; + return commentText.strip(); + } + + void skipFormatting() + { + size_t dfmtOff = index; + size_t dfmtOn = index; + foreach (i; dfmtOff + 1.. tokens.length) + { + dfmtOn = i; + if (tokens[i].type != tok!"comment") + continue; + immutable string commentText = commentText(i); + if (commentText == "dfmt on") + break; + } + write(cast(string) rawSource[tokens[dfmtOff].index .. tokens[dfmtOn].index]); + index = dfmtOn; + } + void formatComment() { + if (commentText(index) == "dfmt off") + { + skipFormatting(); + return; + } + immutable bool currIsSlashSlash = tokens[index].text[0 .. 2] == "//"; immutable prevTokenEndLine = index == 0 ? size_t.max : tokenEndLine(tokens[index - 1]); immutable size_t currTokenLine = tokens[index].line; @@ -279,7 +318,7 @@ private: void formatModuleOrImport() { - auto t = current.type; + immutable t = current.type; writeToken(); if (currentIs(tok!"(")) { @@ -302,7 +341,7 @@ private: break; } else if (t == tok!"import" && !currentIs(tok!"import") && !currentIs(tok!"}") - && !(currentIs(tok!"public") && peekIs(tok!"import"))) + && !(currentIs(tok!"public") && peekIs(tok!"import"))) { simpleNewline(); currentLineLength = 0; @@ -313,6 +352,13 @@ private: newline(); break; } + else if (currentIs(tok!":")) + { + if (config.dfmt_selective_import_space) + write(" "); + writeToken(); + write(" "); + } else if (currentIs(tok!",")) { // compute length until next ',' or ';' @@ -418,12 +464,22 @@ private: void formatColon() { - if (astInformation.caseEndLocations.canFindIndex(current.index) - || astInformation.attributeDeclarationLines.canFindIndex(current.line)) + import dfmt.editorconfig : OptionalBoolean; + + immutable bool isCase = astInformation.caseEndLocations.canFindIndex(current.index); + immutable bool isAttribute = astInformation.attributeDeclarationLines.canFindIndex(current.line); + if (isCase || isAttribute) { writeToken(); if (!currentIs(tok!"{")) + { + if (isCase && !indents.topIs(tok!"case") && config.dfmt_align_switch_statements == OptionalBoolean.f) + indents.push(tok!"case"); + else if (isAttribute && !indents.topIs(tok!"@") && config.dfmt_outdent_attributes == OptionalBoolean.f) + indents.push(tok!"@"); newline(); + } + } else if (peekBackIs(tok!"identifier") && (peekBack2Is(tok!"{", true) || peekBack2Is(tok!"}", true) || peekBack2Is(tok!";", true) @@ -441,7 +497,10 @@ private: else if (isBlockHeader(1) && !peekIs(tok!"if")) { writeToken(); - write(" "); + if (config.dfmt_compact_labeled_statements) + write(" "); + else + newline(); } else if (linebreakHints.canFindIndex(index)) { @@ -492,7 +551,7 @@ private: { if (currentIs(tok!"{")) indents.popTempIndents(); - indentLevel = indents.indentSize; + indentLevel = indents.indentLevel; newline(); } } @@ -539,9 +598,9 @@ private: { indents.popWrapIndents(); if (indents.length && isTempIndent(indents.top)) - indentLevel = indents.indentSize - 1; + indentLevel = indents.indentLevel - 1; else - indentLevel = indents.indentSize; + indentLevel = indents.indentLevel; if (!peekBackIsSlashSlash()) { @@ -555,7 +614,7 @@ private: { writeToken(); indents.popTempIndents(); - indentLevel = indents.indentSize - 1; + indentLevel = indents.indentLevel - 1; } indents.push(tok!"{"); if (!currentIs(tok!"{")) @@ -629,7 +688,7 @@ private: || astInformation.conditionalWithElseLocations.canFindIndex(current.index); immutable bool c = b || astInformation.conditionalStatementLocations.canFindIndex(current.index); - immutable bool shouldPushIndent = c && !(currentIs(tok!"if") && indents.topIsWrap()); + immutable bool shouldPushIndent = c && !(currentIs(tok!"if") && indents.topIsWrap()); if (currentIs(tok!"out") && !peekBackIs(tok!"}")) newline(); if (shouldPushIndent) @@ -1015,7 +1074,6 @@ private: if (hasCurrent) { - bool switchLabel = false; if (currentIs(tok!"else")) { auto i = indents.indentToMostRecent(tok!"if"); @@ -1026,35 +1084,31 @@ private: } else if (currentIs(tok!"identifier") && peekIs(tok!":")) { - while ((peekBackIs(tok!"}", true) || peekBackIs(tok!";", true)) - && indents.length && isTempIndent(indents.top())) - { - indents.pop(); - } + if (peekBackIs(tok!"}", true) || peekBackIs(tok!";", true)) + indents.popTempIndents(); immutable l = indents.indentToMostRecent(tok!"switch"); - if (l != -1) - { + if (l != -1 && config.dfmt_align_switch_statements == OptionalBoolean.t) indentLevel = l; - switchLabel = true; - } - else if (!isBlockHeader(2) || peek2Is(tok!"if")) + else if (config.dfmt_compact_labeled_statements == OptionalBoolean.f + || !isBlockHeader(2) || peek2Is(tok!"if")) { immutable l2 = indents.indentToMostRecent(tok!"{"); - indentLevel = l2 == -1 ? indentLevel : l2; + indentLevel = l2 != -1 ? l2 : indents.indentLevel - 1; } else - indentLevel = indents.indentSize; + indentLevel = indents.indentLevel; } else if (currentIs(tok!"case") || currentIs(tok!"default")) { - while (indents.length && (peekBackIs(tok!"}", true) - || peekBackIs(tok!";", true)) && isTempIndent(indents.top())) + if (peekBackIs(tok!"}", true) || peekBackIs(tok!";", true)) { - indents.pop(); + indents.popTempIndents(); + if (indents.topIs(tok!"case")) + indents.pop(); } immutable l = indents.indentToMostRecent(tok!"switch"); if (l != -1) - indentLevel = l; + indentLevel = config.dfmt_align_switch_statements == OptionalBoolean.t ? l : indents.indentLevel; } else if (currentIs(tok!"{")) { @@ -1062,13 +1116,15 @@ private: if (peekBackIsSlashSlash()) { indents.popTempIndents(); - indentLevel = indents.indentSize; + indentLevel = indents.indentLevel; } } else if (currentIs(tok!"}")) { indents.popTempIndents(); - if (indents.top == tok!"{") + while (indents.topIs(tok!"case") || indents.topIs(tok!"@")) + indents.pop(); + if (indents.topIs(tok!"{")) { indentLevel = indents.indentToMostRecent(tok!"{"); indents.pop(); @@ -1085,22 +1141,30 @@ private: if (indents.topIs(tok!"]")) { indents.pop(); - indentLevel = indents.indentSize; + indentLevel = indents.indentLevel; } } else if (astInformation.attributeDeclarationLines.canFindIndex(current.line)) { - immutable l = indents.indentToMostRecent(tok!"{"); - if (l != -1) - indentLevel = l; + if (config.dfmt_outdent_attributes == OptionalBoolean.t) + { + immutable l = indents.indentToMostRecent(tok!"{"); + if (l != -1) + indentLevel = l; + } + else + { + if (indents.topIs(tok!"@")) + indents.pop(); + indentLevel = indents.indentLevel; + } } else { - while (indents.topIsTemp() && (peekBackIsOneOf(true, tok!"}", tok!";") && indents.top != tok!";")) - { + while (indents.topIsTemp() && (peekBackIsOneOf(true, tok!"}", tok!";") + && indents.top != tok!";")) indents.pop(); - } - indentLevel = indents.indentSize; + indentLevel = indents.indentLevel; } indent(); } diff --git a/src/dfmt/indentation.d b/src/dfmt/indentation.d index 2322a24..861c595 100644 --- a/src/dfmt/indentation.d +++ b/src/dfmt/indentation.d @@ -7,19 +7,33 @@ module dfmt.indentation; import std.d.lexer; +/** + * Returns: true if the given token type is a wrap indent type + */ bool isWrapIndent(IdType type) pure nothrow @nogc @safe { - return type != tok!"{" && type != tok!":" && type != tok!"]" && isOperator(type); + return type != tok!"{" && type != tok!"case" && type != tok!"@" + && type != tok!"]" && isOperator(type); } +/** + * Returns: true if the given token type is a wrap indent type + */ bool isTempIndent(IdType type) pure nothrow @nogc @safe { - return type != tok!"{"; + return type != tok!"{" && type != tok!"case" && type != tok!"@"; } +/** + * Stack for managing indent levels. + */ struct IndentStack { - int indentToMostRecent(IdType item) + /** + * Modifies the indent stack to match the state that it had at the most + * recent appearance of the given token type. + */ + int indentToMostRecent(IdType item) const { size_t i = index; while (true) @@ -47,44 +61,69 @@ struct IndentStack return tempIndentCount; } + /** + * Pushes the given indent type on to the stack. + */ void push(IdType item) pure nothrow { index = index == 255 ? index : index + 1; arr[index] = item; } + /** + * Pops the top indent from the stack. + */ void pop() pure nothrow { index = index == 0 ? index : index - 1; } + /** + * Pops all wrapping indents from the top of the stack. + */ void popWrapIndents() pure nothrow @safe @nogc { while (index > 0 && isWrapIndent(arr[index])) index--; } + /** + * Pops all temporary indents from the top of the stack. + */ void popTempIndents() pure nothrow @safe @nogc { while (index > 0 && isTempIndent(arr[index])) index--; } + /** + * Returns: `true` if the top of the indent stack is the given indent type. + */ bool topIs(IdType type) const pure nothrow @safe @nogc { return index > 0 && arr[index] == type; } + /** + * Returns: `true` if the top of the indent stack is a temporary indent + */ bool topIsTemp() { return index > 0 && index < arr.length && isTempIndent(arr[index]); } + /** + * Returns: `true` if the top of the indent stack is a wrapping indent + */ bool topIsWrap() { return index > 0 && index < arr.length && isWrapIndent(arr[index]); } + /** + * Returns: `true` if the top of the indent stack is one of the given token + * types. + */ bool topIsOneOf(IdType[] types...) const pure nothrow @safe @nogc { if (index <= 0) @@ -101,23 +140,9 @@ struct IndentStack return arr[index]; } - int indentSize(size_t k = size_t.max) const pure nothrow @safe @nogc + int indentLevel() const pure nothrow @safe @nogc @property { - if (index == 0) - return 0; - immutable size_t j = k == size_t.max ? index : k - 1; - int size = 0; - foreach (i; 1 .. j + 1) - { - if ((i + 1 <= index && arr[i] != tok!"]" && !isWrapIndent(arr[i]) - && isTempIndent(arr[i]) && (!isTempIndent(arr[i + 1]) - || arr[i + 1] == tok!"switch"))) - { - continue; - } - size++; - } - return size; + return indentSize(); } int length() const pure nothrow @property @@ -126,6 +151,31 @@ struct IndentStack } private: + size_t index; + IdType[256] arr; + + int indentSize(size_t k = size_t.max) const pure nothrow @safe @nogc + { + if (index == 0) + return 0; + immutable size_t j = k == size_t.max ? index : k - 1; + int size = 0; + foreach (i; 1 .. j + 1) + { + if (i + 1 <= index) + { + if (arr[i] == tok!"]") + continue; + immutable bool currentIsTemp = isTempIndent(arr[i]); + immutable bool nextIsTemp = isTempIndent(arr[i + 1]); + immutable bool nextIsSwitch = arr[i + 1] == tok!"switch"; + if (currentIsTemp && (!nextIsTemp || nextIsSwitch)) + continue; + } + size++; + } + return size; + } } diff --git a/src/dfmt/main.d b/src/dfmt/main.d index e44d998..923f99c 100644 --- a/src/dfmt/main.d +++ b/src/dfmt/main.d @@ -30,22 +30,26 @@ else import dfmt.editorconfig : OptionalBoolean; import std.exception : enforceEx; enforceEx!GetOptException(value == "true" || value == "false", "Invalid argument"); + immutable OptionalBoolean optVal = value == "true" ? OptionalBoolean.t : OptionalBoolean.f; switch (option) { case "align_switch_statements": - optConfig.dfmt_align_switch_statements = value == "true" ? OptionalBoolean.t : OptionalBoolean.f; + optConfig.dfmt_align_switch_statements = optVal; break; case "outdent_attributes": - optConfig.dfmt_outdent_attributes = value == "true" ? OptionalBoolean.t : OptionalBoolean.f; - break; - case "outdent_labels": - optConfig.dfmt_outdent_labels = value == "true" ? OptionalBoolean.t : OptionalBoolean.f; + optConfig.dfmt_outdent_attributes = optVal; break; case "space_after_cast": - optConfig.dfmt_space_after_cast = value == "true" ? OptionalBoolean.t : OptionalBoolean.f; + optConfig.dfmt_space_after_cast = optVal; break; case "split_operator_at_line_end": - optConfig.dfmt_split_operator_at_line_end = value == "true" ? OptionalBoolean.t : OptionalBoolean.f; + optConfig.dfmt_split_operator_at_line_end = optVal; + break; + case "selective_import_space": + optConfig.dfmt_selective_import_space = optVal; + break; + case "compact_labeled_statements": + optConfig.dfmt_compact_labeled_statements = optVal; break; default: assert(false, "Invalid command-line switch"); } @@ -64,9 +68,10 @@ else "max_line_length", &optConfig.max_line_length, "soft_max_line_length", &optConfig.dfmt_soft_max_line_length, "outdent_attributes", &handleBooleans, - "outdent_labels", &handleBooleans, "space_after_cast", &handleBooleans, + "selective_import_space", &handleBooleans, "split_operator_at_line_end", &handleBooleans, + "compact_labeled_statements", &handleBooleans, "tab_width", &optConfig.tab_width); } catch (GetOptException e) @@ -144,7 +149,7 @@ else private void printHelp() { - writeln(`dfmt 0.3.6 + writeln(`dfmt 0.4.0-beta Options: --help | -h Print this help message @@ -161,9 +166,10 @@ Formatting Options: --soft_max_line_length --max_line_length --outdent_attributes - --outdent_labels --space_after_cast - --split_operator_at_line_end`); + --selective_import_space + --split_operator_at_line_end + --compact_labeled_statements`); } private string createFilePath(bool readFromStdin, string fileName) diff --git a/tests/allman/issue0076.d.ref b/tests/allman/issue0076.d.ref new file mode 100644 index 0000000..dbe6f3a --- /dev/null +++ b/tests/allman/issue0076.d.ref @@ -0,0 +1,7 @@ +unittest +{ +Label: + while (1) + { + } +} diff --git a/tests/allman/issue0097.d.ref b/tests/allman/issue0097.d.ref new file mode 100644 index 0000000..632cf84 --- /dev/null +++ b/tests/allman/issue0097.d.ref @@ -0,0 +1,42 @@ +unittest +{ + switch (x) + { + case 0: + version (none) + { + // Comment + case '\n': + break; + } + } +} + +unittest +{ + switch (x) + { + case 0: + { + Label: while (1) + { + } + break; + } + Label2: + doStuff(); + } +} + +unittest +{ + switch (a) + { + case a: + doStuff(); + doOtherStuff(); + break; + default: + break; + } +} diff --git a/tests/allman/issue0102.d.ref b/tests/allman/issue0102.d.ref new file mode 100644 index 0000000..8efd670 --- /dev/null +++ b/tests/allman/issue0102.d.ref @@ -0,0 +1 @@ +import std.stdio: stderr; diff --git a/tests/allman/issue0125.d.ref b/tests/allman/issue0125.d.ref new file mode 100644 index 0000000..ce47f77 --- /dev/null +++ b/tests/allman/issue0125.d.ref @@ -0,0 +1,11 @@ +void main(string[] args) +{ + // dfmt off + getopt(args, + "optionOne", &optionOne, + "optionTwo", &optionTwo, + "optionThree", &optionThree); + // dfmt on + + getopt(args, "optionOne", &optionOne, "optionTwo", &optionTwo, "optionThree", &optionThree); +} diff --git a/tests/allman/issue0130.d.ref b/tests/allman/issue0130.d.ref new file mode 100644 index 0000000..dcaa691 --- /dev/null +++ b/tests/allman/issue0130.d.ref @@ -0,0 +1,11 @@ +class SomeClass +{ + public: + int x; + int y; + private: + int z; +} + +public: + void doStuff(); diff --git a/tests/gen_expected.sh b/tests/gen_expected.sh index 30388cd..a5520f7 100755 --- a/tests/gen_expected.sh +++ b/tests/gen_expected.sh @@ -2,7 +2,7 @@ argsFile=$1.args if [ -e ${argsFile} ]; then args=$(cat ${argsFile}) fi -echo ${args} +echo "Args:" ${args} dfmt --brace_style=allman ${args} $1.d > allman/$1.d.ref dfmt --brace_style=otbs ${args} $1.d > otbs/$1.d.ref diff --git a/tests/issue0076.args b/tests/issue0076.args new file mode 100644 index 0000000..ea99284 --- /dev/null +++ b/tests/issue0076.args @@ -0,0 +1 @@ +--compact_labeled_statements=false diff --git a/tests/issue0076.d b/tests/issue0076.d new file mode 100644 index 0000000..7d4c840 --- /dev/null +++ b/tests/issue0076.d @@ -0,0 +1,7 @@ +unittest +{ +Label: + while (1) + { + } +} diff --git a/tests/issue0097.args b/tests/issue0097.args new file mode 100644 index 0000000..91e2439 --- /dev/null +++ b/tests/issue0097.args @@ -0,0 +1 @@ +--align_switch_statements=false diff --git a/tests/issue0097.d b/tests/issue0097.d new file mode 100644 index 0000000..bcb66db --- /dev/null +++ b/tests/issue0097.d @@ -0,0 +1,42 @@ +unittest +{ + switch (x) + { + case 0: + version (none) + { + // Comment + case '\n': + break; + } + } +} + +unittest +{ + switch (x) + { + case 0: + { + Label: while (1) + { + } + break; + } + Label2: + doStuff(); + } +} + +unittest +{ + switch (a) + { + case a: + doStuff(); + doOtherStuff(); + break; + default: + break; + } +} diff --git a/tests/issue0102.args b/tests/issue0102.args new file mode 100644 index 0000000..d31866f --- /dev/null +++ b/tests/issue0102.args @@ -0,0 +1 @@ +--selective_import_space=false diff --git a/tests/issue0102.d b/tests/issue0102.d new file mode 100644 index 0000000..6710f90 --- /dev/null +++ b/tests/issue0102.d @@ -0,0 +1 @@ +import std.stdio : stderr; diff --git a/tests/issue0125.d b/tests/issue0125.d new file mode 100644 index 0000000..ce47f77 --- /dev/null +++ b/tests/issue0125.d @@ -0,0 +1,11 @@ +void main(string[] args) +{ + // dfmt off + getopt(args, + "optionOne", &optionOne, + "optionTwo", &optionTwo, + "optionThree", &optionThree); + // dfmt on + + getopt(args, "optionOne", &optionOne, "optionTwo", &optionTwo, "optionThree", &optionThree); +} diff --git a/tests/issue0130.args b/tests/issue0130.args new file mode 100644 index 0000000..c73b709 --- /dev/null +++ b/tests/issue0130.args @@ -0,0 +1 @@ +--outdent_attributes=false diff --git a/tests/issue0130.d b/tests/issue0130.d new file mode 100644 index 0000000..09b70bd --- /dev/null +++ b/tests/issue0130.d @@ -0,0 +1,11 @@ +class SomeClass +{ + public: + int x; + int y; + private: + int z; +} + +public: + void doStuff(); diff --git a/tests/otbs/issue0076.d.ref b/tests/otbs/issue0076.d.ref new file mode 100644 index 0000000..9568ea5 --- /dev/null +++ b/tests/otbs/issue0076.d.ref @@ -0,0 +1,5 @@ +unittest { +Label: + while (1) { + } +} diff --git a/tests/otbs/issue0097.d.ref b/tests/otbs/issue0097.d.ref new file mode 100644 index 0000000..c43ea0d --- /dev/null +++ b/tests/otbs/issue0097.d.ref @@ -0,0 +1,33 @@ +unittest { + switch (x) { + case 0: + version (none) { + // Comment + case '\n': + break; + } + } +} + +unittest { + switch (x) { + case 0: { + Label: while (1) { + } + break; + } + Label2: + doStuff(); + } +} + +unittest { + switch (a) { + case a: + doStuff(); + doOtherStuff(); + break; + default: + break; + } +} diff --git a/tests/otbs/issue0102.d.ref b/tests/otbs/issue0102.d.ref new file mode 100644 index 0000000..8efd670 --- /dev/null +++ b/tests/otbs/issue0102.d.ref @@ -0,0 +1 @@ +import std.stdio: stderr; diff --git a/tests/otbs/issue0125.d.ref b/tests/otbs/issue0125.d.ref new file mode 100644 index 0000000..ddc369e --- /dev/null +++ b/tests/otbs/issue0125.d.ref @@ -0,0 +1,10 @@ +void main(string[] args) { + // dfmt off + getopt(args, + "optionOne", &optionOne, + "optionTwo", &optionTwo, + "optionThree", &optionThree); + // dfmt on + + getopt(args, "optionOne", &optionOne, "optionTwo", &optionTwo, "optionThree", &optionThree); +} diff --git a/tests/otbs/issue0130.d.ref b/tests/otbs/issue0130.d.ref new file mode 100644 index 0000000..616293a --- /dev/null +++ b/tests/otbs/issue0130.d.ref @@ -0,0 +1,10 @@ +class SomeClass { + public: + int x; + int y; + private: + int z; +} + +public: + void doStuff();