From d8f9cfeae1a67b6cff2bb09f63a2ff04cc39d28a Mon Sep 17 00:00:00 2001
From: Stefan Koch <stefan.koch@sociomantic.com>
Date: Thu, 7 Dec 2017 12:25:32 +0100
Subject: [PATCH] Put a space behind static and shared constructors as well

---
 src/dfmt/ast_info.d  | 36 ++++++++++++++++++++++++++++++++++--
 src/dfmt/formatter.d | 26 ++++++++++++++++++++++++--
 2 files changed, 58 insertions(+), 4 deletions(-)

diff --git a/src/dfmt/ast_info.d b/src/dfmt/ast_info.d
index 1dec9ca..e2fef35 100644
--- a/src/dfmt/ast_info.d
+++ b/src/dfmt/ast_info.d
@@ -31,6 +31,8 @@ struct ASTInformation
         sort(contractLocations);
         sort(constraintLocations);
         sort(constructorDestructorLocations);
+        sort(staticConstructorDestructorLocations);
+        sort(sharedStaticConstructorDestructorLocations);
     }
 
     /// Locations of end braces for struct bodies
@@ -75,6 +77,12 @@ struct ASTInformation
     /// Locations of template constraint "if" tokens
     size_t[] constraintLocations;
 
+    /// Locations of constructor/destructor "shared" tokens ?
+    size_t[] sharedStaticConstructorDestructorLocations;
+
+    /// Locations of constructor/destructor "static" tokens ?
+    size_t[] staticConstructorDestructorLocations;
+
     /// Locations of constructor/destructor "this" tokens ?
     size_t[] constructorDestructorLocations;
 }
@@ -97,13 +105,37 @@ final class FormatVisitor : ASTVisitor
         arrayInitializer.accept(this);
     }
 
-    override void visit(const Constructor constructor)
+    override void visit (const SharedStaticConstructor sharedStaticConstructor)
+    {
+        astInformation.sharedStaticConstructorDestructorLocations ~= sharedStaticConstructor.location;
+        sharedStaticConstructor.accept(this);
+    }
+
+    override void visit (const SharedStaticDestructor sharedStaticDestructor)
+    {
+        astInformation.sharedStaticConstructorDestructorLocations ~= sharedStaticDestructor.location;
+        sharedStaticDestructor.accept(this);
+    }
+
+    override void visit (const StaticConstructor staticConstructor)
+    {
+        astInformation.staticConstructorDestructorLocations ~= staticConstructor.location;
+        staticConstructor.accept(this);
+    }
+
+    override void visit (const StaticDestructor staticDestructor)
+    {
+        astInformation.staticConstructorDestructorLocations ~= staticDestructor.location;
+        staticDestructor.accept(this);
+    }
+
+    override void visit (const Constructor constructor)
     {
         astInformation.constructorDestructorLocations ~= constructor.location;
         constructor.accept(this);
     }
 
-    override void visit(const Destructor destructor)
+    override void visit (const Destructor destructor)
     {
         astInformation.constructorDestructorLocations ~= destructor.index;
         destructor.accept(this);
diff --git a/src/dfmt/formatter.d b/src/dfmt/formatter.d
index 603e27e..14c56d4 100644
--- a/src/dfmt/formatter.d
+++ b/src/dfmt/formatter.d
@@ -171,6 +171,9 @@ private:
     /// True if we're in an ASM block
     bool inAsm;
 
+    /// True if the next "this" should have a space behind it
+    bool thisSpace;
+
     void formatStep()
     {
         import std.range : assumeSorted;
@@ -269,10 +272,11 @@ private:
             const thisIndex = current.index;
             formatKeyword();
             if (config.dfmt_space_before_function_parameters
-                && astInformation.constructorDestructorLocations
-                    .canFindIndex(thisIndex))
+                && (thisSpace || astInformation.constructorDestructorLocations
+                    .canFindIndex(thisIndex)))
             {
                 write(" ");
+                thisSpace = false;
             }
         }
         else if (isKeyword(current.type))
@@ -1047,6 +1051,24 @@ private:
                     write(" ");
             }
             break;
+        case tok!"static":
+            {
+                if (astInformation.staticConstructorDestructorLocations
+                    .canFindIndex(current.index))
+                {
+                    thisSpace = true;
+                }
+            }
+            goto default;
+        case tok!"shared":
+            {
+                if (astInformation.sharedStaticConstructorDestructorLocations
+                    .canFindIndex(current.index))
+                {
+                    thisSpace = true;
+                }
+            }
+            goto default;
         default:
             if (peekBackIs(tok!"identifier"))
                 write(" ");