Fix #47
This commit is contained in:
parent
8a416f9849
commit
dc7c529716
221
src/dfmt.d
221
src/dfmt.d
|
@ -175,16 +175,19 @@ private:
|
||||||
{
|
{
|
||||||
if (index > 0)
|
if (index > 0)
|
||||||
{
|
{
|
||||||
if (tokens[index - 1].type != tok!";" && tokens[index - 1].type != tok!"}" && tokens[index - 1].line + 1 < tokens[index]
|
immutable t = tokens[index - 1].type;
|
||||||
|
if (t != tok!";" && t != tok!"}" && tokens[index - 1].line + 1 < tokens[index]
|
||||||
.line)
|
.line)
|
||||||
{
|
{
|
||||||
newline();
|
newline();
|
||||||
}
|
}
|
||||||
else if (tokens[index - 1].line == tokens[index].line)
|
else if (tokens[index - 1].line == tokens[index].line)
|
||||||
write(" ");
|
write(" ");
|
||||||
|
else if (isWrapIndent(t))
|
||||||
|
pushWrapIndent(t);
|
||||||
}
|
}
|
||||||
writeToken();
|
writeToken();
|
||||||
auto j = justAddedExtraNewline;
|
immutable j = justAddedExtraNewline;
|
||||||
if (tokens[index - 1].text[0 .. 2] == "//")
|
if (tokens[index - 1].text[0 .. 2] == "//")
|
||||||
{
|
{
|
||||||
newline();
|
newline();
|
||||||
|
@ -370,6 +373,7 @@ private:
|
||||||
break;
|
break;
|
||||||
case tok!"case":
|
case tok!"case":
|
||||||
writeToken();
|
writeToken();
|
||||||
|
if (!currentIs(tok!";"))
|
||||||
write(" ");
|
write(" ");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -429,7 +433,7 @@ private:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
goto case ;
|
goto case;
|
||||||
case tok!"&":
|
case tok!"&":
|
||||||
case tok!"+":
|
case tok!"+":
|
||||||
case tok!"-":
|
case tok!"-":
|
||||||
|
@ -439,19 +443,23 @@ private:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
goto binary;
|
goto binary;
|
||||||
|
case tok!"[":
|
||||||
case tok!"(":
|
case tok!"(":
|
||||||
spaceAfterParens = true;
|
immutable p = tokens[index].type;
|
||||||
|
regenLineBreakHintsIfNecessary(index);
|
||||||
writeToken();
|
writeToken();
|
||||||
parenDepth++;
|
if (p == tok!"(")
|
||||||
if (linebreakHints.canFindIndex(index - 1)
|
|
||||||
|| (linebreakHints.length == 0
|
|
||||||
&& currentLineLength > config.columnSoftLimit
|
|
||||||
&& !currentIs(tok!")")))
|
|
||||||
{
|
{
|
||||||
pushWrapIndent(tok!"(");
|
spaceAfterParens = true;
|
||||||
|
parenDepth++;
|
||||||
|
}
|
||||||
|
if (linebreakHints.canFindIndex(index - 1) || (linebreakHints.length == 0
|
||||||
|
&& currentLineLength > config.columnSoftLimit && !currentIs(
|
||||||
|
tok!")")))
|
||||||
|
{
|
||||||
|
pushWrapIndent(p);
|
||||||
newline();
|
newline();
|
||||||
}
|
}
|
||||||
regenLineBreakHintsIfNecessary(index - 1);
|
|
||||||
break;
|
break;
|
||||||
case tok!")":
|
case tok!")":
|
||||||
parenDepth--;
|
parenDepth--;
|
||||||
|
@ -492,7 +500,8 @@ private:
|
||||||
else
|
else
|
||||||
write(" ");
|
write(" ");
|
||||||
}
|
}
|
||||||
else if (index < tokens.length && !isOperator(tokens[index].type))
|
else if (index < tokens.length && (currentIs(tok!"@") || !isOperator(
|
||||||
|
tokens[index].type)))
|
||||||
write(" ");
|
write(" ");
|
||||||
break;
|
break;
|
||||||
case tok!"!":
|
case tok!"!":
|
||||||
|
@ -500,7 +509,6 @@ private:
|
||||||
write(" ");
|
write(" ");
|
||||||
goto case;
|
goto case;
|
||||||
case tok!"...":
|
case tok!"...":
|
||||||
case tok!"[":
|
|
||||||
case tok!"++":
|
case tok!"++":
|
||||||
case tok!"--":
|
case tok!"--":
|
||||||
case tok!"$":
|
case tok!"$":
|
||||||
|
@ -649,8 +657,7 @@ private:
|
||||||
break;
|
break;
|
||||||
case tok!".":
|
case tok!".":
|
||||||
if (linebreakHints.canFind(index) || (linebreakHints.length == 0
|
if (linebreakHints.canFind(index) || (linebreakHints.length == 0
|
||||||
&& currentLineLength + nextTokenLength(
|
&& currentLineLength + nextTokenLength() > config.columnHardLimit))
|
||||||
) > config.columnHardLimit))
|
|
||||||
{
|
{
|
||||||
pushWrapIndent();
|
pushWrapIndent();
|
||||||
newline();
|
newline();
|
||||||
|
@ -658,9 +665,9 @@ private:
|
||||||
writeToken();
|
writeToken();
|
||||||
break;
|
break;
|
||||||
case tok!",":
|
case tok!",":
|
||||||
|
regenLineBreakHintsIfNecessary(index);
|
||||||
if (!peekIs(tok!"}") && (linebreakHints.canFind(index)
|
if (!peekIs(tok!"}") && (linebreakHints.canFind(index)
|
||||||
|| (linebreakHints.length == 0
|
|| (linebreakHints.length == 0 && currentLineLength > config.columnSoftLimit)))
|
||||||
&& currentLineLength > config.columnSoftLimit)))
|
|
||||||
{
|
{
|
||||||
writeToken();
|
writeToken();
|
||||||
pushWrapIndent(tok!",");
|
pushWrapIndent(tok!",");
|
||||||
|
@ -669,15 +676,18 @@ private:
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
writeToken();
|
writeToken();
|
||||||
if (!currentIs(tok!")", false) && !currentIs(tok!"]", false)
|
if (!currentIs(tok!")", false) && !currentIs(tok!"]", false) && !currentIs(
|
||||||
&& !currentIs(tok!"}", false)
|
tok!"}", false) && !currentIs(tok!"comment", false))
|
||||||
&& !currentIs(tok!"comment", false))
|
|
||||||
{
|
{
|
||||||
write(" ");
|
write(" ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
regenLineBreakHintsIfNecessary(index - 1);
|
regenLineBreakHintsIfNecessary(index - 1);
|
||||||
break;
|
break;
|
||||||
|
case tok!"&&":
|
||||||
|
case tok!"||":
|
||||||
|
regenLineBreakHintsIfNecessary(index);
|
||||||
|
goto case;
|
||||||
case tok!"=":
|
case tok!"=":
|
||||||
case tok!">=":
|
case tok!">=":
|
||||||
case tok!">>=":
|
case tok!">>=":
|
||||||
|
@ -689,15 +699,6 @@ private:
|
||||||
case tok!"&=":
|
case tok!"&=":
|
||||||
case tok!"%=":
|
case tok!"%=":
|
||||||
case tok!"+=":
|
case tok!"+=":
|
||||||
write(" ");
|
|
||||||
writeToken();
|
|
||||||
write(" ");
|
|
||||||
regenLineBreakHintsIfNecessary(index - 1);
|
|
||||||
break;
|
|
||||||
case tok!"&&":
|
|
||||||
case tok!"||":
|
|
||||||
regenLineBreakHintsIfNecessary(index);
|
|
||||||
goto case ;
|
|
||||||
case tok!"^^":
|
case tok!"^^":
|
||||||
case tok!"^=":
|
case tok!"^=":
|
||||||
case tok!"^":
|
case tok!"^":
|
||||||
|
@ -726,7 +727,7 @@ private:
|
||||||
case tok!"..":
|
case tok!"..":
|
||||||
case tok!"%":
|
case tok!"%":
|
||||||
binary:
|
binary:
|
||||||
if (linebreakHints.canFind(index))
|
if (linebreakHints.canFind(index) || peekIs(tok!"comment", false))
|
||||||
{
|
{
|
||||||
pushWrapIndent();
|
pushWrapIndent();
|
||||||
newline();
|
newline();
|
||||||
|
@ -745,8 +746,8 @@ private:
|
||||||
{
|
{
|
||||||
writeToken();
|
writeToken();
|
||||||
if (index < tokens.length && (currentIs(tok!"identifier")
|
if (index < tokens.length && (currentIs(tok!"identifier")
|
||||||
|| isKeyword(current.type) || isBasicType(current.type)
|
|| isKeyword(current.type) || isBasicType(current.type) || currentIs(
|
||||||
|| currentIs(tok!"@")))
|
tok!"@")))
|
||||||
{
|
{
|
||||||
write(" ");
|
write(" ");
|
||||||
}
|
}
|
||||||
|
@ -765,20 +766,20 @@ private:
|
||||||
if (linebreakHints.length == 0 || linebreakHints[$ - 1] <= i - 1)
|
if (linebreakHints.length == 0 || linebreakHints[$ - 1] <= i - 1)
|
||||||
{
|
{
|
||||||
immutable size_t j = expressionEndIndex(i);
|
immutable size_t j = expressionEndIndex(i);
|
||||||
linebreakHints = chooseLineBreakTokens(i, tokens[i .. j], config,
|
linebreakHints = chooseLineBreakTokens(i, tokens[i .. j], config, currentLineLength,
|
||||||
currentLineLength, indentLevel);
|
indentLevel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t expressionEndIndex(size_t i) const pure @safe @nogc
|
size_t expressionEndIndex(size_t i) const pure @safe @nogc
|
||||||
{
|
{
|
||||||
int parenDepth = 0;
|
int parDepth = 0;
|
||||||
int bracketDepth = 0;
|
int bracketDepth = 0;
|
||||||
int braceDepth = 0;
|
int braceDepth = 0;
|
||||||
loop: while (i < tokens.length) switch (tokens[i].type)
|
loop: while (i < tokens.length) switch (tokens[i].type)
|
||||||
{
|
{
|
||||||
case tok!"(":
|
case tok!"(":
|
||||||
parenDepth++;
|
parDepth++;
|
||||||
i++;
|
i++;
|
||||||
break;
|
break;
|
||||||
case tok!"{":
|
case tok!"{":
|
||||||
|
@ -790,20 +791,20 @@ private:
|
||||||
i++;
|
i++;
|
||||||
break;
|
break;
|
||||||
case tok!")":
|
case tok!")":
|
||||||
parenDepth--;
|
parDepth--;
|
||||||
if (parenDepth <= 0)
|
if (parDepth <= 0 && braceDepth <= 0 && bracketDepth <= 0)
|
||||||
break loop;
|
break loop;
|
||||||
i++;
|
i++;
|
||||||
break;
|
break;
|
||||||
case tok!"}":
|
case tok!"}":
|
||||||
braceDepth--;
|
braceDepth--;
|
||||||
if (braceDepth <= 0)
|
if (parDepth <= 0 && braceDepth <= 0 && bracketDepth <= 0)
|
||||||
break loop;
|
break loop;
|
||||||
i++;
|
i++;
|
||||||
break;
|
break;
|
||||||
case tok!"]":
|
case tok!"]":
|
||||||
bracketDepth--;
|
bracketDepth--;
|
||||||
if (bracketDepth <= 0)
|
if (parDepth <= 0 && braceDepth <= 0 && bracketDepth <= 0)
|
||||||
break loop;
|
break loop;
|
||||||
i++;
|
i++;
|
||||||
break;
|
break;
|
||||||
|
@ -991,8 +992,7 @@ private:
|
||||||
return false;
|
return false;
|
||||||
auto t = tokens[i + index].type;
|
auto t = tokens[i + index].type;
|
||||||
return t == tok!"for" || t == tok!"foreach" || t == tok!"foreach_reverse"
|
return t == tok!"for" || t == tok!"foreach" || t == tok!"foreach_reverse"
|
||||||
|| t == tok!"while" || t == tok!"if" || t == tok!"out" || t == tok!"catch"
|
|| t == tok!"while" || t == tok!"if" || t == tok!"out" || t == tok!"catch" || t == tok!"with";
|
||||||
|| t == tok!"with";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void newline()
|
void newline()
|
||||||
|
@ -1000,14 +1000,13 @@ private:
|
||||||
import std.range : assumeSorted;
|
import std.range : assumeSorted;
|
||||||
import std.algorithm : max;
|
import std.algorithm : max;
|
||||||
|
|
||||||
if (currentIs(tok!"comment")
|
if (currentIs(tok!"comment") && current.line == tokenEndLine(tokens[index - 1]))
|
||||||
&& current.line == tokenEndLine(tokens[index - 1]))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
immutable bool hasCurrent = index + 1 < tokens.length;
|
immutable bool hasCurrent = index + 1 < tokens.length;
|
||||||
|
|
||||||
if (hasCurrent && tokens[index].type == tok!"}"
|
if (hasCurrent && tokens[index].type == tok!"}" && !assumeSorted(astInformation.funLitEndLocations).equalRange(
|
||||||
&& !assumeSorted(astInformation.funLitEndLocations).equalRange(tokens[index].index).empty)
|
tokens[index].index).empty)
|
||||||
{
|
{
|
||||||
write(" ");
|
write(" ");
|
||||||
return;
|
return;
|
||||||
|
@ -1066,19 +1065,16 @@ private:
|
||||||
if (l != -1)
|
if (l != -1)
|
||||||
indentLevel = l;
|
indentLevel = l;
|
||||||
}
|
}
|
||||||
else if (currentIs(tok!"{")
|
else if (currentIs(tok!"{") && !astInformation.structInitStartLocations.canFindIndex(
|
||||||
&& !astInformation.structInitStartLocations.canFindIndex(
|
tokens[index].index) && !astInformation.funLitStartLocations.canFindIndex(
|
||||||
tokens[index].index)
|
|
||||||
&& !astInformation.funLitStartLocations.canFindIndex(
|
|
||||||
tokens[index].index))
|
tokens[index].index))
|
||||||
{
|
{
|
||||||
while (indents.length && isWrapIndent(indents.top))
|
while (indents.length && isWrapIndent(indents.top))
|
||||||
indents.pop();
|
indents.pop();
|
||||||
indents.push(tok!"{");
|
indents.push(tok!"{");
|
||||||
if (index == 1 || peekBackIs(tok!":", true)
|
if (index == 1 || peekBackIs(tok!":", true) || peekBackIs(tok!"{",
|
||||||
|| peekBackIs(tok!"{", true) || peekBackIs(tok!"}",
|
true) || peekBackIs(tok!"}", true) || peekBackIs(tok!")", true) || peekBackIs(
|
||||||
true) || peekBackIs(tok!")", true)
|
tok!";", true))
|
||||||
|| peekBackIs(tok!";", true))
|
|
||||||
{
|
{
|
||||||
indentLevel = indents.indentSize - 1;
|
indentLevel = indents.indentSize - 1;
|
||||||
}
|
}
|
||||||
|
@ -1093,14 +1089,13 @@ private:
|
||||||
indents.pop();
|
indents.pop();
|
||||||
}
|
}
|
||||||
while (indents.length && isTempIndent(indents.top)
|
while (indents.length && isTempIndent(indents.top)
|
||||||
&& ((indents.top != tok!"if" && indents.top != tok!"version")
|
&& ((indents.top != tok!"if" && indents.top != tok!"version") || !peekIs(
|
||||||
|| !peekIs(tok!"else")))
|
tok!"else")))
|
||||||
{
|
{
|
||||||
indents.pop();
|
indents.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (astInformation.attributeDeclarationLines.canFindIndex(
|
else if (astInformation.attributeDeclarationLines.canFindIndex(current.line))
|
||||||
current.line))
|
|
||||||
{
|
{
|
||||||
auto l = indents.indentToMostRecent(tok!"{");
|
auto l = indents.indentToMostRecent(tok!"{");
|
||||||
if (l != -1)
|
if (l != -1)
|
||||||
|
@ -1199,7 +1194,7 @@ private:
|
||||||
|
|
||||||
bool isWrapIndent(IdType type) pure nothrow @nogc @safe
|
bool isWrapIndent(IdType type) pure nothrow @nogc @safe
|
||||||
{
|
{
|
||||||
return type != tok!"{" && isOperator(type);
|
return type != tok!"{" && type != tok!":" && isOperator(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isTempIndent(IdType type) pure nothrow @nogc @safe
|
bool isTempIndent(IdType type) pure nothrow @nogc @safe
|
||||||
|
@ -1360,8 +1355,7 @@ 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
|
if (functionBody.bodyStatement !is null && functionBody.bodyStatement.blockStatement !is null)
|
||||||
&& functionBody.bodyStatement.blockStatement !is null)
|
|
||||||
astInformation.doubleNewlineLocations ~= functionBody.bodyStatement.blockStatement.endLocation;
|
astInformation.doubleNewlineLocations ~= functionBody.bodyStatement.blockStatement.endLocation;
|
||||||
functionBody.accept(this);
|
functionBody.accept(this);
|
||||||
}
|
}
|
||||||
|
@ -1413,8 +1407,7 @@ 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;
|
||||||
}
|
}
|
||||||
|
@ -1456,13 +1449,14 @@ string generateFixedLengthCases()
|
||||||
"volatile", "wchar", "while", "with", "__DATE__", "__EOF__", "__FILE__",
|
"volatile", "wchar", "while", "with", "__DATE__", "__EOF__", "__FILE__",
|
||||||
"__FUNCTION__", "__gshared", "__LINE__", "__MODULE__", "__parameters",
|
"__FUNCTION__", "__gshared", "__LINE__", "__MODULE__", "__parameters",
|
||||||
"__PRETTY_FUNCTION__", "__TIME__", "__TIMESTAMP__", "__traits", "__vector",
|
"__PRETTY_FUNCTION__", "__TIME__", "__TIMESTAMP__", "__traits", "__vector",
|
||||||
"__VENDOR__", "__VERSION__", ",", ".", "..", "...", "/", "/=", "!", "!<", "!<=",
|
"__VENDOR__", "__VERSION__", ",", ".", "..", "...", "/", "/=", "!", "!<",
|
||||||
"!<>", "!<>=", "!=", "!>", "!>=", "$", "%", "%=", "&", "&&", "&=", "(", ")", "*",
|
"!<=", "!<>", "!<>=", "!=", "!>", "!>=", "$", "%", "%=", "&", "&&", "&=",
|
||||||
"*=", "+", "++", "+=", "-", "--", "-=", ":", ";", "<", "<<", "<<=", "<=", "<>",
|
"(", ")", "*", "*=", "+", "++", "+=", "-", "--", "-=", ":", ";", "<", "<<",
|
||||||
"<>=", "=", "==", "=>", ">", ">=", ">>", ">>=", ">>>", ">>>=", "?", "@", "[", "]",
|
"<<=", "<=", "<>", "<>=", "=", "==", "=>", ">", ">=", ">>", ">>=", ">>>",
|
||||||
"^", "^=", "^^", "^^=", "{", "|", "|=", "||", "}", "~", "~="];
|
">>>=", "?", "@", "[", "]", "^", "^=", "^^", "^^=", "{", "|", "|=", "||", "}",
|
||||||
return fixedLengthTokens.map!(a => format(`case tok!"%s": return %d;`, a,
|
"~", "~="];
|
||||||
a.length)).join("\n\t");
|
return fixedLengthTokens.map!(a => format(`case tok!"%s": return %d;`, a, a.length)).join(
|
||||||
|
"\n\t");
|
||||||
}
|
}
|
||||||
|
|
||||||
int tokenLength(ref const Token t) pure @safe @nogc
|
int tokenLength(ref const Token t) pure @safe @nogc
|
||||||
|
@ -1562,11 +1556,12 @@ int breakCost(IdType t)
|
||||||
{
|
{
|
||||||
case tok!"||":
|
case tok!"||":
|
||||||
case tok!"&&":
|
case tok!"&&":
|
||||||
return 0;
|
|
||||||
case tok!"[":
|
|
||||||
case tok!"(":
|
|
||||||
case tok!",":
|
case tok!",":
|
||||||
return 10;
|
return 0;
|
||||||
|
case tok!"(":
|
||||||
|
return 60;
|
||||||
|
case tok!"[":
|
||||||
|
return 100;
|
||||||
case tok!"^^":
|
case tok!"^^":
|
||||||
case tok!"^=":
|
case tok!"^=":
|
||||||
case tok!"^":
|
case tok!"^":
|
||||||
|
@ -1608,35 +1603,62 @@ int breakCost(IdType t)
|
||||||
case tok!"-":
|
case tok!"-":
|
||||||
case tok!"~":
|
case tok!"~":
|
||||||
case tok!"+=":
|
case tok!"+=":
|
||||||
return 100;
|
return 300;
|
||||||
case tok!".":
|
case tok!".":
|
||||||
return 200;
|
return 700;
|
||||||
default:
|
default:
|
||||||
return 1000;
|
return 1000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
foreach (ubyte u; 0 .. ubyte.max)
|
||||||
|
if (isBreakToken(u))
|
||||||
|
assert(breakCost(u) != 1000);
|
||||||
|
}
|
||||||
|
|
||||||
struct State
|
struct State
|
||||||
{
|
{
|
||||||
this(size_t[] breaks, const Token[] tokens, int depth,
|
this(size_t[] breaks, const Token[] tokens, int depth,
|
||||||
const FormatterConfig* formatterConfig, int currentLineLength,
|
const FormatterConfig* formatterConfig, int currentLineLength, int indentLevel)
|
||||||
int indentLevel)
|
|
||||||
{
|
{
|
||||||
|
immutable remainingCharsMultiplier = 40;
|
||||||
|
immutable newlinePenalty = 800;
|
||||||
|
|
||||||
|
|
||||||
this.breaks = breaks;
|
this.breaks = breaks;
|
||||||
this._depth = depth;
|
this._depth = depth;
|
||||||
import std.algorithm : map, sum;
|
import std.algorithm : map, sum;
|
||||||
|
|
||||||
this._cost = breaks.map!(b => breakCost(tokens[b].type)).sum() + (depth * 500);
|
this._cost = 0;
|
||||||
|
int parenDepth = 0;
|
||||||
|
for (size_t i = 0; i != breaks.length; ++i)
|
||||||
|
{
|
||||||
|
immutable b = tokens[breaks[i]].type;
|
||||||
|
if (b == tok!"(" || b == tok!"[")
|
||||||
|
parenDepth++;
|
||||||
|
else if (b == tok!")" || b == tok!"]")
|
||||||
|
parenDepth--;
|
||||||
|
immutable bc = breakCost(b) * (parenDepth == 0 ? 1 : parenDepth * 2);
|
||||||
|
this._cost += bc;
|
||||||
|
}
|
||||||
int ll = currentLineLength;
|
int ll = currentLineLength;
|
||||||
size_t breakIndex = 0;
|
size_t breakIndex = 0;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
bool s = true;
|
bool s = true;
|
||||||
if (breaks.length == 0)
|
if (breaks.length == 0)
|
||||||
{
|
{
|
||||||
_cost = int.max;
|
immutable int l = currentLineLength + tokens.map!(a => tokenLength(a)).sum();
|
||||||
immutable int l = currentLineLength + tokens.map!(a => tokenLength(
|
_cost = l;
|
||||||
a)).sum();
|
if (l > formatterConfig.columnSoftLimit)
|
||||||
s = l < formatterConfig.columnSoftLimit;
|
{
|
||||||
|
immutable longPenalty = (l - formatterConfig.columnSoftLimit) * remainingCharsMultiplier;
|
||||||
|
_cost += longPenalty;
|
||||||
|
s = longPenalty < newlinePenalty;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
s = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1644,17 +1666,20 @@ struct State
|
||||||
{
|
{
|
||||||
immutable size_t j = breakIndex < breaks.length ? breaks[breakIndex] : tokens.length;
|
immutable size_t j = breakIndex < breaks.length ? breaks[breakIndex] : tokens.length;
|
||||||
ll += tokens[i .. j].map!(a => tokenLength(a)).sum();
|
ll += tokens[i .. j].map!(a => tokenLength(a)).sum();
|
||||||
if (ll > formatterConfig.columnSoftLimit)
|
if (ll > formatterConfig.columnHardLimit)
|
||||||
{
|
{
|
||||||
s = false;
|
s = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else if (ll > formatterConfig.columnSoftLimit)
|
||||||
|
_cost += (ll - formatterConfig.columnSoftLimit) * remainingCharsMultiplier;
|
||||||
i = j;
|
i = j;
|
||||||
ll = (indentLevel + 1) * formatterConfig.indentSize;
|
ll = indentLevel * formatterConfig.indentSize;
|
||||||
breakIndex++;
|
breakIndex++;
|
||||||
}
|
}
|
||||||
while (i + 1 < tokens.length);
|
while (i + 1 < tokens.length);
|
||||||
}
|
}
|
||||||
|
this._cost += breaks.length * newlinePenalty;
|
||||||
this._solved = s;
|
this._solved = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1675,9 +1700,8 @@ struct State
|
||||||
|
|
||||||
int opCmp(ref const State other) const pure nothrow @safe
|
int opCmp(ref const State other) const pure nothrow @safe
|
||||||
{
|
{
|
||||||
if (cost < other.cost || (cost == other.cost && ((breaks.length
|
if (cost < other.cost || (cost == other.cost && ((breaks.length && other.breaks.length && breaks[
|
||||||
&& other.breaks.length && breaks[0] > other.breaks[0]) || (_solved
|
0] > other.breaks[0]) || (_solved && !other.solved))))
|
||||||
&& !other.solved))))
|
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1701,20 +1725,19 @@ private:
|
||||||
bool _solved;
|
bool _solved;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t[] chooseLineBreakTokens(size_t index, const Token[] tokens, const FormatterConfig* formatterConfig, int currentLineLength,
|
size_t[] chooseLineBreakTokens(size_t index, const Token[] tokens,
|
||||||
int indentLevel)
|
const FormatterConfig* formatterConfig, int currentLineLength, int indentLevel)
|
||||||
{
|
{
|
||||||
import std.container.rbtree : RedBlackTree;
|
import std.container.rbtree : RedBlackTree;
|
||||||
import std.algorithm : filter, min;
|
import std.algorithm : filter, min;
|
||||||
import core.memory : GC;
|
import core.memory : GC;
|
||||||
|
|
||||||
enum ALGORITHMIC_COMPLEXITY_SUCKS = 25;
|
enum ALGORITHMIC_COMPLEXITY_SUCKS = 25;
|
||||||
immutable size_t tokensEnd = min(tokens.length,
|
immutable size_t tokensEnd = min(tokens.length, ALGORITHMIC_COMPLEXITY_SUCKS);
|
||||||
ALGORITHMIC_COMPLEXITY_SUCKS);
|
|
||||||
int depth = 0;
|
int depth = 0;
|
||||||
auto open = new RedBlackTree!State;
|
auto open = new RedBlackTree!State;
|
||||||
open.insert(State(cast(size_t[])[], tokens[0 .. tokensEnd], depth,
|
open.insert(State(cast(size_t[])[], tokens[0 .. tokensEnd], depth, formatterConfig,
|
||||||
formatterConfig, currentLineLength, indentLevel));
|
currentLineLength, indentLevel));
|
||||||
State lowest;
|
State lowest;
|
||||||
GC.disable();
|
GC.disable();
|
||||||
scope(exit) GC.enable();
|
scope(exit) GC.enable();
|
||||||
|
@ -1729,8 +1752,8 @@ size_t[] chooseLineBreakTokens(size_t index, const Token[] tokens, const Formatt
|
||||||
current.breaks[] += index;
|
current.breaks[] += index;
|
||||||
return current.breaks;
|
return current.breaks;
|
||||||
}
|
}
|
||||||
foreach (next; validMoves(tokens[0 .. tokensEnd], current,
|
foreach (next; validMoves(tokens[0 .. tokensEnd], current, formatterConfig,
|
||||||
formatterConfig, currentLineLength, indentLevel, depth))
|
currentLineLength, indentLevel, depth))
|
||||||
{
|
{
|
||||||
open.insert(next);
|
open.insert(next);
|
||||||
}
|
}
|
||||||
|
@ -1824,8 +1847,8 @@ struct IndentStack
|
||||||
int size = 0;
|
int size = 0;
|
||||||
foreach (i; 1 .. j + 1)
|
foreach (i; 1 .. j + 1)
|
||||||
{
|
{
|
||||||
if ((i + 1 <= index && !isWrapIndent(arr[i]) && isTempIndent(arr[i])
|
if ((i + 1 <= index && !isWrapIndent(arr[i]) && isTempIndent(arr[i]) && (
|
||||||
&& (!isTempIndent(arr[i + 1]) || arr[i + 1] == tok!"switch")))
|
!isTempIndent(arr[i + 1]) || arr[i + 1] == tok!"switch")))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1844,7 +1867,7 @@ private:
|
||||||
IdType[256] arr;
|
IdType[256] arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
unittest
|
version (none) unittest
|
||||||
{
|
{
|
||||||
import std.string : format;
|
import std.string : format;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
|
||||||
|
FuncDeclaration* pFd = cast(FuncDeclaration*) dmd_aaGet(&arrayfuncs, cast(void*) ident);
|
||||||
|
FuncDeclaration fd = *pFd;
|
||||||
|
{
|
||||||
|
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"));
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
auto ed = new EnumDeclaration(loc, ident, memtype ? memtype.syntaxCopy() : null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void doStuff(const Token[] tokens, ref const State current,
|
||||||
|
const FormatterConfig* formatterConfig, int currentLineLength, int indentLevel,
|
||||||
|
int depth)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
|
@ -7,11 +7,9 @@ version (AArch64)
|
||||||
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
|
if (alpha < beta && alpha > golf && hotel < alpha && bravo >= charlie && echo < delta)
|
||||||
&& echo < delta)
|
|
||||||
{
|
{
|
||||||
if (alpha < beta && alpha > golf && hotel < alpha && bravo >= charlie
|
if (alpha < beta && alpha > golf && hotel < alpha && bravo >= charlie && echo < delta)
|
||||||
&& echo < delta)
|
|
||||||
{
|
{
|
||||||
if (alpha < beta && alpha > golf && hotel < alpha && bravo >= charlie
|
if (alpha < beta && alpha > golf && hotel < alpha && bravo >= charlie
|
||||||
&& echo < delta)
|
&& echo < delta)
|
||||||
|
|
|
@ -2,8 +2,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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
|
||||||
|
FuncDeclaration* pFd = cast(FuncDeclaration*) dmd_aaGet(&arrayfuncs, cast(void*) ident);
|
||||||
|
FuncDeclaration fd = *pFd;
|
||||||
|
{
|
||||||
|
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"));
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
auto ed = new EnumDeclaration(loc, ident, memtype ? memtype.syntaxCopy() : null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void doStuff(const Token[] tokens, ref const State current, const FormatterConfig* formatterConfig, int currentLineLength, int indentLevel, int depth)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
unittest {
|
||||||
|
|
||||||
|
FuncDeclaration* pFd = cast(FuncDeclaration*) dmd_aaGet(&arrayfuncs, cast(void*) ident);
|
||||||
|
FuncDeclaration fd = *pFd;
|
||||||
|
{
|
||||||
|
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"));
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
auto ed = new EnumDeclaration(loc, ident, memtype ? memtype.syntaxCopy() : null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void doStuff(const Token[] tokens, ref const State current,
|
||||||
|
const FormatterConfig* formatterConfig, int currentLineLength, int indentLevel,
|
||||||
|
int depth) {
|
||||||
|
return;
|
||||||
|
}
|
|
@ -4,10 +4,8 @@ version (AArch64) {
|
||||||
|
|
||||||
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
|
if (alpha < beta && alpha > golf && hotel < alpha && bravo >= charlie && echo < delta) {
|
||||||
&& 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
|
if (alpha < beta && alpha > golf && hotel < alpha && bravo >= charlie
|
||||||
&& echo < delta) {
|
&& echo < delta) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue