diff --git a/src/dfmt/ast_info.d b/src/dfmt/ast_info.d index 9a9c0f1..4703888 100644 --- a/src/dfmt/ast_info.d +++ b/src/dfmt/ast_info.d @@ -96,7 +96,8 @@ final class FormatVisitor : ASTVisitor auto condition = dec.compileCondition; if (condition.versionCondition !is null) { - astInformation.conditionalWithElseLocations ~= condition.versionCondition.versionIndex; + astInformation.conditionalWithElseLocations + ~= condition.versionCondition.versionIndex; } else if (condition.debugCondition !is null) { @@ -151,8 +152,10 @@ final class FormatVisitor : ASTVisitor { if (functionBody.blockStatement !is null) astInformation.doubleNewlineLocations ~= functionBody.blockStatement.endLocation; - if (functionBody.bodyStatement !is null && functionBody.bodyStatement.blockStatement !is null) - astInformation.doubleNewlineLocations ~= functionBody.bodyStatement.blockStatement.endLocation; + if (functionBody.bodyStatement !is null && functionBody.bodyStatement + .blockStatement !is null) + astInformation.doubleNewlineLocations + ~= functionBody.bodyStatement.blockStatement.endLocation; functionBody.accept(this); } @@ -203,8 +206,8 @@ final class FormatVisitor : ASTVisitor override void visit(const UnaryExpression unary) { if (unary.prefix.type == tok!"~" || unary.prefix.type == tok!"&" - || unary.prefix.type == tok!"*" || unary.prefix.type == tok!"+" - || unary.prefix.type == tok!"-") + || unary.prefix.type == tok!"*" + || unary.prefix.type == tok!"+" || unary.prefix.type == tok!"-") { astInformation.unaryLocations ~= unary.prefix.index; } diff --git a/src/dfmt/config.d b/src/dfmt/config.d index 060fdab..5158d44 100644 --- a/src/dfmt/config.d +++ b/src/dfmt/config.d @@ -21,7 +21,7 @@ enum BraceStyle enum TemplateConstraintStyle { - unspecified, + unspecified, conditional_newline_indent, conditional_newline, always_newline, @@ -54,7 +54,6 @@ struct Config mixin StandardEditorConfigFields; - /** * Initializes the standard EditorConfig properties with default values that * make sense for D code. @@ -89,8 +88,9 @@ struct Config if (dfmt_soft_max_line_length > max_line_length) { - 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); + 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/editorconfig.d b/src/dfmt/editorconfig.d index dbb828d..cee0000 100644 --- a/src/dfmt/editorconfig.d +++ b/src/dfmt/editorconfig.d @@ -73,11 +73,11 @@ mixin template StandardEditorConfigFields() auto thisN = &mixin("this." ~ N); static if (N == "pattern") continue; - else static if (is (T == enum)) + else static if (is(T == enum)) *thisN = otherN != T.unspecified ? otherN : *thisN; - else static if (is (T == int)) + else static if (is(T == int)) *thisN = otherN != -1 ? otherN : *thisN; - else static if (is (T == string)) + else static if (is(T == string)) *thisN = otherN !is null ? otherN : *thisN; else static assert(false); @@ -143,6 +143,7 @@ EC getConfigFor(EC)(string path) static if (__VERSION__ >= 2067) { import std.algorithm : each; + configs.each!(a => a.each!(b => result.merge(b, fileName)))(); } else diff --git a/src/dfmt/formatter.d b/src/dfmt/formatter.d index 842bec2..9fa70ad 100644 --- a/src/dfmt/formatter.d +++ b/src/dfmt/formatter.d @@ -15,7 +15,7 @@ import dfmt.wrapping; import std.array; void format(OutputRange)(string source_desc, ubyte[] buffer, OutputRange output, - Config* formatterConfig) + Config* formatterConfig) { LexerConfig config; config.stringBehavior = StringBehavior.source; @@ -33,7 +33,7 @@ void format(OutputRange)(string source_desc, ubyte[] buffer, OutputRange output, auto tokens = byToken(buffer, config, &cache).array(); auto depths = generateDepthInfo(tokens); auto tokenFormatter = TokenFormatter!OutputRange(buffer, tokens, depths, - output, &astInformation, formatterConfig); + output, &astInformation, formatterConfig); tokenFormatter.format(); } @@ -79,7 +79,7 @@ struct TokenFormatter(OutputRange) * decisions. */ this(const ubyte[] rawSource, const(Token)[] tokens, immutable short[] depths, - OutputRange output, ASTInformation* astInformation, Config* config) + OutputRange output, ASTInformation* astInformation, Config* config) { this.rawSource = rawSource; this.tokens = tokens; @@ -259,7 +259,7 @@ private: || isBasicType(current.type) || currentIs(tok!"@") || currentIs(tok!"if") || isNumberLiteral(tokens[index].type) || (inAsm - && peekBack2Is(tok!";") && currentIs(tok!"[")))) + && peekBack2Is(tok!";") && currentIs(tok!"[")))) { write(" "); } @@ -351,7 +351,7 @@ private: indents.pop(); else if (peekBack2Is(tok!",") && !indents.topIs(tok!",") && indents.indentToMostRecent(tok!"enum") == -1) - indents.push(tok!","); + pushWrapIndent(tok!","); newline(); } } @@ -387,7 +387,7 @@ private: break; else if (t == tok!"import" && !currentIs(tok!"import") && !currentIs(tok!"}") && !(currentIs(tok!"public") - && peekIs(tok!"import")) + && peekIs(tok!"import")) && !indents.topIsOneOf(tok!"if", tok!"debug", tok!"version")) { simpleNewline(); @@ -440,11 +440,12 @@ private: } body { - immutable p = tokens[index].type; + immutable p = current.type; regenLineBreakHintsIfNecessary(index); writeToken(); if (p == tok!"(") { + indents.push(p); spaceAfterParens = true; parenDepth++; } @@ -454,19 +455,18 @@ private: if (arrayInitializerStart) { // Use the close bracket as the indent token to distinguish - // the array initialiazer from an array index in the newling + // the array initialiazer from an array index in the newline // handling code pushWrapIndent(tok!"]"); newline(); immutable size_t j = expressionEndIndex(index); linebreakHints = chooseLineBreakTokens(index, tokens[index .. j], - depths[index .. j], config, currentLineLength, indentLevel); + depths[index .. j], config, currentLineLength, indentLevel); } else if (!currentIs(tok!")") && !currentIs(tok!"]") && (linebreakHints.canFindIndex(index - 1) - || (linebreakHints.length == 0 && currentLineLength > config.max_line_length))) + || (linebreakHints.length == 0 && currentLineLength > config.max_line_length))) { - pushWrapIndent(p); newline(); } } @@ -479,8 +479,9 @@ private: body { parenDepth--; - if (parenDepth == 0) - indents.popWrapIndents(); + indents.popWrapIndents(); + if (indents.topIs(tok!"(")) + indents.pop(); if (parenDepth == 0 && (peekIs(tok!"is") || peekIs(tok!"in") || peekIs(tok!"out") || peekIs(tok!"body"))) @@ -505,17 +506,13 @@ private: immutable l = currentLineLength + betweenParenLength(tokens[index + 1 .. $]); if (l > config.dfmt_soft_max_line_length) { - // The order of these two calls is intentional newline(); - pushWrapIndent(tok!"!"); } else write(" "); break; case always_newline: - // The order of these two calls is intentional newline(); - pushWrapIndent(tok!"!"); break; case conditional_newline_indent: immutable l = currentLineLength + betweenParenLength(tokens[index + 1 .. $]); @@ -688,7 +685,7 @@ private: a => tokenLength(a)).sum(); immutable bool multiline = l > config.dfmt_soft_max_line_length || tokens[index .. e].canFind!(a => a.type == tok!"comment" - || isBlockHeaderToken(a.type))(); + || isBlockHeaderToken(a.type))(); writeToken(); if (multiline) { @@ -801,6 +798,8 @@ private: void formatBlockHeader() { + if (indents.topIs(tok!"!")) + indents.pop(); immutable bool a = !currentIs(tok!"version") && !currentIs(tok!"debug"); immutable bool b = a || astInformation.conditionalWithElseLocations.canFindIndex(current.index); @@ -1150,10 +1149,10 @@ private: } else if (!peekIs(tok!"}") && (linebreakHints.canFind(index) || (linebreakHints.length == 0 - && currentLineLength > config.dfmt_soft_max_line_length))) + && currentLineLength > config.dfmt_soft_max_line_length))) { + pushWrapIndent(); writeToken(); - pushWrapIndent(tok!","); newline(); } else @@ -1172,7 +1171,7 @@ private: { immutable size_t j = expressionEndIndex(i); linebreakHints = chooseLineBreakTokens(i, tokens[i .. j], depths[i .. j], - config, currentLineLength, indentLevel); + config, currentLineLength, indentLevel); } void regenLineBreakHintsIfNecessary(immutable size_t i) @@ -1271,6 +1270,12 @@ private: indentLevel = config.dfmt_align_switch_statements == OptionalBoolean.t ? l : indents.indentLevel; } + else if (currentIs(tok!")")) + { + if (indents.topIs(tok!"(")) + indents.pop(); + indentLevel = indents.indentLevel; + } else if (currentIs(tok!"{")) { indents.popWrapIndents(); @@ -1292,7 +1297,7 @@ private: } while (sBraceDepth == 0 && indents.topIsTemp() && ((indents.top != tok!"if" - && indents.top != tok!"version") || !peekIs(tok!"else"))) + && indents.top != tok!"version") || !peekIs(tok!"else"))) { indents.pop(); } @@ -1378,7 +1383,7 @@ private: { if (currentLineLength >= config.dfmt_soft_max_line_length) { - pushWrapIndent(tok!";"); + pushWrapIndent(); writeToken(); newline(); } diff --git a/src/dfmt/globmatch_editorconfig.d b/src/dfmt/globmatch_editorconfig.d index f171c71..28d3e75 100644 --- a/src/dfmt/globmatch_editorconfig.d +++ b/src/dfmt/globmatch_editorconfig.d @@ -10,15 +10,15 @@ import std.path : filenameCharCmp, isDirSeparator; // From std.path with changes: // * changes meaning to match all characters except '/' // ** added to take over the old meaning of * -bool globMatchEditorConfig(CaseSensitive cs = CaseSensitive.osDefault, C, Range) -(Range path, const(C)[] pattern) -@safe pure nothrow -if (isForwardRange!Range && isSomeChar!(ElementEncodingType!Range) && - isSomeChar!C && is(Unqual!C == Unqual!(ElementEncodingType!Range))) +bool globMatchEditorConfig(CaseSensitive cs = CaseSensitive.osDefault, C, Range)( + Range path, const(C)[] pattern) @safe pure nothrow if (isForwardRange!Range + && isSomeChar!(ElementEncodingType!Range) && isSomeChar!C + && is(Unqual!C == Unqual!(ElementEncodingType!Range))) in { // Verify that pattern[] is valid import std.algorithm : balancedParens; + assert(balancedParens(pattern, '[', ']', 0)); assert(balancedParens(pattern, '{', '}', 0)); } @@ -29,11 +29,13 @@ body static if (RC.sizeof == 1 && isSomeString!Range) { import std.utf : byChar; + return globMatchEditorConfig!cs(path.byChar, pattern); } else static if (RC.sizeof == 2 && isSomeString!Range) { import std.utf : byWchar; + return globMatchEditorConfig!cs(path.byWchar, pattern); } else @@ -44,134 +46,131 @@ body const pc = pattern[pi]; switch (pc) { - case '*': - if (pi < pattern.length-1 && pattern[pi+1] == '*') + case '*': + if (pi < pattern.length - 1 && pattern[pi + 1] == '*') + { + if (pi + 2 == pattern.length) + return true; + for (; !path.empty; path.popFront()) { - if (pi + 2 == pattern.length) + auto p = path.save; + if (globMatchEditorConfig!(cs, C)(p, pattern[pi + 2 .. pattern.length])) return true; - for (; !path.empty; path.popFront()) + } + return false; + } + else + { + if (pi + 1 == pattern.length) + return true; + for (; !path.empty; path.popFront()) + { + auto p = path.save; + //if (p[0].to!dchar.isDirSeparator() && !pattern[pi+1].isDirSeparator()) + // return false; + if (globMatchEditorConfig!(cs, C)(p, pattern[pi + 1 .. pattern.length])) + return true; + if (p[0].to!dchar.isDirSeparator()) + return false; + } + return false; + } + case '?': + if (path.empty) + return false; + path.popFront(); + break; + + case '[': + if (path.empty) + return false; + auto nc = path.front; + path.popFront(); + auto not = false; + ++pi; + if (pattern[pi] == '!') + { + not = true; + ++pi; + } + auto anymatch = false; + while (1) + { + const pc2 = pattern[pi]; + if (pc2 == ']') + break; + if (!anymatch && (filenameCharCmp!cs(nc, pc2) == 0)) + anymatch = true; + ++pi; + } + if (anymatch == not) + return false; + break; + + case '{': + // find end of {} section + auto piRemain = pi; + for (; piRemain < pattern.length && pattern[piRemain] != '}'; ++piRemain) + { + } + + if (piRemain < pattern.length) + ++piRemain; + ++pi; + + while (pi < pattern.length) + { + const pi0 = pi; + C pc3 = pattern[pi]; + // find end of current alternative + for (; pi < pattern.length && pc3 != '}' && pc3 != ','; ++pi) + { + pc3 = pattern[pi]; + } + + auto p = path.save; + if (pi0 == pi) + { + if (globMatchEditorConfig!(cs, C)(p, pattern[piRemain .. $])) { - auto p = path.save; - if (globMatchEditorConfig!(cs, C)(p, - pattern[pi + 2 .. pattern.length])) - return true; + return true; } - return false; + ++pi; } else { - if (pi + 1 == pattern.length) - return true; - for (; !path.empty; path.popFront()) - { - auto p = path.save; - //if (p[0].to!dchar.isDirSeparator() && !pattern[pi+1].isDirSeparator()) - // return false; - if (globMatchEditorConfig!(cs, C)(p, - pattern[pi + 1 .. pattern.length])) - return true; - if (p[0].to!dchar.isDirSeparator()) - return false; - } - return false; - } - case '?': - if (path.empty) - return false; - path.popFront(); - break; - - case '[': - if (path.empty) - return false; - auto nc = path.front; - path.popFront(); - auto not = false; - ++pi; - if (pattern[pi] == '!') - { - not = true; - ++pi; - } - auto anymatch = false; - while (1) - { - const pc2 = pattern[pi]; - if (pc2 == ']') - break; - if (!anymatch && (filenameCharCmp!cs(nc, pc2) == 0)) - anymatch = true; - ++pi; - } - if (anymatch == not) - return false; - break; - - case '{': - // find end of {} section - auto piRemain = pi; - for (; piRemain < pattern.length - && pattern[piRemain] != '}'; ++piRemain) - { } - - if (piRemain < pattern.length) - ++piRemain; - ++pi; - - while (pi < pattern.length) - { - const pi0 = pi; - C pc3 = pattern[pi]; - // find end of current alternative - for (; pi < pattern.length && pc3 != '}' && pc3 != ','; ++pi) - { - pc3 = pattern[pi]; - } - - auto p = path.save; - if (pi0 == pi) - { - if (globMatchEditorConfig!(cs, C)(p, pattern[piRemain..$])) - { - return true; - } - ++pi; - } - else - { - /* Match for: + /* Match for: * pattern[pi0..pi-1] ~ pattern[piRemain..$] */ - if (pattmp.ptr == null) - // Allocate this only once per function invocation. - // Should do it with malloc/free, but that would make it impure. - pattmp = new C[pattern.length]; + if (pattmp.ptr == null) // Allocate this only once per function invocation. + // Should do it with malloc/free, but that would make it impure. + pattmp = new C[pattern.length]; - const len1 = pi - 1 - pi0; - pattmp[0 .. len1] = pattern[pi0 .. pi - 1]; + const len1 = pi - 1 - pi0; + pattmp[0 .. len1] = pattern[pi0 .. pi - 1]; - const len2 = pattern.length - piRemain; - pattmp[len1 .. len1 + len2] = pattern[piRemain .. $]; + const len2 = pattern.length - piRemain; + pattmp[len1 .. len1 + len2] = pattern[piRemain .. $]; - if (globMatchEditorConfig!(cs, C)(p, pattmp[0 .. len1 + len2])) - { - return true; - } - } - if (pc3 == '}') + if (globMatchEditorConfig!(cs, C)(p, pattmp[0 .. len1 + len2])) { - break; + return true; } } - return false; + if (pc3 == '}') + { + break; + } + } + return false; - default: - if (path.empty) - return false; - if (filenameCharCmp!cs(pc, path.front) != 0) - return false; - path.popFront(); - break; + default: + if (path.empty) + return false; + if (filenameCharCmp!cs(pc, path.front) != 0) + return false; + path.popFront(); + break; } } return path.empty; @@ -180,8 +179,8 @@ body unittest { - assert (globMatchEditorConfig!(CaseSensitive.no)("foo", "Foo")); - assert (!globMatchEditorConfig!(CaseSensitive.yes)("foo", "Foo")); + assert(globMatchEditorConfig!(CaseSensitive.no)("foo", "Foo")); + assert(!globMatchEditorConfig!(CaseSensitive.yes)("foo", "Foo")); assert(globMatchEditorConfig("foo", "*")); assert(globMatchEditorConfig("foo.bar"w, "*"w)); @@ -225,7 +224,7 @@ unittest assert(!globMatchEditorConfig("foo", "foob")); assert(!globMatchEditorConfig("foo", "foo{b}")); - assert (globMatchEditorConfig(`foo/foo\bar`, "f**b**r")); + assert(globMatchEditorConfig(`foo/foo\bar`, "f**b**r")); assert(globMatchEditorConfig("foo", "**")); assert(globMatchEditorConfig("foo/bar", "foo/bar")); assert(globMatchEditorConfig("foo/bar", "foo/*")); @@ -235,6 +234,5 @@ unittest assert(!globMatchEditorConfig("/foo/bar/gluu/sar.png", "*/sar.png")); assert(!globMatchEditorConfig("/foo/bar/gluu/sar.png", "*/*.png")); - static assert(globMatchEditorConfig("foo.bar", "[!gh]*bar")); } diff --git a/src/dfmt/indentation.d b/src/dfmt/indentation.d index 8211af2..1a4ab51 100644 --- a/src/dfmt/indentation.d +++ b/src/dfmt/indentation.d @@ -12,8 +12,8 @@ import dparse.lexer; */ bool isWrapIndent(IdType type) pure nothrow @nogc @safe { - return type != tok!"{" && type != tok!"case" && type != tok!"@" - && type != tok!"]" && isOperator(type); + return type != tok!"{" && type != tok!"case" && type != tok!"@" + && type != tok!"]" && type != tok!"(" && isOperator(type); } /** @@ -30,8 +30,7 @@ bool isTempIndent(IdType type) pure nothrow @nogc @safe struct IndentStack { /** - * Modifies the indent stack to match the state that it had at the most - * recent appearance of the given token type. + * Get the indent size at the most recent occurence of the given indent type */ int indentToMostRecent(IdType item) const { @@ -152,6 +151,15 @@ struct IndentStack return cast(int) index; } + /+void dump() + { + import std.stdio : stderr; + import dparse.lexer : str; + import std.algorithm.iteration : map; + + stderr.writefln("\033[31m%(%s %)\033[0m", arr[0 .. index].map!(a => str(a))); + }+/ + private: size_t index; @@ -164,18 +172,32 @@ private: return 0; immutable size_t j = k == size_t.max ? index : k; int size = 0; + int parenCount; foreach (i; 0 .. j) { if (i + 1 < index) { - if (arr[i] == tok!"]") + if (arr[i] == tok!"(") + parenCount++; + else 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)) + else + { + if (isWrapIndent(arr[i]) && parenCount > 0) + { + parenCount = 0; + continue; + } + parenCount = 0; + } + immutable currentIsNonWrapTemp = !isWrapIndent(arr[i]) && isTempIndent(arr[i]); + immutable nextIsParenOrSwitch = arr[i + 1] == tok!"(" + || arr[i + 1] == tok!"switch" || arr[i + 1] == tok!"{"; + if (currentIsNonWrapTemp && nextIsParenOrSwitch) continue; } + if (arr[i] == tok!"!") + size++; size++; } return size; diff --git a/src/dfmt/main.d b/src/dfmt/main.d index 00fbeca..afa75e4 100644 --- a/src/dfmt/main.d +++ b/src/dfmt/main.d @@ -5,7 +5,7 @@ module dfmt.main; -private enum VERSION = "0.4.5"; +private enum VERSION = "0.5.0"; version (NoMain) { @@ -32,8 +32,10 @@ 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; + immutable OptionalBoolean optVal = value == "true" ? OptionalBoolean.t + : OptionalBoolean.f; switch (option) { case "align_switch_statements": @@ -54,7 +56,8 @@ else case "compact_labeled_statements": optConfig.dfmt_compact_labeled_statements = optVal; break; - default: assert(false, "Invalid command-line switch"); + default: + assert(false, "Invalid command-line switch"); } } @@ -113,17 +116,19 @@ else return 1; File output = stdout; - version(Windows) + version (Windows) { // On Windows, set stdout to binary mode (needed for correct EOL writing) // See Phobos' stdio.File.rawWrite { import std.stdio; + immutable fd = fileno(output.getFP()); setmode(fd, _O_BINARY); - version(CRuntime_DigitalMars) + version (CRuntime_DigitalMars) { import core.atomic : atomicOp; + atomicOp!"&="(__fhnd_info[fd], ~FHND_TEXT); } } @@ -176,15 +181,18 @@ else } } -private string optionsToString(E)() if(is(E == enum)) { - import std.traits:EnumMembers; - import std.conv; - string result = "["; - foreach(i, option; EnumMembers!E) { - result ~= to!string(option) ~ "|"; - } - result = result[0 .. $-1] ~ "]"; - return result; +private string optionsToString(E)() if (is(E == enum)) +{ + import std.traits : EnumMembers; + import std.conv; + + string result = "["; + foreach (i, option; EnumMembers!E) + { + result ~= to!string(option) ~ "|"; + } + result = result[0 .. $ - 1] ~ "]"; + return result; } private void printHelp() @@ -199,11 +207,13 @@ Options: Formatting Options: --align_switch_statements - --brace_style `, optionsToString!(typeof(Config.dfmt_brace_style))(), ` + --brace_style `, + optionsToString!(typeof(Config.dfmt_brace_style))(), ` --end_of_line --help|h --indent_size - --indent_style|t `, optionsToString!(typeof(Config.indent_style))(), ` + --indent_style|t `, + optionsToString!(typeof(Config.indent_style))(), ` --soft_max_line_length --max_line_length --outdent_attributes @@ -211,7 +221,8 @@ Formatting Options: --selective_import_space --split_operator_at_line_end --compact_labeled_statements - --template_constraint_style `, optionsToString!(typeof(Config.dfmt_template_constraint_style))()); + --template_constraint_style `, + optionsToString!(typeof(Config.dfmt_template_constraint_style))()); } private string createFilePath(bool readFromStdin, string fileName) diff --git a/src/dfmt/tokens.d b/src/dfmt/tokens.d index 8ef032c..0a6f768 100644 --- a/src/dfmt/tokens.d +++ b/src/dfmt/tokens.d @@ -195,7 +195,6 @@ pure nothrow @safe @nogc unittest assert(breakCost(tok!".", u) != 1000); } - private string generateFixedLengthCases() { import std.algorithm : map; @@ -205,11 +204,11 @@ private string generateFixedLengthCases() assert(__ctfe); string[] spacedOperatorTokens = [ - ",", "..", "...", "/", "/=", "!", "!<", "!<=", "!<>", "!<>=", "!=", "!>", - "!>=", "%", "%=", "&", "&&", "&=", "*", "*=", "+", "+=", "-", "-=", ":", - ";", "<", "<<", "<<=", "<=", "<>", "<>=", "=", "==", "=>", ">", ">=", - ">>", ">>=", ">>>", ">>>=", "?", "@", "^", "^=", "^^", "^^=", "|", "|=", "||", - "~", "~=" + ",", "..", "...", "/", "/=", "!", "!<", "!<=", "!<>", "!<>=", "!=", + "!>", "!>=", "%", "%=", "&", "&&", "&=", "*", "*=", "+", "+=", "-", + "-=", ":", ";", "<", "<<", "<<=", "<=", "<>", "<>=", "=", "==", "=>", + ">", ">=", ">>", ">>=", ">>>", ">>>=", "?", "@", "^", "^=", "^^", + "^^=", "|", "|=", "||", "~", "~=" ]; immutable spacedOperatorTokenCases = spacedOperatorTokens.map!( a => format(`case tok!"%s": return %d + 1;`, a, a.length)).join("\n\t"); @@ -219,20 +218,21 @@ private string generateFixedLengthCases() "break", "byte", "case", "cast", "catch", "cdouble", "cent", "cfloat", "char", "class", "const", "continue", "creal", "dchar", "debug", "default", "delegate", "delete", "deprecated", "do", "double", "else", - "enum", "export", "extern", "false", "final", "finally", "float", "for", - "foreach", "foreach_reverse", "function", "goto", "idouble", "if", - "ifloat", "immutable", "import", "in", "inout", "int", "interface", - "invariant", "ireal", "is", "lazy", "long", "macro", "mixin", "module", - "new", "nothrow", "null", "out", "override", "package", "pragma", - "private", "protected", "public", "pure", "real", "ref", "return", - "scope", "shared", "short", "static", "struct", "super", "switch", - "synchronized", "template", "this", "throw", "true", "try", "typedef", - "typeid", "typeof", "ubyte", "ucent", "uint", "ulong", "union", - "unittest", "ushort", "version", "void", "volatile", "wchar", "while", - "with", "__DATE__", "__EOF__", "__FILE__", "__FUNCTION__", "__gshared", - "__LINE__", "__MODULE__", "__parameters", "__PRETTY_FUNCTION__", - "__TIME__", "__TIMESTAMP__", "__traits", "__vector", "__VENDOR__", - "__VERSION__", "$", "++", "--", ".", "[", "]", "(", ")", "{", "}" + "enum", "export", "extern", "false", "final", "finally", "float", + "for", "foreach", "foreach_reverse", "function", "goto", "idouble", + "if", "ifloat", "immutable", "import", "in", "inout", "int", + "interface", "invariant", "ireal", "is", "lazy", "long", "macro", + "mixin", "module", "new", "nothrow", "null", "out", "override", + "package", "pragma", "private", "protected", "public", "pure", "real", + "ref", "return", "scope", "shared", "short", "static", "struct", + "super", "switch", "synchronized", "template", "this", "throw", "true", + "try", "typedef", "typeid", "typeof", "ubyte", "ucent", "uint", + "ulong", "union", "unittest", "ushort", "version", "void", "volatile", + "wchar", "while", "with", "__DATE__", "__EOF__", "__FILE__", + "__FUNCTION__", "__gshared", "__LINE__", "__MODULE__", "__parameters", + "__PRETTY_FUNCTION__", "__TIME__", "__TIMESTAMP__", "__traits", + "__vector", "__VENDOR__", "__VERSION__", "$", "++", "--", ".", "[", + "]", "(", ")", "{", "}" ]; immutable identifierTokenCases = identifierTokens.map!( a => format(`case tok!"%s": return %d;`, a, a.length)).join("\n\t"); diff --git a/src/dfmt/wrapping.d b/src/dfmt/wrapping.d index a42c5da..52ca119 100644 --- a/src/dfmt/wrapping.d +++ b/src/dfmt/wrapping.d @@ -12,13 +12,14 @@ import dfmt.config; struct State { this(uint breaks, const Token[] tokens, immutable short[] depths, - const Config* config, int currentLineLength, int indentLevel) pure @safe + const Config* config, int currentLineLength, int indentLevel) pure @safe { import std.math : abs; import core.bitop : popcnt, bsf; import std.algorithm : min, map, sum; - immutable int remainingCharsMultiplier = config.max_line_length - config.dfmt_soft_max_line_length; + immutable int remainingCharsMultiplier = config.max_line_length + - config.dfmt_soft_max_line_length; immutable int newlinePenalty = remainingCharsMultiplier * 20; this.breaks = breaks; @@ -119,7 +120,7 @@ private: } size_t[] chooseLineBreakTokens(size_t index, const Token[] tokens, - immutable short[] depths, const Config* config, int currentLineLength, int indentLevel) + immutable short[] depths, const Config* config, int currentLineLength, int indentLevel) { import std.container.rbtree : RedBlackTree; import std.algorithm : filter, min; @@ -139,7 +140,7 @@ size_t[] chooseLineBreakTokens(size_t index, const Token[] tokens, immutable size_t tokensEnd = min(tokens.length, ALGORITHMIC_COMPLEXITY_SUCKS); auto open = new RedBlackTree!State; open.insert(State(0, tokens[0 .. tokensEnd], depths[0 .. tokensEnd], config, - currentLineLength, indentLevel)); + currentLineLength, indentLevel)); State lowest; while (!open.empty) { @@ -152,7 +153,8 @@ size_t[] chooseLineBreakTokens(size_t index, const Token[] tokens, return genRetVal(current.breaks, index); } validMoves!(typeof(open))(open, tokens[0 .. tokensEnd], - depths[0 .. tokensEnd], current.breaks, config, currentLineLength, indentLevel); + depths[0 .. tokensEnd], current.breaks, config, currentLineLength, + indentLevel); } if (open.empty) return genRetVal(lowest.breaks, index); @@ -162,8 +164,8 @@ size_t[] chooseLineBreakTokens(size_t index, const Token[] tokens, } void validMoves(OR)(auto ref OR output, const Token[] tokens, - immutable short[] depths, uint current, const Config* config, - int currentLineLength, int indentLevel) + immutable short[] depths, uint current, const Config* config, + int currentLineLength, int indentLevel) { import std.algorithm : sort, canFind; import std.array : insertInPlace; diff --git a/tests/allman/guessnumber.d.ref b/tests/allman/guessnumber.d.ref index b40b2e9..7855ed9 100644 --- a/tests/allman/guessnumber.d.ref +++ b/tests/allman/guessnumber.d.ref @@ -4,7 +4,7 @@ void main() { immutable interval = tuple(1, 100); writefln("Guess my target number that is between " ~ "%d and %d (inclusive).\n", - interval[]); + interval[]); immutable target = uniform!"[]"(interval[]); foreach (immutable i; sequence!q{n}) diff --git a/tests/allman/issue0047.d.ref b/tests/allman/issue0047.d.ref index 5e2aacd..9c257e5 100644 --- a/tests/allman/issue0047.d.ref +++ b/tests/allman/issue0047.d.ref @@ -6,7 +6,7 @@ unittest { auto dd = new DtorDeclaration(declLoc, Loc(), stc, Identifier.idPool("__fieldDtor")); auto dd = new DtorDeclaration(declLoc, Loc(), stc, extraParam, - midLengthFun(param, param), longIdentifier, Identifier.idPool("__fieldDtor")); + midLengthFun(param, param), longIdentifier, Identifier.idPool("__fieldDtor")); memcpy(&saved_idents, &rvl.saved_idents, (const(char)*).sizeof * VC_SAVED_IDENT_CNT); memcpy(&saved_types, &rvl.saved_types, (Type).sizeof * VC_SAVED_TYPE_CNT); @@ -16,8 +16,8 @@ unittest } void doStuff(const Token[] tokens, ref const State current, - const FormatterConfig* formatterConfig, int currentLineLength, int indentLevel, - int depth) + const FormatterConfig* formatterConfig, int currentLineLength, int indentLevel, + int depth) { return; } diff --git a/tests/allman/issue0111.d.ref b/tests/allman/issue0111.d.ref index 1bb4f3d..02e45b3 100644 --- a/tests/allman/issue0111.d.ref +++ b/tests/allman/issue0111.d.ref @@ -1,8 +1,9 @@ struct Test { this(string name, string[] aliasList, string briefDescription, string examDesc, - string onOpenDesc, string openDesc, string onCloseDesc, string closeDesc, - Flag!"canOpen" canOpen, Flag!"canClose" canClose, Flag!"isOpen" isOpen) + string onOpenDesc, string openDesc, string onCloseDesc, + string closeDesc, Flag!"canOpen" canOpen, Flag!"canClose" canClose, + Flag!"isOpen" isOpen) { } } diff --git a/tests/allman/issue0119.d.ref b/tests/allman/issue0119.d.ref index 30596c7..e337743 100644 --- a/tests/allman/issue0119.d.ref +++ b/tests/allman/issue0119.d.ref @@ -18,8 +18,8 @@ unittest callFunc({ int i = 10; foo(alpha_longVarName, bravo_longVarName, charlie_longVarName, - delta_longVarName, echo_longVarName, foxtrot_longVarName, - golf_longVarName, echo_longVarName); + delta_longVarName, echo_longVarName, foxtrot_longVarName, + golf_longVarName, echo_longVarName); doStuff(withThings, andOtherStuff); return i; }, more_stuff); diff --git a/tests/allman/issue0123.d.ref b/tests/allman/issue0123.d.ref index 33e1296..38b22f1 100644 --- a/tests/allman/issue0123.d.ref +++ b/tests/allman/issue0123.d.ref @@ -1,7 +1,7 @@ struct State { this(uint breaks, const Token[] tokens, immutable short[] depths, - const Config* config, int currentLineLength, int indentLevel) pure @safe + const Config* config, int currentLineLength, int indentLevel) pure @safe { } } diff --git a/tests/allman/issue0162.d.ref b/tests/allman/issue0162.d.ref index 6d43b37..cc9715b 100644 --- a/tests/allman/issue0162.d.ref +++ b/tests/allman/issue0162.d.ref @@ -1,8 +1,8 @@ void foo(int foobarbazqux1, /* */ - int foobarbazqux2, /* */ - int foobarbazqux3, /* */ - int foobarbazqux4, /* */ - int foobarbazqux5, /* */ - int foobarbazqux6, /* */ - int foobarbazqux7 /* */ + int foobarbazqux2, /* */ + int foobarbazqux3, /* */ + int foobarbazqux4, /* */ + int foobarbazqux5, /* */ + int foobarbazqux6, /* */ + int foobarbazqux7 /* */ ); diff --git a/tests/allman/issue0215a.d.ref b/tests/allman/issue0215a.d.ref index d0a9509..91d51e9 100644 --- a/tests/allman/issue0215a.d.ref +++ b/tests/allman/issue0215a.d.ref @@ -8,9 +8,9 @@ unittest { { bool anotherTemplatedFunction(One, Two, Three)(One alpha, Two bravo, - Three charlie, double delta) - if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo - && foxtrot && golf && hotel && india && juliet) + Three charlie, double delta) + if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo + && foxtrot && golf && hotel && india && juliet) { } diff --git a/tests/allman/issue0215b.d.ref b/tests/allman/issue0215b.d.ref index cdaabfd..8c46790 100644 --- a/tests/allman/issue0215b.d.ref +++ b/tests/allman/issue0215b.d.ref @@ -8,9 +8,9 @@ unittest { { bool anotherTemplatedFunction(One, Two, Three)(One alpha, Two bravo, - Three charlie, double delta) + Three charlie, double delta) if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo - && foxtrot && golf && hotel && india && juliet) + && foxtrot && golf && hotel && india && juliet) { } diff --git a/tests/allman/issue0215c.d.ref b/tests/allman/issue0215c.d.ref index 7b8bf0c..74c8f9a 100644 --- a/tests/allman/issue0215c.d.ref +++ b/tests/allman/issue0215c.d.ref @@ -9,9 +9,9 @@ unittest { { bool anotherTemplatedFunction(One, Two, Three)(One alpha, Two bravo, - Three charlie, double delta) + Three charlie, double delta) if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo - && foxtrot && golf && hotel && india && juliet) + && foxtrot && golf && hotel && india && juliet) { } diff --git a/tests/allman/issue0215d.d.ref b/tests/allman/issue0215d.d.ref index f43d9d5..747deff 100644 --- a/tests/allman/issue0215d.d.ref +++ b/tests/allman/issue0215d.d.ref @@ -1,7 +1,7 @@ module example; bool aTemplatedFunction(One)(One alpha) - if (isNumeric!One) + if (isNumeric!One) { } @@ -9,9 +9,9 @@ unittest { { bool anotherTemplatedFunction(One, Two, Three)(One alpha, Two bravo, - Three charlie, double delta) - if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo - && foxtrot && golf && hotel && india && juliet) + Three charlie, double delta) + if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo + && foxtrot && golf && hotel && india && juliet) { } diff --git a/tests/allman/longParamList.d.ref b/tests/allman/longParamList.d.ref index 8084436..9e99814 100644 --- a/tests/allman/longParamList.d.ref +++ b/tests/allman/longParamList.d.ref @@ -5,7 +5,7 @@ version (AArch64) public: double javaStyleFunctionName(double alpha, double bravo, double charlie, - double delta, double echo, double foxtrot, double golf, double hotel) + double delta, double echo, double foxtrot, double golf, double hotel) { if (alpha < beta && alpha > golf && hotel < alpha && bravo >= charlie && echo < delta) { diff --git a/tests/allman/parenIndent.d.ref b/tests/allman/parenIndent.d.ref new file mode 100644 index 0000000..03620de --- /dev/null +++ b/tests/allman/parenIndent.d.ref @@ -0,0 +1,36 @@ +unittest +{ + if (a) + { + while (sBraceDepth == 0 && indents.topIsTemp() + && ((indents.top != tok!"if" && indents.top != tok!"version") + || !peekIs(tok!"else"))) + { + a(); + } + } + + if (parenDepth == 0 && (peekIs(tok!"is") || peekIs(tok!"in") + || peekIs(tok!"out") || peekIs(tok!"body"))) + writeToken(); + + { + { + while (sBraceDepth == 0 && indents.topIsTemp() + && ((indents.top != tok!"if" + && indents.top != tok!"version") || !peekIs(tok!"else"))) + { + indents.pop(); + } + } + } + + { + while (sBraceDepth == 0 && indents.topIsTemp() + && ((indents.top != tok!"if" && indents.top != tok!"version") + || !peekIs(tok!"else"))) + { + indents.pop(); + } + } +} diff --git a/tests/allman/wrapping1.d.ref b/tests/allman/wrapping1.d.ref index a8c443e..320b14b 100644 --- a/tests/allman/wrapping1.d.ref +++ b/tests/allman/wrapping1.d.ref @@ -3,7 +3,7 @@ void main(string[] args) if (prevLocation != size_t.max) { addErrorMessage(line, column, KEY, - "Expression %s is true: already checked on line %d.".format( - expressions[prevLocation].formatted, expressions[prevLocation].line)); + "Expression %s is true: already checked on line %d.".format( + expressions[prevLocation].formatted, expressions[prevLocation].line)); } } diff --git a/tests/otbs/guessnumber.d.ref b/tests/otbs/guessnumber.d.ref index 76227d0..7cc250d 100644 --- a/tests/otbs/guessnumber.d.ref +++ b/tests/otbs/guessnumber.d.ref @@ -3,7 +3,7 @@ import std.stdio, std.random, std.typecons, std.conv, std.string, std.range; void main() { immutable interval = tuple(1, 100); writefln("Guess my target number that is between " ~ "%d and %d (inclusive).\n", - interval[]); + interval[]); immutable target = uniform!"[]"(interval[]); foreach (immutable i; sequence!q{n}) { diff --git a/tests/otbs/issue0047.d.ref b/tests/otbs/issue0047.d.ref index 9ee6c76..d23d7fd 100644 --- a/tests/otbs/issue0047.d.ref +++ b/tests/otbs/issue0047.d.ref @@ -5,7 +5,7 @@ unittest { { auto dd = new DtorDeclaration(declLoc, Loc(), stc, Identifier.idPool("__fieldDtor")); auto dd = new DtorDeclaration(declLoc, Loc(), stc, extraParam, - midLengthFun(param, param), longIdentifier, Identifier.idPool("__fieldDtor")); + midLengthFun(param, param), longIdentifier, Identifier.idPool("__fieldDtor")); memcpy(&saved_idents, &rvl.saved_idents, (const(char)*).sizeof * VC_SAVED_IDENT_CNT); memcpy(&saved_types, &rvl.saved_types, (Type).sizeof * VC_SAVED_TYPE_CNT); @@ -15,8 +15,8 @@ unittest { } void doStuff(const Token[] tokens, ref const State current, - const FormatterConfig* formatterConfig, int currentLineLength, int indentLevel, - int depth) { + const FormatterConfig* formatterConfig, int currentLineLength, int indentLevel, + int depth) { return; } diff --git a/tests/otbs/issue0111.d.ref b/tests/otbs/issue0111.d.ref index 4019687..934e844 100644 --- a/tests/otbs/issue0111.d.ref +++ b/tests/otbs/issue0111.d.ref @@ -1,6 +1,7 @@ struct Test { this(string name, string[] aliasList, string briefDescription, string examDesc, - string onOpenDesc, string openDesc, string onCloseDesc, string closeDesc, - Flag!"canOpen" canOpen, Flag!"canClose" canClose, Flag!"isOpen" isOpen) { + string onOpenDesc, string openDesc, string onCloseDesc, + string closeDesc, Flag!"canOpen" canOpen, Flag!"canClose" canClose, + Flag!"isOpen" isOpen) { } } diff --git a/tests/otbs/issue0119.d.ref b/tests/otbs/issue0119.d.ref index 1b961d8..e20016e 100644 --- a/tests/otbs/issue0119.d.ref +++ b/tests/otbs/issue0119.d.ref @@ -17,8 +17,8 @@ unittest { callFunc({ int i = 10; foo(alpha_longVarName, bravo_longVarName, charlie_longVarName, - delta_longVarName, echo_longVarName, foxtrot_longVarName, - golf_longVarName, echo_longVarName); + delta_longVarName, echo_longVarName, foxtrot_longVarName, + golf_longVarName, echo_longVarName); doStuff(withThings, andOtherStuff); return i; }, more_stuff); diff --git a/tests/otbs/issue0123.d.ref b/tests/otbs/issue0123.d.ref index 28bc34a..39b0b26 100644 --- a/tests/otbs/issue0123.d.ref +++ b/tests/otbs/issue0123.d.ref @@ -1,5 +1,5 @@ struct State { this(uint breaks, const Token[] tokens, immutable short[] depths, - const Config* config, int currentLineLength, int indentLevel) pure @safe { + const Config* config, int currentLineLength, int indentLevel) pure @safe { } } diff --git a/tests/otbs/issue0162.d.ref b/tests/otbs/issue0162.d.ref index 6d43b37..cc9715b 100644 --- a/tests/otbs/issue0162.d.ref +++ b/tests/otbs/issue0162.d.ref @@ -1,8 +1,8 @@ void foo(int foobarbazqux1, /* */ - int foobarbazqux2, /* */ - int foobarbazqux3, /* */ - int foobarbazqux4, /* */ - int foobarbazqux5, /* */ - int foobarbazqux6, /* */ - int foobarbazqux7 /* */ + int foobarbazqux2, /* */ + int foobarbazqux3, /* */ + int foobarbazqux4, /* */ + int foobarbazqux5, /* */ + int foobarbazqux6, /* */ + int foobarbazqux7 /* */ ); diff --git a/tests/otbs/issue0215a.d.ref b/tests/otbs/issue0215a.d.ref index 9daad81..8f62b4c 100644 --- a/tests/otbs/issue0215a.d.ref +++ b/tests/otbs/issue0215a.d.ref @@ -6,9 +6,9 @@ bool aTemplatedFunction(One)(One alpha) if (isNumeric!One) { unittest { { bool anotherTemplatedFunction(One, Two, Three)(One alpha, Two bravo, - Three charlie, double delta) - if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo - && foxtrot && golf && hotel && india && juliet) { + Three charlie, double delta) + if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo + && foxtrot && golf && hotel && india && juliet) { } } diff --git a/tests/otbs/issue0215b.d.ref b/tests/otbs/issue0215b.d.ref index af5a581..4989c5a 100644 --- a/tests/otbs/issue0215b.d.ref +++ b/tests/otbs/issue0215b.d.ref @@ -6,9 +6,9 @@ bool aTemplatedFunction(One)(One alpha) if (isNumeric!One) { unittest { { bool anotherTemplatedFunction(One, Two, Three)(One alpha, Two bravo, - Three charlie, double delta) + Three charlie, double delta) if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo - && foxtrot && golf && hotel && india && juliet) { + && foxtrot && golf && hotel && india && juliet) { } } diff --git a/tests/otbs/issue0215c.d.ref b/tests/otbs/issue0215c.d.ref index 702571e..bec24f7 100644 --- a/tests/otbs/issue0215c.d.ref +++ b/tests/otbs/issue0215c.d.ref @@ -7,9 +7,9 @@ if (isNumeric!One) { unittest { { bool anotherTemplatedFunction(One, Two, Three)(One alpha, Two bravo, - Three charlie, double delta) + Three charlie, double delta) if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo - && foxtrot && golf && hotel && india && juliet) { + && foxtrot && golf && hotel && india && juliet) { } } diff --git a/tests/otbs/issue0215d.d.ref b/tests/otbs/issue0215d.d.ref index 05c935d..8624b69 100644 --- a/tests/otbs/issue0215d.d.ref +++ b/tests/otbs/issue0215d.d.ref @@ -1,15 +1,15 @@ module example; bool aTemplatedFunction(One)(One alpha) - if (isNumeric!One) { + if (isNumeric!One) { } unittest { { bool anotherTemplatedFunction(One, Two, Three)(One alpha, Two bravo, - Three charlie, double delta) - if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo - && foxtrot && golf && hotel && india && juliet) { + Three charlie, double delta) + if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo + && foxtrot && golf && hotel && india && juliet) { } } diff --git a/tests/otbs/longParamList.d.ref b/tests/otbs/longParamList.d.ref index f511599..40d12ea 100644 --- a/tests/otbs/longParamList.d.ref +++ b/tests/otbs/longParamList.d.ref @@ -3,7 +3,7 @@ version (AArch64) { public: double javaStyleFunctionName(double alpha, double bravo, double charlie, - double delta, double echo, double foxtrot, double golf, double hotel) { + double delta, double echo, double foxtrot, double golf, double hotel) { if (alpha < beta && alpha > golf && hotel < alpha && bravo >= charlie && echo < delta) { if (alpha < beta && alpha > golf && hotel < alpha && bravo >= charlie && echo < delta) { if (alpha < beta && alpha > golf && hotel < alpha diff --git a/tests/otbs/parenIndent.d.ref b/tests/otbs/parenIndent.d.ref new file mode 100644 index 0000000..053585f --- /dev/null +++ b/tests/otbs/parenIndent.d.ref @@ -0,0 +1,31 @@ +unittest { + if (a) { + while (sBraceDepth == 0 && indents.topIsTemp() + && ((indents.top != tok!"if" && indents.top != tok!"version") + || !peekIs(tok!"else"))) { + a(); + } + } + + if (parenDepth == 0 && (peekIs(tok!"is") || peekIs(tok!"in") + || peekIs(tok!"out") || peekIs(tok!"body"))) + writeToken(); + + { + { + while (sBraceDepth == 0 && indents.topIsTemp() + && ((indents.top != tok!"if" + && indents.top != tok!"version") || !peekIs(tok!"else"))) { + indents.pop(); + } + } + } + + { + while (sBraceDepth == 0 && indents.topIsTemp() + && ((indents.top != tok!"if" && indents.top != tok!"version") + || !peekIs(tok!"else"))) { + indents.pop(); + } + } +} diff --git a/tests/otbs/wrapping1.d.ref b/tests/otbs/wrapping1.d.ref index 0455f31..1e3b571 100644 --- a/tests/otbs/wrapping1.d.ref +++ b/tests/otbs/wrapping1.d.ref @@ -1,7 +1,7 @@ void main(string[] args) { if (prevLocation != size_t.max) { addErrorMessage(line, column, KEY, - "Expression %s is true: already checked on line %d.".format( - expressions[prevLocation].formatted, expressions[prevLocation].line)); + "Expression %s is true: already checked on line %d.".format( + expressions[prevLocation].formatted, expressions[prevLocation].line)); } } diff --git a/tests/parenIndent.d b/tests/parenIndent.d new file mode 100644 index 0000000..cce0da9 --- /dev/null +++ b/tests/parenIndent.d @@ -0,0 +1,32 @@ +unittest +{ + if (a) + { + while (sBraceDepth == 0 && indents.topIsTemp() + && ((indents.top != tok!"if" && indents.top != tok!"version")|| !peekIs(tok!"else"))) + { + a(); + } + } + + if (parenDepth == 0 && (peekIs(tok!"is") || peekIs(tok!"in") + || peekIs(tok!"out") || peekIs(tok!"body"))) + writeToken(); + + { + { + while (sBraceDepth == 0 && indents.topIsTemp()&& ((indents.top != tok!"if" +&& indents.top != tok!"version") || !peekIs(tok!"else"))) + { + indents.pop(); + } + } + } + + { + while (sBraceDepth == 0 && indents.topIsTemp()&& ((indents.top != tok!"if" && indents.top != tok!"version") || !peekIs(tok!"else"))) + { + indents.pop(); + } + } +} diff --git a/tests/test b/tests/test deleted file mode 100755 index 7f11c5a..0000000 --- a/tests/test +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env bash -set -e - -for braceStyle in allman otbs -do - for source in *.d - do - echo "${source}.ref" "${braceStyle}/${source}.out" - argsFile=$(basename ${source} .d).args - if [ -e ${argsFile} ]; then - args=$(cat ${argsFile}) - else - args= - fi - ../bin/dfmt --brace_style=${braceStyle} ${args} "${source}" > "${braceStyle}/${source}.out" - diff -u "${braceStyle}/${source}.ref" "${braceStyle}/${source}.out" - done -done