From bb3ee5df18891ea9dd4380b74c475bc0513faed1 Mon Sep 17 00:00:00 2001
From: Hackerpilot <briancschott@gmail.com>
Date: Mon, 27 Apr 2015 15:34:35 -0700
Subject: [PATCH] Fix #140

---
 libdparse                      |  2 +-
 src/dfmt/formatter.d           | 78 ++++++++++++++++++----------------
 src/dfmt/indentation.d         | 10 +++++
 tests/allman/issue0023.d.ref   |  1 +
 tests/allman/issue0051.d.d.ref |  0
 tests/allman/issue0054.d.ref   |  1 +
 tests/allman/issue0095.d.d.ref |  0
 tests/allman/issue0140.d.ref   |  6 +++
 tests/issue0140.d              |  6 +++
 tests/otbs/issue0023.d.ref     |  1 +
 tests/otbs/issue0027.d.ref     | 46 ++++++++++----------
 tests/otbs/issue0051.d.d.ref   |  0
 tests/otbs/issue0051.d.ref     | 12 +++---
 tests/otbs/issue0054.d.ref     |  1 +
 tests/otbs/issue0095.d.d.ref   |  0
 tests/otbs/issue0098.d.ref     |  4 +-
 tests/otbs/issue0140.d.ref     |  5 +++
 17 files changed, 104 insertions(+), 69 deletions(-)
 create mode 100644 tests/allman/issue0051.d.d.ref
 create mode 100644 tests/allman/issue0095.d.d.ref
 create mode 100644 tests/allman/issue0140.d.ref
 create mode 100644 tests/issue0140.d
 create mode 100644 tests/otbs/issue0051.d.d.ref
 create mode 100644 tests/otbs/issue0095.d.d.ref
 create mode 100644 tests/otbs/issue0140.d.ref

diff --git a/libdparse b/libdparse
index 256b979..ccb3d98 160000
--- a/libdparse
+++ b/libdparse
@@ -1 +1 @@
-Subproject commit 256b979f3b53c3367b6556c5b68e9cc76ceaf391
+Subproject commit ccb3d98996f89cfb35799aee6358e640f6f71f67
diff --git a/src/dfmt/formatter.d b/src/dfmt/formatter.d
index b28db08..c7ced79 100644
--- a/src/dfmt/formatter.d
+++ b/src/dfmt/formatter.d
@@ -475,7 +475,18 @@ private:
             linebreakHints = [];
             while (indents.topIs(tok!"enum"))
                 indents.pop();
-            newline();
+            if (config.dfmt_brace_style == BraceStyle.allman)
+            {
+                if (!currentIs(tok!"{"))
+                    newline();
+            }
+            else
+            {
+                if (currentIs(tok!"{"))
+                    indents.popTempIndents();
+                indentLevel = indents.indentSize;
+                newline();
+            }
         }
     }
 
@@ -518,31 +529,29 @@ private:
         }
         else
         {
-            if (!justAddedExtraNewline && !peekBackIsOneOf(false, tok!"{",
-                    tok!"}", tok!";", tok!";"))
+            indents.popWrapIndents();
+            if (indents.length && isTempIndent(indents.top))
+                indentLevel = indents.indentSize - 1;
+            else
+                indentLevel = indents.indentSize;
+
+            if (!peekBackIsSlashSlash())
             {
-                if (config.dfmt_brace_style != BraceStyle.allman)
-                {
-                    if (!astInformation.structInitStartLocations.canFindIndex(tokens[index].index)
-                            && !astInformation.funLitStartLocations.canFindIndex(
-                            tokens[index].index))
-                    {
-                        indents.popWrapIndents();
-                        indents.push(tok!"{");
-                        if (index == 1 || peekBackIsOneOf(true, tok!":", tok!"{",
-                                tok!"}", tok!")", tok!";"))
-                        {
-                            indentLevel = indents.indentSize - 1;
-                        }
-                    }
-                    write(" ");
-                }
-                else if (index > 0 && (!peekBackIs(tok!"comment")
-                        || tokens[index - 1].text[0 .. 2] != "//"))
+                if (config.dfmt_brace_style == BraceStyle.allman || peekBackIsOneOf(true, tok!"{", tok!"}"))
                     newline();
+                else if (!peekBackIsOneOf(true, tok!"{", tok!"}", tok!";"))
+                    write(" ");
+                writeToken();
             }
-            writeToken();
-            newline();
+            else
+            {
+                writeToken();
+                indents.popTempIndents();
+                indentLevel = indents.indentSize - 1;
+            }
+            indents.push(tok!"{");
+            if (!currentIs(tok!"{"))
+                newline();
             linebreakHints = [];
         }
     }
@@ -584,9 +593,9 @@ private:
                 currentLineLength = 0;
                 justAddedExtraNewline = true;
             }
-            if (config.dfmt_brace_style == BraceStyle.otbs && currentIs(tok!"else"))
+            if (config.dfmt_brace_style != BraceStyle.allman && currentIs(tok!"else"))
                 write(" ");
