Rearrange wrapping code to work around code generation bug in DMD
This commit is contained in:
parent
fa27b6c680
commit
076b4bc8c4
|
@ -9,8 +9,6 @@ import std.d.lexer;
|
||||||
import dfmt.tokens;
|
import dfmt.tokens;
|
||||||
import dfmt.config;
|
import dfmt.config;
|
||||||
|
|
||||||
version = WTF_DMD;
|
|
||||||
|
|
||||||
struct State
|
struct State
|
||||||
{
|
{
|
||||||
this(uint breaks, const Token[] tokens, immutable short[] depths,
|
this(uint breaks, const Token[] tokens, immutable short[] depths,
|
||||||
|
@ -18,24 +16,30 @@ struct State
|
||||||
{
|
{
|
||||||
import std.math : abs;
|
import std.math : abs;
|
||||||
import core.bitop : popcnt, bsf;
|
import core.bitop : popcnt, bsf;
|
||||||
import std.algorithm : min;
|
import std.algorithm : min, map, sum;
|
||||||
import std.algorithm : map, sum;
|
|
||||||
|
|
||||||
// TODO: Figure out what is going on here.
|
immutable int remainingCharsMultiplier = config.columnHardLimit - config.columnSoftLimit;
|
||||||
version (WTF_DMD)
|
immutable int newlinePenalty = remainingCharsMultiplier * 20;
|
||||||
|
|
||||||
|
this.breaks = breaks;
|
||||||
|
this._cost = 0;
|
||||||
|
this._solved = true;
|
||||||
|
int ll = currentLineLength;
|
||||||
|
|
||||||
|
if (breaks == 0)
|
||||||
{
|
{
|
||||||
enum int remainingCharsMultiplier = 40;
|
immutable int l = currentLineLength + tokens.map!(a => tokenLength(a)).sum();
|
||||||
enum int newlinePenalty = 800;
|
if (l > config.columnSoftLimit)
|
||||||
|
{
|
||||||
|
immutable int longPenalty = (l - config.columnSoftLimit) * remainingCharsMultiplier;
|
||||||
|
this._cost += longPenalty;
|
||||||
|
this._solved = longPenalty < newlinePenalty;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
this._solved = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
immutable int remainingCharsMultiplier = config.columnHardLimit - config.columnSoftLimit;
|
|
||||||
immutable int newlinePenalty = remainingCharsMultiplier * 20;
|
|
||||||
assert(remainingCharsMultiplier == 40);
|
|
||||||
assert(newlinePenalty == 800);
|
|
||||||
}
|
|
||||||
|
|
||||||
int cost = 0;
|
|
||||||
for (size_t i = 0; i != uint.sizeof * 8; ++i)
|
for (size_t i = 0; i != uint.sizeof * 8; ++i)
|
||||||
{
|
{
|
||||||
if (((1 << i) & breaks) == 0)
|
if (((1 << i) & breaks) == 0)
|
||||||
|
@ -43,50 +47,33 @@ struct State
|
||||||
immutable b = tokens[i].type;
|
immutable b = tokens[i].type;
|
||||||
immutable p = abs(depths[i]);
|
immutable p = abs(depths[i]);
|
||||||
immutable bc = breakCost(b) * (p == 0 ? 1 : p * 2);
|
immutable bc = breakCost(b) * (p == 0 ? 1 : p * 2);
|
||||||
cost += bc;
|
this._cost += bc;
|
||||||
}
|
}
|
||||||
int ll = currentLineLength;
|
|
||||||
bool solved = true;
|
|
||||||
if (breaks == 0)
|
|
||||||
{
|
|
||||||
immutable int l = currentLineLength + tokens.map!(a => tokenLength(a)).sum();
|
|
||||||
cost = l;
|
|
||||||
if (l > config.columnSoftLimit)
|
|
||||||
{
|
|
||||||
immutable int longPenalty = (l - config.columnSoftLimit) * remainingCharsMultiplier;
|
|
||||||
cost += longPenalty;
|
|
||||||
solved = longPenalty < newlinePenalty;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
solved = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
foreach (_; 0 .. uint.sizeof * 8)
|
foreach (_; 0 .. uint.sizeof * 8)
|
||||||
{
|
{
|
||||||
immutable size_t k = breaks >>> i;
|
immutable uint k = breaks >>> i;
|
||||||
immutable bool b = k == 0;
|
immutable bool b = k == 0;
|
||||||
immutable size_t j = min(i + bsf(k) + 1, tokens.length);
|
immutable size_t j = min(i + bsf(k) + 1, tokens.length);
|
||||||
ll += tokens[i .. j].map!(a => tokenLength(a)).sum();
|
ll += tokens[i .. j].map!(a => tokenLength(a)).sum();
|
||||||
|
if (ll > config.columnSoftLimit)
|
||||||
|
{
|
||||||
|
immutable int longPenalty = (ll - config.columnSoftLimit) * remainingCharsMultiplier;
|
||||||
|
this._cost += longPenalty;
|
||||||
|
}
|
||||||
if (ll > config.columnHardLimit)
|
if (ll > config.columnHardLimit)
|
||||||
{
|
{
|
||||||
solved = false;
|
this._solved = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (ll > config.columnSoftLimit)
|
|
||||||
cost += (ll - config.columnSoftLimit) * remainingCharsMultiplier;
|
|
||||||
i = j;
|
i = j;
|
||||||
ll = indentLevel * config.indentSize;
|
ll = indentLevel * config.indentSize;
|
||||||
if (b)
|
if (b)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cost += popcnt(breaks) * newlinePenalty;
|
this._cost += popcnt(breaks) * newlinePenalty;
|
||||||
|
|
||||||
this.breaks = breaks;
|
|
||||||
this._cost = cost;
|
|
||||||
this._solved = solved;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int cost() const pure nothrow @safe @property
|
int cost() const pure nothrow @safe @property
|
||||||
|
@ -103,13 +90,13 @@ struct State
|
||||||
{
|
{
|
||||||
import core.bitop : bsf, popcnt;
|
import core.bitop : bsf, popcnt;
|
||||||
|
|
||||||
if (cost < other.cost || (cost == other.cost && ((popcnt(breaks)
|
if (_cost < other._cost || (_cost == other._cost && ((popcnt(breaks)
|
||||||
&& popcnt(other.breaks) && bsf(breaks) > bsf(other.breaks))
|
&& popcnt(other.breaks) && bsf(breaks) > bsf(other.breaks))
|
||||||
|| (_solved && !other.solved))))
|
|| (_solved && !other.solved))))
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return other.cost > _cost;
|
return other._cost > _cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool opEquals(ref const State other) const pure nothrow @safe
|
bool opEquals(ref const State other) const pure nothrow @safe
|
||||||
|
@ -149,8 +136,8 @@ size_t[] chooseLineBreakTokens(size_t index, const Token[] tokens,
|
||||||
enum ALGORITHMIC_COMPLEXITY_SUCKS = uint.sizeof * 8;
|
enum ALGORITHMIC_COMPLEXITY_SUCKS = uint.sizeof * 8;
|
||||||
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],
|
open.insert(State(0, tokens[0 .. tokensEnd], depths[0 .. tokensEnd], config,
|
||||||
config, currentLineLength, indentLevel));
|
currentLineLength, indentLevel));
|
||||||
State lowest;
|
State lowest;
|
||||||
while (!open.empty)
|
while (!open.empty)
|
||||||
{
|
{
|
||||||
|
@ -184,7 +171,6 @@ void validMoves(OR)(auto ref OR output, const Token[] tokens,
|
||||||
if (!isBreakToken(token.type) || (((1 << i) & current) != 0))
|
if (!isBreakToken(token.type) || (((1 << i) & current) != 0))
|
||||||
continue;
|
continue;
|
||||||
immutable uint breaks = current | (1 << i);
|
immutable uint breaks = current | (1 << i);
|
||||||
output.insert(State(breaks, tokens, depths, config,
|
output.insert(State(breaks, tokens, depths, config, currentLineLength, indentLevel));
|
||||||
currentLineLength, indentLevel));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue