Merge pull request #217 from Hackerpilot/indentation-madness

0.5.0 changes
This commit is contained in:
Brian Schott 2016-01-19 05:27:15 -08:00
commit 87c70065d5
37 changed files with 410 additions and 285 deletions

View File

@ -96,7 +96,8 @@ final class FormatVisitor : ASTVisitor
auto condition = dec.compileCondition; auto condition = dec.compileCondition;
if (condition.versionCondition !is null) if (condition.versionCondition !is null)
{ {
astInformation.conditionalWithElseLocations ~= condition.versionCondition.versionIndex; astInformation.conditionalWithElseLocations
~= condition.versionCondition.versionIndex;
} }
else if (condition.debugCondition !is null) else if (condition.debugCondition !is null)
{ {
@ -151,8 +152,10 @@ final class FormatVisitor : ASTVisitor
{ {
if (functionBody.blockStatement !is null) if (functionBody.blockStatement !is null)
astInformation.doubleNewlineLocations ~= functionBody.blockStatement.endLocation; astInformation.doubleNewlineLocations ~= functionBody.blockStatement.endLocation;
if (functionBody.bodyStatement !is null && functionBody.bodyStatement.blockStatement !is null) if (functionBody.bodyStatement !is null && functionBody.bodyStatement
astInformation.doubleNewlineLocations ~= functionBody.bodyStatement.blockStatement.endLocation; .blockStatement !is null)
astInformation.doubleNewlineLocations
~= functionBody.bodyStatement.blockStatement.endLocation;
functionBody.accept(this); functionBody.accept(this);
} }
@ -203,8 +206,8 @@ final class FormatVisitor : ASTVisitor
override void visit(const UnaryExpression unary) override void visit(const UnaryExpression unary)
{ {
if (unary.prefix.type == tok!"~" || unary.prefix.type == tok!"&" 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; astInformation.unaryLocations ~= unary.prefix.index;
} }

View File

@ -21,7 +21,7 @@ enum BraceStyle
enum TemplateConstraintStyle enum TemplateConstraintStyle
{ {
unspecified, unspecified,
conditional_newline_indent, conditional_newline_indent,
conditional_newline, conditional_newline,
always_newline, always_newline,
@ -54,7 +54,6 @@ struct Config
mixin StandardEditorConfigFields; mixin StandardEditorConfigFields;
/** /**
* Initializes the standard EditorConfig properties with default values that * Initializes the standard EditorConfig properties with default values that
* make sense for D code. * make sense for D code.
@ -89,8 +88,9 @@ struct Config
if (dfmt_soft_max_line_length > max_line_length) 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)", stderr.writefln(
max_line_length, dfmt_soft_max_line_length); "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 false;
} }
return true; return true;

View File

@ -73,11 +73,11 @@ mixin template StandardEditorConfigFields()
auto thisN = &mixin("this." ~ N); auto thisN = &mixin("this." ~ N);
static if (N == "pattern") static if (N == "pattern")
continue; continue;
else static if (is (T == enum)) else static if (is(T == enum))
*thisN = otherN != T.unspecified ? otherN : *thisN; *thisN = otherN != T.unspecified ? otherN : *thisN;
else static if (is (T == int)) else static if (is(T == int))
*thisN = otherN != -1 ? otherN : *thisN; *thisN = otherN != -1 ? otherN : *thisN;
else static if (is (T == string)) else static if (is(T == string))
*thisN = otherN !is null ? otherN : *thisN; *thisN = otherN !is null ? otherN : *thisN;
else else
static assert(false); static assert(false);
@ -143,6 +143,7 @@ EC getConfigFor(EC)(string path)
static if (__VERSION__ >= 2067) static if (__VERSION__ >= 2067)
{ {
import std.algorithm : each; import std.algorithm : each;
configs.each!(a => a.each!(b => result.merge(b, fileName)))(); configs.each!(a => a.each!(b => result.merge(b, fileName)))();
} }
else else

View File

@ -15,7 +15,7 @@ import dfmt.wrapping;
import std.array; import std.array;
void format(OutputRange)(string source_desc, ubyte[] buffer, OutputRange output, void format(OutputRange)(string source_desc, ubyte[] buffer, OutputRange output,
Config* formatterConfig) Config* formatterConfig)
{ {
LexerConfig config; LexerConfig config;
config.stringBehavior = StringBehavior.source; 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 tokens = byToken(buffer, config, &cache).array();
auto depths = generateDepthInfo(tokens); auto depths = generateDepthInfo(tokens);
auto tokenFormatter = TokenFormatter!OutputRange(buffer, tokens, depths, auto tokenFormatter = TokenFormatter!OutputRange(buffer, tokens, depths,
output, &astInformation, formatterConfig); output, &astInformation, formatterConfig);
tokenFormatter.format(); tokenFormatter.format();
} }
@ -79,7 +79,7 @@ struct TokenFormatter(OutputRange)
* decisions. * decisions.
*/ */
this(const ubyte[] rawSource, const(Token)[] tokens, immutable short[] depths, 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.rawSource = rawSource;
this.tokens = tokens; this.tokens = tokens;
@ -259,7 +259,7 @@ private:
|| isBasicType(current.type) || currentIs(tok!"@") || isBasicType(current.type) || currentIs(tok!"@")
|| currentIs(tok!"if") || currentIs(tok!"if")
|| isNumberLiteral(tokens[index].type) || (inAsm || isNumberLiteral(tokens[index].type) || (inAsm
&& peekBack2Is(tok!";") && currentIs(tok!"[")))) && peekBack2Is(tok!";") && currentIs(tok!"["))))
{ {
write(" "); write(" ");
} }
@ -351,7 +351,7 @@ private:
indents.pop(); indents.pop();
else if (peekBack2Is(tok!",") && !indents.topIs(tok!",") else if (peekBack2Is(tok!",") && !indents.topIs(tok!",")
&& indents.indentToMostRecent(tok!"enum") == -1) && indents.indentToMostRecent(tok!"enum") == -1)
indents.push(tok!","); pushWrapIndent(tok!",");
newline(); newline();
} }
} }
@ -387,7 +387,7 @@ private:
break; break;
else if (t == tok!"import" && !currentIs(tok!"import") else if (t == tok!"import" && !currentIs(tok!"import")
&& !currentIs(tok!"}") && !(currentIs(tok!"public") && !currentIs(tok!"}") && !(currentIs(tok!"public")
&& peekIs(tok!"import")) && peekIs(tok!"import"))
&& !indents.topIsOneOf(tok!"if", tok!"debug", tok!"version")) && !indents.topIsOneOf(tok!"if", tok!"debug", tok!"version"))
{ {
simpleNewline(); simpleNewline();
@ -440,11 +440,12 @@ private:
} }
body body
{ {
immutable p = tokens[index].type; immutable p = current.type;
regenLineBreakHintsIfNecessary(index); regenLineBreakHintsIfNecessary(index);
writeToken(); writeToken();
if (p == tok!"(") if (p == tok!"(")
{ {
indents.push(p);
spaceAfterParens = true; spaceAfterParens = true;
parenDepth++; parenDepth++;
} }
@ -454,19 +455,18 @@ private:
if (arrayInitializerStart) if (arrayInitializerStart)
{ {
// Use the close bracket as the indent token to distinguish // 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 // handling code
pushWrapIndent(tok!"]"); pushWrapIndent(tok!"]");
newline(); newline();
immutable size_t j = expressionEndIndex(index); immutable size_t j = expressionEndIndex(index);
linebreakHints = chooseLineBreakTokens(index, tokens[index .. j], linebreakHints = chooseLineBreakTokens(index, tokens[index .. j],
depths[index .. j], config, currentLineLength, indentLevel); depths[index .. j], config, currentLineLength, indentLevel);
} }
else if (!currentIs(tok!")") && !currentIs(tok!"]") else if (!currentIs(tok!")") && !currentIs(tok!"]")
&& (linebreakHints.canFindIndex(index - 1) && (linebreakHints.canFindIndex(index - 1)
|| (linebreakHints.length == 0 && currentLineLength > config.max_line_length))) || (linebreakHints.length == 0 && currentLineLength > config.max_line_length)))
{ {
pushWrapIndent(p);
newline(); newline();
} }
} }
@ -479,8 +479,9 @@ private:
body body
{ {
parenDepth--; parenDepth--;
if (parenDepth == 0) indents.popWrapIndents();
indents.popWrapIndents(); if (indents.topIs(tok!"("))
indents.pop();
if (parenDepth == 0 && (peekIs(tok!"is") || peekIs(tok!"in") if (parenDepth == 0 && (peekIs(tok!"is") || peekIs(tok!"in")
|| peekIs(tok!"out") || peekIs(tok!"body"))) || peekIs(tok!"out") || peekIs(tok!"body")))
@ -505,17 +506,13 @@ private:
immutable l = currentLineLength + betweenParenLength(tokens[index + 1 .. $]); immutable l = currentLineLength + betweenParenLength(tokens[index + 1 .. $]);
if (l > config.dfmt_soft_max_line_length) if (l > config.dfmt_soft_max_line_length)
{ {
// The order of these two calls is intentional
newline(); newline();
pushWrapIndent(tok!"!");
} }
else else
write(" "); write(" ");
break; break;
case always_newline: case always_newline:
// The order of these two calls is intentional
newline(); newline();
pushWrapIndent(tok!"!");
break; break;
case conditional_newline_indent: case conditional_newline_indent:
immutable l = currentLineLength + betweenParenLength(tokens[index + 1 .. $]); immutable l = currentLineLength + betweenParenLength(tokens[index + 1 .. $]);
@ -688,7 +685,7 @@ private:
a => tokenLength(a)).sum(); a => tokenLength(a)).sum();
immutable bool multiline = l > config.dfmt_soft_max_line_length immutable bool multiline = l > config.dfmt_soft_max_line_length
|| tokens[index .. e].canFind!(a => a.type == tok!"comment" || tokens[index .. e].canFind!(a => a.type == tok!"comment"
|| isBlockHeaderToken(a.type))(); || isBlockHeaderToken(a.type))();
writeToken(); writeToken();
if (multiline) if (multiline)
{ {
@ -801,6 +798,8 @@ private:
void formatBlockHeader() void formatBlockHeader()
{ {
if (indents.topIs(tok!"!"))
indents.pop();
immutable bool a = !currentIs(tok!"version") && !currentIs(tok!"debug"); immutable bool a = !currentIs(tok!"version") && !currentIs(tok!"debug");
immutable bool b = a immutable bool b = a
|| astInformation.conditionalWithElseLocations.canFindIndex(current.index); || astInformation.conditionalWithElseLocations.canFindIndex(current.index);
@ -1150,10 +1149,10 @@ private:
} }
else if (!peekIs(tok!"}") && (linebreakHints.canFind(index) else if (!peekIs(tok!"}") && (linebreakHints.canFind(index)
|| (linebreakHints.length == 0 || (linebreakHints.length == 0
&& currentLineLength > config.dfmt_soft_max_line_length))) && currentLineLength > config.dfmt_soft_max_line_length)))
{ {
pushWrapIndent();
writeToken(); writeToken();
pushWrapIndent(tok!",");
newline(); newline();
} }
else else
@ -1172,7 +1171,7 @@ private:
{ {
immutable size_t j = expressionEndIndex(i); immutable size_t j = expressionEndIndex(i);
linebreakHints = chooseLineBreakTokens(i, tokens[i .. j], depths[i .. j], linebreakHints = chooseLineBreakTokens(i, tokens[i .. j], depths[i .. j],
config, currentLineLength, indentLevel); config, currentLineLength, indentLevel);
} }
void regenLineBreakHintsIfNecessary(immutable size_t i) void regenLineBreakHintsIfNecessary(immutable size_t i)
@ -1271,6 +1270,12 @@ private:
indentLevel = config.dfmt_align_switch_statements indentLevel = config.dfmt_align_switch_statements
== OptionalBoolean.t ? l : indents.indentLevel; == OptionalBoolean.t ? l : indents.indentLevel;
} }
else if (currentIs(tok!")"))
{
if (indents.topIs(tok!"("))
indents.pop();
indentLevel = indents.indentLevel;
}
else if (currentIs(tok!"{")) else if (currentIs(tok!"{"))
{ {
indents.popWrapIndents(); indents.popWrapIndents();
@ -1292,7 +1297,7 @@ private:
} }
while (sBraceDepth == 0 && indents.topIsTemp() while (sBraceDepth == 0 && indents.topIsTemp()
&& ((indents.top != tok!"if" && ((indents.top != tok!"if"
&& indents.top != tok!"version") || !peekIs(tok!"else"))) && indents.top != tok!"version") || !peekIs(tok!"else")))
{ {
indents.pop(); indents.pop();
} }
@ -1378,7 +1383,7 @@ private:
{ {
if (currentLineLength >= config.dfmt_soft_max_line_length) if (currentLineLength >= config.dfmt_soft_max_line_length)
{ {
pushWrapIndent(tok!";"); pushWrapIndent();
writeToken(); writeToken();
newline(); newline();
} }

View File

@ -10,15 +10,15 @@ import std.path : filenameCharCmp, isDirSeparator;
// From std.path with changes: // From std.path with changes:
// * changes meaning to match all characters except '/' // * changes meaning to match all characters except '/'
// ** added to take over the old meaning of * // ** added to take over the old meaning of *
bool globMatchEditorConfig(CaseSensitive cs = CaseSensitive.osDefault, C, Range) bool globMatchEditorConfig(CaseSensitive cs = CaseSensitive.osDefault, C, Range)(
(Range path, const(C)[] pattern) Range path, const(C)[] pattern) @safe pure nothrow if (isForwardRange!Range
@safe pure nothrow && isSomeChar!(ElementEncodingType!Range) && isSomeChar!C
if (isForwardRange!Range && isSomeChar!(ElementEncodingType!Range) && && is(Unqual!C == Unqual!(ElementEncodingType!Range)))
isSomeChar!C && is(Unqual!C == Unqual!(ElementEncodingType!Range)))
in in
{ {
// Verify that pattern[] is valid // Verify that pattern[] is valid
import std.algorithm : balancedParens; import std.algorithm : balancedParens;
assert(balancedParens(pattern, '[', ']', 0)); assert(balancedParens(pattern, '[', ']', 0));
assert(balancedParens(pattern, '{', '}', 0)); assert(balancedParens(pattern, '{', '}', 0));
} }
@ -29,11 +29,13 @@ body
static if (RC.sizeof == 1 && isSomeString!Range) static if (RC.sizeof == 1 && isSomeString!Range)
{ {
import std.utf : byChar; import std.utf : byChar;
return globMatchEditorConfig!cs(path.byChar, pattern); return globMatchEditorConfig!cs(path.byChar, pattern);
} }
else static if (RC.sizeof == 2 && isSomeString!Range) else static if (RC.sizeof == 2 && isSomeString!Range)
{ {
import std.utf : byWchar; import std.utf : byWchar;
return globMatchEditorConfig!cs(path.byWchar, pattern); return globMatchEditorConfig!cs(path.byWchar, pattern);
} }
else else
@ -44,134 +46,131 @@ body
const pc = pattern[pi]; const pc = pattern[pi];
switch (pc) switch (pc)
{ {
case '*': case '*':
if (pi < pattern.length-1 && pattern[pi+1] == '*') 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; 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; return true;
if (globMatchEditorConfig!(cs, C)(p,
pattern[pi + 2 .. pattern.length]))
return true;
} }
return false; ++pi;
} }
else else
{ {
if (pi + 1 == pattern.length) /* Match for:
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:
* pattern[pi0..pi-1] ~ pattern[piRemain..$] * pattern[pi0..pi-1] ~ pattern[piRemain..$]
*/ */
if (pattmp.ptr == null) if (pattmp.ptr == null) // Allocate this only once per function invocation.
// Allocate this only once per function invocation. // Should do it with malloc/free, but that would make it impure.
// Should do it with malloc/free, but that would make it impure. pattmp = new C[pattern.length];
pattmp = new C[pattern.length];
const len1 = pi - 1 - pi0; const len1 = pi - 1 - pi0;
pattmp[0 .. len1] = pattern[pi0 .. pi - 1]; pattmp[0 .. len1] = pattern[pi0 .. pi - 1];
const len2 = pattern.length - piRemain; const len2 = pattern.length - piRemain;
pattmp[len1 .. len1 + len2] = pattern[piRemain .. $]; pattmp[len1 .. len1 + len2] = pattern[piRemain .. $];
if (globMatchEditorConfig!(cs, C)(p, pattmp[0 .. len1 + len2])) if (globMatchEditorConfig!(cs, C)(p, pattmp[0 .. len1 + len2]))
{
return true;
}
}
if (pc3 == '}')
{ {
break; return true;
} }
} }
return false; if (pc3 == '}')
{
break;
}
}
return false;
default: default:
if (path.empty) if (path.empty)
return false; return false;
if (filenameCharCmp!cs(pc, path.front) != 0) if (filenameCharCmp!cs(pc, path.front) != 0)
return false; return false;
path.popFront(); path.popFront();
break; break;
} }
} }
return path.empty; return path.empty;
@ -180,8 +179,8 @@ body
unittest unittest
{ {
assert (globMatchEditorConfig!(CaseSensitive.no)("foo", "Foo")); assert(globMatchEditorConfig!(CaseSensitive.no)("foo", "Foo"));
assert (!globMatchEditorConfig!(CaseSensitive.yes)("foo", "Foo")); assert(!globMatchEditorConfig!(CaseSensitive.yes)("foo", "Foo"));
assert(globMatchEditorConfig("foo", "*")); assert(globMatchEditorConfig("foo", "*"));
assert(globMatchEditorConfig("foo.bar"w, "*"w)); assert(globMatchEditorConfig("foo.bar"w, "*"w));
@ -225,7 +224,7 @@ unittest
assert(!globMatchEditorConfig("foo", "foob")); assert(!globMatchEditorConfig("foo", "foob"));
assert(!globMatchEditorConfig("foo", "foo{b}")); 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", "**"));
assert(globMatchEditorConfig("foo/bar", "foo/bar")); assert(globMatchEditorConfig("foo/bar", "foo/bar"));
assert(globMatchEditorConfig("foo/bar", "foo/*")); 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", "*/sar.png"));
assert(!globMatchEditorConfig("/foo/bar/gluu/sar.png", "*/*.png")); assert(!globMatchEditorConfig("/foo/bar/gluu/sar.png", "*/*.png"));
static assert(globMatchEditorConfig("foo.bar", "[!gh]*bar")); static assert(globMatchEditorConfig("foo.bar", "[!gh]*bar"));
} }