-            if (!peekIs(tok!",") && !peekIs(tok!")") && !peekIs(tok!";"))
+            if (!peekIs(tok!",") && !peekIs(tok!")") && !peekIs(tok!";") && !peekIs(tok!"{"))
             {
                 index++;
                 newline();
@@ -967,7 +976,7 @@ private:
         if (currentIs(tok!"comment") && index > 0 && current.line == tokenEndLine(tokens[index - 1]))
             return;
 
-        immutable bool hasCurrent = index + 1 < tokens.length;
+        immutable bool hasCurrent = index < tokens.length;
 
         if (niBraceDepth > 0 && !peekBackIsSlashSlash() && hasCurrent
                 && tokens[index].type == tok!"}" && !assumeSorted(
@@ -1031,16 +1040,13 @@ private:
                 if (l != -1)
                     indentLevel = l;
             }
-            else if (currentIs(tok!"{")
-                    && !astInformation.structInitStartLocations.canFindIndex(tokens[index].index)
-                    && !astInformation.funLitStartLocations.canFindIndex(tokens[index].index))
+            else if (currentIs(tok!"{"))
             {
                 indents.popWrapIndents();
-                indents.push(tok!"{");
-                if (index == 1 || peekBackIsOneOf(true, tok!":", tok!"{",
-                        tok!"}", tok!")", tok!";", tok!"identifier") || peekBackIsKeyword())
+                if (peekBackIsSlashSlash())
                 {
-                    indentLevel = indents.indentSize - 1;
+                    indents.popTempIndents();
+                    indentLevel = indents.indentSize;
                 }
             }
             else if (currentIs(tok!"}"))
@@ -1051,8 +1057,7 @@ private:
                     indentLevel = indents.indentToMostRecent(tok!"{");
                     indents.pop();
                 }
-                while (indents.length && isTempIndent(indents.top)
-                        && ((indents.top != tok!"if"
+                while (indents.topIsTemp() && ((indents.top != tok!"if"
                         && indents.top != tok!"version") || !peekIs(tok!"else")))
                 {
                     indents.pop();
@@ -1075,8 +1080,7 @@ private:
             }
             else
             {
-                while (indents.length && (peekBackIsOneOf(true, tok!"}",
-                        tok!";") && indents.top != tok!";") && isTempIndent(indents.top()))
+                while (indents.topIsTemp() && (peekBackIsOneOf(true, tok!"}", tok!";") && indents.top != tok!";"))
                 {
                     indents.pop();
                 }
diff --git a/src/dfmt/indentation.d b/src/dfmt/indentation.d
index a34af53..2322a24 100644
--- a/src/dfmt/indentation.d
+++ b/src/dfmt/indentation.d
@@ -75,6 +75,16 @@ struct IndentStack
         return index > 0 && arr[index] == type;
     }
 
+    bool topIsTemp()
+    {
+        return index > 0 && index < arr.length && isTempIndent(arr[index]);
+    }
+
+    bool topIsWrap()
+    {
+        return index > 0 && index < arr.length && isWrapIndent(arr[index]);
+    }
+
     bool topIsOneOf(IdType[] types...) const pure nothrow @safe @nogc
     {
         if (index <= 0)
diff --git a/tests/allman/issue0023.d.ref b/tests/allman/issue0023.d.ref
index 4691e95..3efacc2 100644
--- a/tests/allman/issue0023.d.ref
+++ b/tests/allman/issue0023.d.ref
@@ -32,4 +32,5 @@ string generateFixedLengthCases()
         "=>", ">", ">=", ">>", ">>=", ">>>", ">>>=", "?", "@", "[", "]", "^",
         "^=", "^^", "^^=", "{", "|", "|=", "||", "}", "~", "~="
     ];
+
 }
diff --git a/tests/allman/issue0051.d.d.ref b/tests/allman/issue0051.d.d.ref
new file mode 100644
index 0000000..e69de29
diff --git a/tests/allman/issue0054.d.ref b/tests/allman/issue0054.d.ref
index 397f972..33ed5de 100644
--- a/tests/allman/issue0054.d.ref
+++ b/tests/allman/issue0054.d.ref
@@ -24,4 +24,5 @@ struct ClassFlags
     alias isAbstract = Enum.isAbstract;
     alias isCPPclass = Enum.isCPPclass;
     alias hasDtor = Enum.hasDtor;
+
 }
diff --git a/tests/allman/issue0095.d.d.ref b/tests/allman/issue0095.d.d.ref
new file mode 100644
index 0000000..e69de29
diff --git a/tests/allman/issue0140.d.ref b/tests/allman/issue0140.d.ref
new file mode 100644
index 0000000..b3e0c70
--- /dev/null
+++ b/tests/allman/issue0140.d.ref
@@ -0,0 +1,6 @@
+class C
+{
+
+    int foo;
+
+}
diff --git a/tests/issue0140.d b/tests/issue0140.d
new file mode 100644
index 0000000..001b035
--- /dev/null
+++ b/tests/issue0140.d
@@ -0,0 +1,6 @@
+class C
+{
+
+	int foo;
+
+}
diff --git a/tests/otbs/issue0023.d.ref b/tests/otbs/issue0023.d.ref
index 7f7d4ad..0f2fa9a 100644
--- a/tests/otbs/issue0023.d.ref
+++ b/tests/otbs/issue0023.d.ref
@@ -31,4 +31,5 @@ string generateFixedLengthCases() {
         "=>", ">", ">=", ">>", ">>=", ">>>", ">>>=", "?", "@", "[", "]", "^",
         "^=", "^^", "^^=", "{", "|", "|=", "||", "}", "~", "~="
     ];
+
 }
diff --git a/tests/otbs/issue0027.d.ref b/tests/otbs/issue0027.d.ref
index ba1d859..c37499f 100644
--- a/tests/otbs/issue0027.d.ref
+++ b/tests/otbs/issue0027.d.ref
@@ -7,38 +7,38 @@ SignExtendedNumber opMul(const SignExtendedNumber a) const {
 
 unittest {
     if (Port.isNan(r1) || Port.isNan(r2)) // if unordered
-     {
-        }
+    {
+    }
 
-        while (cur && cur.ty == Tsarray) // sizes of dimensions
-         {
-                TypeSArray sa = cast(TypeSArray) cur;
-                mangleNumber(sa.dim ? sa.dim.toInteger() : 0);
-                cur = cur.nextOf();
-            }
+    while (cur && cur.ty == Tsarray) // sizes of dimensions
+    {
+        TypeSArray sa = cast(TypeSArray) cur;
+        mangleNumber(sa.dim ? sa.dim.toInteger() : 0);
+        cur = cur.nextOf();
+    }
 
-            if (fd) {
-                /* Use storage_class2 instead of storage_class otherwise when we do .di generation
+    if (fd) {
+        /* Use storage_class2 instead of storage_class otherwise when we do .di generation
 		* we'll wind up with 'const const' rather than 'const'.
 		*/
-                /* Don't think we need to worry about mutually exclusive storage classes here
+        /* Don't think we need to worry about mutually exclusive storage classes here
 		*/
-                fd.storage_class2 |= stc;
-            }
+        fd.storage_class2 |= stc;
+    }
 
-        }
+}
 
-        SignExtendedNumber opMul(const SignExtendedNumber a) const {
-            /* Special handling for zeros:
+SignExtendedNumber opMul(const SignExtendedNumber a) const {
+    /* Special handling for zeros:
     */
 
-            //  like 0x10 * 0x10 == 0x100 == 0.
-        }
+    //  like 0x10 * 0x10 == 0x100 == 0.
+}
 
-        // Because int64_t and friends may be any integral type of the
-        // correct size, we have to explicitly ask for the correct
-        // integer type to get the correct mangling with ddmd
+// Because int64_t and friends may be any integral type of the
+// correct size, we have to explicitly ask for the correct
+// integer type to get the correct mangling with ddmd
 
-        // Be careful not to care about sign when using dinteger_t
-        // use this instead of integer_t to
+// Be careful not to care about sign when using dinteger_t
+// use this instead of integer_t to
 // avoid conflicts with system #include's
diff --git a/tests/otbs/issue0051.d.d.ref b/tests/otbs/issue0051.d.d.ref
new file mode 100644
index 0000000..e69de29
diff --git a/tests/otbs/issue0051.d.ref b/tests/otbs/issue0051.d.ref
index 5660d65..91b3eeb 100644
--- a/tests/otbs/issue0051.d.ref
+++ b/tests/otbs/issue0051.d.ref
@@ -2,11 +2,11 @@ void f() {
     if (a) {
     }
     else // wat
-     {
-            if (!is_temp_arg_ref) {
-                if (global.params.isOSX)
-                    buf.writeByte('_');
-            }
+    {
+        if (!is_temp_arg_ref) {
+            if (global.params.isOSX)
+                buf.writeByte('_');
         }
-        return;
+    }
+    return;
 }
diff --git a/tests/otbs/issue0054.d.ref b/tests/otbs/issue0054.d.ref
index 6ecadf9..464dfb9 100644
--- a/tests/otbs/issue0054.d.ref
+++ b/tests/otbs/issue0054.d.ref
@@ -22,4 +22,5 @@ struct ClassFlags {
     alias isAbstract = Enum.isAbstract;
     alias isCPPclass = Enum.isCPPclass;
     alias hasDtor = Enum.hasDtor;
+
 }
diff --git a/tests/otbs/issue0095.d.d.ref b/tests/otbs/issue0095.d.d.ref
new file mode 100644
index 0000000..e69de29
diff --git a/tests/otbs/issue0098.d.ref b/tests/otbs/issue0098.d.ref
index 832fe56..ecb4ff9 100644
--- a/tests/otbs/issue0098.d.ref
+++ b/tests/otbs/issue0098.d.ref
@@ -1,6 +1,6 @@
 unittest {
     if (!fdmatch)
         goto Lfd; // comment
-     {
-        }
+    {
+    }
 }
diff --git a/tests/otbs/issue0140.d.ref b/tests/otbs/issue0140.d.ref
new file mode 100644
index 0000000..471bf96
--- /dev/null
+++ b/tests/otbs/issue0140.d.ref
@@ -0,0 +1,5 @@
+class C {
+
+    int foo;
+
+}