Massive switch statement rework. Fixes #80

This commit is contained in:
Hackerpilot 2015-03-10 03:03:08 -07:00
parent cb5ca659b1
commit cade56450c
6 changed files with 103 additions and 116 deletions

View File

@ -321,6 +321,8 @@ private:
} }
else if (!currentIs(tok!"{") && !currentIs(tok!"comment")) else if (!currentIs(tok!"{") && !currentIs(tok!"comment"))
{ {
if (ifIndents.length)
ifIndents.pop();
pushIndent(); pushIndent();
newline(); newline();
} }
@ -434,31 +436,38 @@ private:
else if (!assumeSorted(astInformation.caseEndLocations) else if (!assumeSorted(astInformation.caseEndLocations)
.equalRange(current.index).empty) .equalRange(current.index).empty)
{ {
if (!(peekIs(tok!"case", false) || peekIs(tok!"default", false) indentLevel++;
|| peekIs(tok!"}") || peekIsLabel()))
{
indentLevel++;
}
writeToken(); writeToken();
newline(); newline();
} }
else if (peekBackIs(tok!"identifier") && (peekBack2Is(tok!";", true) else if (peekBackIs(tok!"identifier") && (index <= 1
|| peekBack2Is(tok!"}", true) || peekBack2Is(tok!"{", true))) || peekBack2Is(tok!"{", true) || peekBack2Is(tok!"}", true)
|| peekBack2Is(tok!";", true) || peekBack2Is(tok!":", true))
&& !peekIs(tok!"{") && !(isBlockHeader(1) && !peekIs(tok!"if")))
{ {
if (tempIndent < 0) indentLevel++;
tempIndent = 0;
else
popIndent();
writeToken(); writeToken();
if (isBlockHeader() && !currentIs(tok!"if")) newline();
write(" ");
else if (!currentIs(tok!"{"))
newline();
} }
else else
{ {
write(" : "); if (peekIs(tok!".."))
index++; writeToken();
else if (peekIs(tok!"{"))
{
writeToken();
pushIndent();
}
else if (isBlockHeader(1) && !peekIs(tok!"if"))
{
writeToken();
write(" ");
}
else
{
write(" : ");
index++;
}
} }
break; break;
case tok!"]": case tok!"]":
@ -467,18 +476,17 @@ private:
write(" "); write(" ");
break; break;
case tok!";": case tok!";":
if (peekIs(tok!"else")) if (peekIs(tok!"else") && ifIndents.length)
{
tempIndent = ifIndents.top(); tempIndent = ifIndents.top();
if (ifIndents.length) else if (!peekIs(tok!"}"))
ifIndents.pop();
}
else if (braceIndents.top() < tempIndent)
{ {
if (!peekIs(tok!"}")) if (ifIndents.length)
tempIndent = 0; {
tempIndent = ifIndents.top();
ifIndents.pop();
}
else else
popIndent(); tempIndent = 0;
} }
writeToken(); writeToken();
linebreakHints = []; linebreakHints = [];
@ -681,7 +689,8 @@ private:
{ {
if (currentIs(tok!"{")) if (currentIs(tok!"{"))
{ {
braceIndents.push(tempIndent); braceIndents.push(indentLevel);
braceTempIndents.push(tempIndent);
depth++; depth++;
if (assumeSorted(astInformation.structInitStartLocations) if (assumeSorted(astInformation.structInitStartLocations)
.equalRange(tokens[index].index).length) .equalRange(tokens[index].index).length)
@ -708,7 +717,6 @@ private:
} }
else if (currentIs(tok!"}")) else if (currentIs(tok!"}"))
{ {
braceIndents.pop();
depth--; depth--;
if (assumeSorted(astInformation.structInitEndLocations) if (assumeSorted(astInformation.structInitEndLocations)
.equalRange(tokens[index].index).length) .equalRange(tokens[index].index).length)
@ -731,8 +739,6 @@ private:
if (config.braceStyle == BraceStyle.otbs && currentIs(tok!"else")) if (config.braceStyle == BraceStyle.otbs && currentIs(tok!"else"))
write(" "); write(" ");
index++; index++;
if (peekIs(tok!"case") || peekIs(tok!"default"))
indentLevel--;
if (ifIndents.length >= 2 && ifIndents.top == tempIndent && !currentIs(tok!"else")) if (ifIndents.length >= 2 && ifIndents.top == tempIndent && !currentIs(tok!"else"))
{ {
ifIndents.pop(); ifIndents.pop();
@ -813,7 +819,6 @@ private:
formatStep(); formatStep();
} }
while (index < tokens.length && depth > 0); while (index < tokens.length && depth > 0);
// popIndent();
tempIndent = t; tempIndent = t;
linebreakHints = []; linebreakHints = [];
} }
@ -835,93 +840,16 @@ private:
void formatSwitch() void formatSwitch()
{ {
immutable l = indentLevel; switchIndents.push(indentLevel);
writeToken(); // switch writeToken(); // switch
write(" "); write(" ");
writeParens(true); writeParens(true);
if (currentIs(tok!"with")) while (currentIs(tok!"with"))
{ {
writeToken(); writeToken();
write(" "); write(" ");
writeParens(true); writeParens(true);
} }
if (!currentIs(tok!"{"))
return;
if (config.braceStyle == BraceStyle.otbs)
write(" ");
else
newline();
writeToken();
if (!currentIs(tok!"case") && !currentIs(tok!"default") && !currentIs(tok!"}"))
indentLevel++;
newline();
while (index < tokens.length)
{
if (currentIs(tok!"}"))
{
indentLevel = l;
indent();
writeToken();
newline();
return;
}
else if (currentIs(tok!";") && peekIs(tok!"}", false))
{
writeToken();
newline();
indentLevel = l;
writeToken();
newline();
return;
}
else if (currentIs(tok!"case"))
{
writeToken();
write(" ");
}
else if (currentIs(tok!":"))
{
if (peekIs(tok!".."))
{
writeToken();
write(" ");
writeToken();
write(" ");
}
else if (peekIsLabel())
{
writeToken();
pushIndent();
newline();
writeToken();
writeToken();
pushIndent();
newline();
}
else
goto peek;
}
else if (currentIs(tok!"}", false))
break;
else
{
peek:
if (peekIs(tok!"case", false) || peekIs(tok!"default", false)
|| peekIs(tok!"}", false))
{
indentLevel = l;
if (peekIsLabel())
pushIndent();
}
formatStep();
}
}
indentLevel = l;
if (currentIs(tok!"}"))
{
writeToken();
newline();
}
} }
int currentTokenLength() pure @safe @nogc int currentTokenLength() pure @safe @nogc
@ -1089,14 +1017,30 @@ private:
currentLineLength = 0; currentLineLength = 0;
if (hasCurrent) if (hasCurrent)
{ {
bool switchLabel = false;
if (switchIndents.length && (currentIs(tok!"case") || currentIs(tok!"default")
|| (currentIs(tok!"identifier") && peekIs(tok!":"))))
{
indentLevel = switchIndents.top();
switchLabel = true;
}
if (currentIs(tok!"}")) if (currentIs(tok!"}"))
{ {
tempIndent = braceIndents.top(); if (braceIndents.length)
indentLevel--; {
assert (braceTempIndents.length);
indentLevel = braceIndents.top();
tempIndent = braceTempIndents.top();
braceIndents.pop();
braceTempIndents.pop();
}
if (switchIndents.length && indentLevel == switchIndents.top)
switchIndents.pop();
} }
else if ((!assumeSorted(astInformation.attributeDeclarationLines) else if ((!assumeSorted(astInformation.attributeDeclarationLines)
.equalRange(current.line).empty) || (currentIs(tok!"identifier") .equalRange(current.line).empty) || (!switchLabel
&& peekIs(tok!":") && (!isBlockHeader(2) || peek2Is(tok!"if")))) && currentIs(tok!"identifier") && peekIs(tok!":")
&& (!isBlockHeader(2) || peek2Is(tok!"if"))))
{ {
tempIndent--; tempIndent--;
} }
@ -1162,7 +1106,9 @@ private:
size_t[] linebreakHints; size_t[] linebreakHints;
FixedStack ifIndents; FixedStack ifIndents;
FixedStack braceTempIndents;
FixedStack braceIndents; FixedStack braceIndents;
FixedStack switchIndents;
/// Configuration /// Configuration
FormatterConfig* config; FormatterConfig* config;

View File

@ -3,7 +3,7 @@ unittest
switch (something) with (stuff){ switch (something) with (stuff){
case 1: case 2: case 1: case 2:
label:doStuff(); label:doStuff();
case 3: case 3: .. case 4:
doOtherStuff(); doOtherStuff();
goto label; goto label;
default: default:

View File

@ -6,7 +6,7 @@ unittest
case 2: case 2:
label: label:
doStuff(); doStuff();
case 3: case 3: .. case 4:
doOtherStuff(); doOtherStuff();
goto label; goto label;
default: default:

13
tests/issue0080.d Normal file
View File

@ -0,0 +1,13 @@
unittest
{
switch (x)
{
case a:
return;
version (A)
{
case b:
return;
}
}
}

13
tests/issue0080.d.ref Normal file
View File

@ -0,0 +1,13 @@
unittest
{
switch (x)
{
case a:
return;
version (A)
{
case b:
return;
}
}
}

View File

@ -1,3 +1,18 @@
unittest
{
if (0)
if (0)
{
}
else if (0)
{
}
else
{
}
doSomething();
}
unittest unittest
{ {
if (0) if (0)