View File

@ -12,8 +12,8 @@ import dparse.lexer;
*/ */
bool isWrapIndent(IdType type) pure nothrow @nogc @safe bool isWrapIndent(IdType type) pure nothrow @nogc @safe
{ {
return type != tok!"{" && type != tok!"case" && type != tok!"@" return type != tok!"{" && type != tok!"case" && type != tok!"@"
&& type != tok!"]" && isOperator(type); && type != tok!"]" && type != tok!"(" && isOperator(type);
} }
/** /**
@ -30,8 +30,7 @@ bool isTempIndent(IdType type) pure nothrow @nogc @safe
struct IndentStack struct IndentStack
{ {
/** /**
* Modifies the indent stack to match the state that it had at the most * Get the indent size at the most recent occurence of the given indent type
* recent appearance of the given token type.
*/ */
int indentToMostRecent(IdType item) const int indentToMostRecent(IdType item) const
{ {
@ -152,6 +151,15 @@ struct IndentStack
return cast(int) index; 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: private:
size_t index; size_t index;
@ -164,18 +172,32 @@ private:
return 0; return 0;
immutable size_t j = k == size_t.max ? index : k; immutable size_t j = k == size_t.max ? index : k;
int size = 0; int size = 0;
int parenCount;
foreach (i; 0 .. j) foreach (i; 0 .. j)
{ {
if (i + 1 < index) if (i + 1 < index)
{ {
if (arr[i] == tok!"]") if (arr[i] == tok!"(")
parenCount++;
else if (arr[i] == tok!"]")
continue; continue;
immutable bool currentIsTemp = isTempIndent(arr[i]); else
immutable bool nextIsTemp = isTempIndent(arr[i + 1]); {
immutable bool nextIsSwitch = arr[i + 1] == tok!"switch"; if (isWrapIndent(arr[i]) && parenCount > 0)
if (currentIsTemp && (!nextIsTemp || nextIsSwitch)) {
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; continue;
} }
if (arr[i] == tok!"!")
size++;
size++; size++;
} }
return size; return size;

View File

@ -5,7 +5,7 @@
module dfmt.main; module dfmt.main;
private enum VERSION = "0.4.5"; private enum VERSION = "0.5.0";
version (NoMain) version (NoMain)
{ {
@ -32,8 +32,10 @@ else
{ {
import dfmt.editorconfig : OptionalBoolean; import dfmt.editorconfig : OptionalBoolean;
import std.exception : enforceEx; import std.exception : enforceEx;
enforceEx!GetOptException(value == "true" || value == "false", "Invalid argument"); 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) switch (option)
{ {
case "align_switch_statements": case "align_switch_statements":
@ -54,7 +56,8 @@ else
case "compact_labeled_statements": case "compact_labeled_statements":
optConfig.dfmt_compact_labeled_statements = optVal; optConfig.dfmt_compact_labeled_statements = optVal;
break; break;
default: assert(false, "Invalid command-line switch"); default:
assert(false, "Invalid command-line switch");
} }
} }
@ -113,17 +116,19 @@ else
return 1; return 1;
File output = stdout; File output = stdout;
version(Windows) version (Windows)
{ {
// On Windows, set stdout to binary mode (needed for correct EOL writing) // On Windows, set stdout to binary mode (needed for correct EOL writing)
// See Phobos' stdio.File.rawWrite // See Phobos' stdio.File.rawWrite
{ {
import std.stdio; import std.stdio;
immutable fd = fileno(output.getFP()); immutable fd = fileno(output.getFP());
setmode(fd, _O_BINARY); setmode(fd, _O_BINARY);
version(CRuntime_DigitalMars) version (CRuntime_DigitalMars)
{ {
import core.atomic : atomicOp; import core.atomic : atomicOp;
atomicOp!"&="(__fhnd_info[fd], ~FHND_TEXT); atomicOp!"&="(__fhnd_info[fd], ~FHND_TEXT);
} }
} }
@ -176,15 +181,18 @@ else
} }
} }
private string optionsToString(E)() if(is(E == enum)) { private string optionsToString(E)() if (is(E == enum))
import std.traits:EnumMembers; {
import std.conv; import std.traits : EnumMembers;
string result = "["; import std.conv;
foreach(i, option; EnumMembers!E) {
result ~= to!string(option) ~ "|"; string result = "[";
} foreach (i, option; EnumMembers!E)
result = result[0 .. $-1] ~ "]"; {
return result; result ~= to!string(option) ~ "|";
}
result = result[0 .. $ - 1] ~ "]";
return result;
} }
private void printHelp() private void printHelp()
@ -199,11 +207,13 @@ Options:
Formatting Options: Formatting Options:
--align_switch_statements --align_switch_statements
--brace_style `, optionsToString!(typeof(Config.dfmt_brace_style))(), ` --brace_style `,
optionsToString!(typeof(Config.dfmt_brace_style))(), `
--end_of_line --end_of_line
--help|h --help|h
--indent_size --indent_size
--indent_style|t `, optionsToString!(typeof(Config.indent_style))(), ` --indent_style|t `,
optionsToString!(typeof(Config.indent_style))(), `
--soft_max_line_length --soft_max_line_length
--max_line_length --max_line_length
--outdent_attributes --outdent_attributes
@ -211,7 +221,8 @@ Formatting Options:
--selective_import_space --selective_import_space
--split_operator_at_line_end --split_operator_at_line_end
--compact_labeled_statements --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) private string createFilePath(bool readFromStdin, string fileName)

View File

@ -195,7 +195,6 @@ pure nothrow @safe @nogc unittest
assert(breakCost(tok!".", u) != 1000); assert(breakCost(tok!".", u) != 1000);
} }
private string generateFixedLengthCases() private string generateFixedLengthCases()
{ {
import std.algorithm : map; import std.algorithm : map;
@ -205,11 +204,11 @@ private string generateFixedLengthCases()
assert(__ctfe); assert(__ctfe);
string[] spacedOperatorTokens = [ string[] spacedOperatorTokens = [
",", "..", "...", "/", "/=", "!", "!<", "!<=", "!<>", "!<>=", "!=", "!>", ",", "..", "...", "/", "/=", "!", "!<", "!<=", "!<>", "!<>=", "!=",
"!>=", "%", "%=", "&", "&&", "&=", "*", "*=", "+", "+=", "-", "-=", ":", "!>", "!>=", "%", "%=", "&", "&&", "&=", "*", "*=", "+", "+=", "-",
";", "<", "<<", "<<=", "<=", "<>", "<>=", "=", "==", "=>", ">", ">=", "-=", ":", ";", "<", "<<", "<<=", "<=", "<>", "<>=", "=", "==", "=>",
">>", ">>=", ">>>", ">>>=", "?", "@", "^", "^=", "^^", "^^=", "|", "|=", "||", ">", ">=", ">>", ">>=", ">>>", ">>>=", "?", "@", "^", "^=", "^^",
"~", "~=" "^^=", "|", "|=", "||", "~", "~="
]; ];
immutable spacedOperatorTokenCases = spacedOperatorTokens.map!( immutable spacedOperatorTokenCases = spacedOperatorTokens.map!(
a => format(`case tok!"%s": return %d + 1;`, a, a.length)).join("\n\t"); 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", "break", "byte", "case", "cast", "catch", "cdouble", "cent", "cfloat",
"char", "class", "const", "continue", "creal", "dchar", "debug", "char", "class", "const", "continue", "creal", "dchar", "debug",
"default", "delegate", "delete", "deprecated", "do", "double", "else", "default", "delegate", "delete", "deprecated", "do", "double", "else",
"enum", "export", "extern", "false", "final", "finally", "float", "for", "enum", "export", "extern", "false", "final", "finally", "float",
"foreach", "foreach_reverse", "function", "goto", "idouble", "if", "for", "foreach", "foreach_reverse", "function", "goto", "idouble",
"ifloat", "immutable", "import", "in", "inout", "int", "interface", "if", "ifloat", "immutable", "import", "in", "inout", "int",
"invariant", "ireal", "is", "lazy", "long", "macro", "mixin", "module", "interface", "invariant", "ireal", "is", "lazy", "long", "macro",
"new", "nothrow", "null", "out", "override", "package", "pragma", "mixin", "module", "new", "nothrow", "null", "out", "override",
"private", "protected", "public", "pure", "real", "ref", "return", "package", "pragma", "private", "protected", "public", "pure", "real",
"scope", "shared", "short", "static", "struct", "super", "switch", "ref", "return", "scope", "shared", "short", "static", "struct",
"synchronized", "template", "this", "throw", "true", "try", "typedef", "super", "switch", "synchronized", "template", "this", "throw", "true",
"typeid", "typeof", "ubyte", "ucent", "uint", "ulong", "union", "try", "typedef", "typeid", "typeof", "ubyte", "ucent", "uint",
"unittest", "ushort", "version", "void", "volatile", "wchar", "while", "ulong", "union", "unittest", "ushort", "version", "void", "volatile",
"with", "__DATE__", "__EOF__", "__FILE__", "__FUNCTION__", "__gshared", "wchar", "while", "with", "__DATE__", "__EOF__", "__FILE__",
"__LINE__", "__MODULE__", "__parameters", "__PRETTY_FUNCTION__", "__FUNCTION__", "__gshared", "__LINE__", "__MODULE__", "__parameters",
"__TIME__", "__TIMESTAMP__", "__traits", "__vector", "__VENDOR__", "__PRETTY_FUNCTION__", "__TIME__", "__TIMESTAMP__", "__traits",
"__VERSION__", "$", "++", "--", ".", "[", "]", "(", ")", "{", "}" "__vector", "__VENDOR__", "__VERSION__", "$", "++", "--", ".", "[",
"]", "(", ")", "{", "}"
]; ];
immutable identifierTokenCases = identifierTokens.map!( immutable identifierTokenCases = identifierTokens.map!(
a => format(`case tok!"%s": return %d;`, a, a.length)).join("\n\t"); a => format(`case tok!"%s": return %d;`, a, a.length)).join("\n\t");

View File

@ -12,13 +12,14 @@ import dfmt.config;
struct State struct State
{ {
this(uint breaks, const Token[] tokens, immutable short[] depths, 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 std.math : abs;
import core.bitop : popcnt, bsf; import core.bitop : popcnt, bsf;
import std.algorithm : min, map, sum; 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; immutable int newlinePenalty = remainingCharsMultiplier * 20;
this.breaks = breaks; this.breaks = breaks;
@ -119,7 +120,7 @@ private:
} }
size_t[] chooseLineBreakTokens(size_t index, const Token[] tokens, 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.container.rbtree : RedBlackTree;
import std.algorithm : filter, min; 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); immutable size_t tokensEnd = min(tokens.length, ALGORITHMIC_COMPLEXITY_SUCKS);
auto open = new RedBlackTree!State; auto open = new RedBlackTree!State;
open.insert(State(0, tokens[0 .. tokensEnd], depths[0 .. tokensEnd], config, open.insert(State(0, tokens[0 .. tokensEnd], depths[0 .. tokensEnd], config,
currentLineLength, indentLevel)); currentLineLength, indentLevel));
State lowest; State lowest;
while (!open.empty) while (!open.empty)
{ {
@ -152,7 +153,8 @@ size_t[] chooseLineBreakTokens(size_t index, const Token[] tokens,
return genRetVal(current.breaks, index); return genRetVal(current.breaks, index);
} }
validMoves!(typeof(open))(open, tokens[0 .. tokensEnd], 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) if (open.empty)
return genRetVal(lowest.breaks, index); 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, void validMoves(OR)(auto ref OR output, const Token[] tokens,
immutable short[] depths, uint current, const Config* config, immutable short[] depths, uint current, const Config* config,
int currentLineLength, int indentLevel) int currentLineLength, int indentLevel)
{ {
import std.algorithm : sort, canFind; import std.algorithm : sort, canFind;
import std.array : insertInPlace; import std.array : insertInPlace;

View File

@ -4,7 +4,7 @@ void main()
{ {
immutable interval = tuple(1, 100); immutable interval = tuple(1, 100);
writefln("Guess my target number that is between " ~ "%d and %d (inclusive).\n", writefln("Guess my target number that is between " ~ "%d and %d (inclusive).\n",
interval[]); interval[]);
immutable target = uniform!"[]"(interval[]); immutable target = uniform!"[]"(interval[]);
foreach (immutable i; sequence!q{n}) foreach (immutable i; sequence!q{n})

View File

@ -6,7 +6,7 @@ unittest
{ {
auto dd = new DtorDeclaration(declLoc, Loc(), stc, Identifier.idPool("__fieldDtor")); auto dd = new DtorDeclaration(declLoc, Loc(), stc, Identifier.idPool("__fieldDtor"));
auto dd = new DtorDeclaration(declLoc, Loc(), stc, extraParam, 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_idents, &rvl.saved_idents, (const(char)*).sizeof * VC_SAVED_IDENT_CNT);
memcpy(&saved_types, &rvl.saved_types, (Type).sizeof * VC_SAVED_TYPE_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, void doStuff(const Token[] tokens, ref const State current,
const FormatterConfig* formatterConfig, int currentLineLength, int indentLevel, const FormatterConfig* formatterConfig, int currentLineLength, int indentLevel,
int depth) int depth)
{ {
return; return;
} }

View File

@ -1,8 +1,9 @@
struct Test struct Test
{ {
this(string name, string[] aliasList, string briefDescription, string examDesc, this(string name, string[] aliasList, string briefDescription, string examDesc,
string onOpenDesc, string openDesc, string onCloseDesc, string closeDesc, string onOpenDesc, string openDesc, string onCloseDesc,
Flag!"canOpen" canOpen, Flag!"canClose" canClose, Flag!"isOpen" isOpen) string closeDesc, Flag!"canOpen" canOpen, Flag!"canClose" canClose,
Flag!"isOpen" isOpen)
{ {
} }
} }

View File

@ -18,8 +18,8 @@ unittest
callFunc({ callFunc({
int i = 10; int i = 10;
foo(alpha_longVarName, bravo_longVarName, charlie_longVarName, foo(alpha_longVarName, bravo_longVarName, charlie_longVarName,
delta_longVarName, echo_longVarName, foxtrot_longVarName, delta_longVarName, echo_longVarName, foxtrot_longVarName,
golf_longVarName, echo_longVarName); golf_longVarName, echo_longVarName);
doStuff(withThings, andOtherStuff); doStuff(withThings, andOtherStuff);
return i; return i;
}, more_stuff); }, more_stuff);

View File

@ -1,7 +1,7 @@
struct State struct State
{ {
this(uint breaks, const Token[] tokens, immutable short[] depths, 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
{ {
} }
} }

View File

@ -1,8 +1,8 @@
void foo(int foobarbazqux1, /* */ void foo(int foobarbazqux1, /* */
int foobarbazqux2, /* */ int foobarbazqux2, /* */
int foobarbazqux3, /* */ int foobarbazqux3, /* */
int foobarbazqux4, /* */ int foobarbazqux4, /* */
int foobarbazqux5, /* */ int foobarbazqux5, /* */
int foobarbazqux6, /* */ int foobarbazqux6, /* */
int foobarbazqux7 /* */ int foobarbazqux7 /* */
); );

View File

@ -8,9 +8,9 @@ unittest
{ {
{ {
bool anotherTemplatedFunction(One, Two, Three)(One alpha, Two bravo, 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 if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo
&& foxtrot && golf && hotel && india && juliet) && foxtrot && golf && hotel && india && juliet)
{ {
} }

View File

@ -8,9 +8,9 @@ unittest
{ {
{ {
bool anotherTemplatedFunction(One, Two, Three)(One alpha, Two bravo, 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 if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo
&& foxtrot && golf && hotel && india && juliet) && foxtrot && golf && hotel && india && juliet)
{ {
} }

View File

@ -9,9 +9,9 @@ unittest
{ {
{ {
bool anotherTemplatedFunction(One, Two, Three)(One alpha, Two bravo, 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 if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo
&& foxtrot && golf && hotel && india && juliet) && foxtrot && golf && hotel && india && juliet)
{ {
} }

View File

@ -1,7 +1,7 @@
module example; module example;
bool aTemplatedFunction(One)(One alpha) 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, 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 if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo
&& foxtrot && golf && hotel && india && juliet) && foxtrot && golf && hotel && india && juliet)
{ {
} }

View File

@ -5,7 +5,7 @@ version (AArch64)
public: public:
double javaStyleFunctionName(double alpha, double bravo, double charlie, 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)
{ {

View File

@ -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();
}
}
}

View File

@ -3,7 +3,7 @@ void main(string[] args)
if (prevLocation != size_t.max) if (prevLocation != size_t.max)
{ {
addErrorMessage(line, column, KEY, addErrorMessage(line, column, KEY,
"Expression %s is true: already checked on line %d.".format( "Expression %s is true: already checked on line %d.".format(
expressions[prevLocation].formatted, expressions[prevLocation].line)); expressions[prevLocation].formatted, expressions[prevLocation].line));
} }
} }

View File

@ -3,7 +3,7 @@ import std.stdio, std.random, std.typecons, std.conv, std.string, std.range;
void main() { void main() {
immutable interval = tuple(1, 100); immutable interval = tuple(1, 100);
writefln("Guess my target number that is between " ~ "%d and %d (inclusive).\n", writefln("Guess my target number that is between " ~ "%d and %d (inclusive).\n",
interval[]); interval[]);
immutable target = uniform!"[]"(interval[]); immutable target = uniform!"[]"(interval[]);
foreach (immutable i; sequence!q{n}) { foreach (immutable i; sequence!q{n}) {

View File

@ -5,7 +5,7 @@ unittest {
{ {
auto dd = new DtorDeclaration(declLoc, Loc(), stc, Identifier.idPool("__fieldDtor")); auto dd = new DtorDeclaration(declLoc, Loc(), stc, Identifier.idPool("__fieldDtor"));
auto dd = new DtorDeclaration(declLoc, Loc(), stc, extraParam, 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_idents, &rvl.saved_idents, (const(char)*).sizeof * VC_SAVED_IDENT_CNT);
memcpy(&saved_types, &rvl.saved_types, (Type).sizeof * VC_SAVED_TYPE_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, void doStuff(const Token[] tokens, ref const State current,
const FormatterConfig* formatterConfig, int currentLineLength, int indentLevel, const FormatterConfig* formatterConfig, int currentLineLength, int indentLevel,
int depth) { int depth) {
return; return;
} }

View File

@ -1,6 +1,7 @@
struct Test { struct Test {
this(string name, string[] aliasList, string briefDescription, string examDesc, this(string name, string[] aliasList, string briefDescription, string examDesc,
string onOpenDesc, string openDesc, string onCloseDesc, string closeDesc, string onOpenDesc, string openDesc, string onCloseDesc,
Flag!"canOpen" canOpen, Flag!"canClose" canClose, Flag!"isOpen" isOpen) { string closeDesc, Flag!"canOpen" canOpen, Flag!"canClose" canClose,
Flag!"isOpen" isOpen) {
} }
} }

View File

@ -17,8 +17,8 @@ unittest {
callFunc({ callFunc({
int i = 10; int i = 10;
foo(alpha_longVarName, bravo_longVarName, charlie_longVarName, foo(alpha_longVarName, bravo_longVarName, charlie_longVarName,
delta_longVarName, echo_longVarName, foxtrot_longVarName, delta_longVarName, echo_longVarName, foxtrot_longVarName,
golf_longVarName, echo_longVarName); golf_longVarName, echo_longVarName);
doStuff(withThings, andOtherStuff); doStuff(withThings, andOtherStuff);
return i; return i;
}, more_stuff); }, more_stuff);

View File

@ -1,5 +1,5 @@
struct State { struct State {
this(uint breaks, const Token[] tokens, immutable short[] depths, 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 {
} }
} }

View File

@ -1,8 +1,8 @@
void foo(int foobarbazqux1, /* */ void foo(int foobarbazqux1, /* */
int foobarbazqux2, /* */ int foobarbazqux2, /* */
int foobarbazqux3, /* */ int foobarbazqux3, /* */
int foobarbazqux4, /* */ int foobarbazqux4, /* */
int foobarbazqux5, /* */ int foobarbazqux5, /* */
int foobarbazqux6, /* */ int foobarbazqux6, /* */
int foobarbazqux7 /* */ int foobarbazqux7 /* */
); );

View File

@ -6,9 +6,9 @@ bool aTemplatedFunction(One)(One alpha) if (isNumeric!One) {
unittest { unittest {
{ {
bool anotherTemplatedFunction(One, Two, Three)(One alpha, Two bravo, 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 if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo
&& foxtrot && golf && hotel && india && juliet) { && foxtrot && golf && hotel && india && juliet) {
} }
} }

View File

@ -6,9 +6,9 @@ bool aTemplatedFunction(One)(One alpha) if (isNumeric!One) {
unittest { unittest {
{ {
bool anotherTemplatedFunction(One, Two, Three)(One alpha, Two bravo, 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 if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo
&& foxtrot && golf && hotel && india && juliet) { && foxtrot && golf && hotel && india && juliet) {
} }
} }

View File

@ -7,9 +7,9 @@ if (isNumeric!One) {
unittest { unittest {
{ {
bool anotherTemplatedFunction(One, Two, Three)(One alpha, Two bravo, 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 if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo
&& foxtrot && golf && hotel && india && juliet) { && foxtrot && golf && hotel && india && juliet) {
} }
} }

View File

@ -1,15 +1,15 @@
module example; module example;
bool aTemplatedFunction(One)(One alpha) bool aTemplatedFunction(One)(One alpha)
if (isNumeric!One) { if (isNumeric!One) {
} }
unittest { unittest {
{ {
bool anotherTemplatedFunction(One, Two, Three)(One alpha, Two bravo, 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 if (isNumeric!One && isNumeric!Two && isNumeric!Three && echo
&& foxtrot && golf && hotel && india && juliet) { && foxtrot && golf && hotel && india && juliet) {
} }
} }

View File

@ -3,7 +3,7 @@ version (AArch64) {
public: public:
double javaStyleFunctionName(double alpha, double bravo, double charlie, 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 && bravo >= charlie && echo < delta) { if (alpha < beta && alpha > golf && hotel < alpha && bravo >= charlie && echo < delta) {
if (alpha < beta && alpha > golf && hotel < alpha if (alpha < beta && alpha > golf && hotel < alpha

View File

@ -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();
}
}
}

View File

@ -1,7 +1,7 @@
void main(string[] args) { void main(string[] args) {
if (prevLocation != size_t.max) { if (prevLocation != size_t.max) {
addErrorMessage(line, column, KEY, addErrorMessage(line, column, KEY,
"Expression %s is true: already checked on line %d.".format( "Expression %s is true: already checked on line %d.".format(
expressions[prevLocation].formatted, expressions[prevLocation].line)); expressions[prevLocation].formatted, expressions[prevLocation].line));
} }
} }

32
tests/parenIndent.d Normal file
View File

@ -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();
}
}
}

View File

@ -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