From 9a8c0aa520d746e5168947f9c19939a8e3fbf87e Mon Sep 17 00:00:00 2001
From: Starbeamrainbowlabs <sbrl@starbeamrainbowlabs.com>
Date: Thu, 4 Aug 2016 12:15:15 +0100
Subject: [PATCH] Add support for namespaces

---
 cscz/ClassGenerator.cs | 74 ++++++++++++++++++++++++++++--------------
 1 file changed, 49 insertions(+), 25 deletions(-)

diff --git a/cscz/ClassGenerator.cs b/cscz/ClassGenerator.cs
index 3c4fcef..ad6bae9 100644
--- a/cscz/ClassGenerator.cs
+++ b/cscz/ClassGenerator.cs
@@ -4,6 +4,7 @@ using System.Text;
 using System.Text.RegularExpressions;
 using System.Diagnostics;
 using System.IO;
+using System.Runtime.ConstrainedExecution;
 
 namespace cscz
 {
@@ -42,6 +43,7 @@ namespace cscz
 		public List<string> Signatures = new List<string>();
 
 		public string ClassName = "Carrot";
+		public string Namespace = string.Empty;
 
 		public GenerationMode GenerationMode = GenerationMode.PublicVariables;
 
@@ -87,6 +89,12 @@ namespace cscz
 				{
 					// It's the class name
 					ClassName = UppercaseFirstLetter(nextLine.TrimStart(new char[] { '#' })).Trim();
+					// Parse the namespace, if one is present
+					if(ClassName.Contains("."))
+					{
+						Namespace = ClassName.Substring(0, ClassName.LastIndexOf("."));
+						ClassName = ClassName.Substring(ClassName.LastIndexOf(".") + 1);
+					}
 				}
 				else
 				{
@@ -97,22 +105,23 @@ namespace cscz
 
 		public override string ToString()
 		{
-			StringBuilder result = new StringBuilder();
+			StringWriter usingStatements = new StringWriter();
 
-			// Using statements
+			// Generate the using statements
 			foreach(string usingStatement in UsingStatements)
-				result.AppendLine(string.Format("using {0};", expandUsingShortcut(usingStatement)));
-			
-			result.AppendLine();
+				usingStatements.WriteLine("using {0};", expandUsingShortcut(usingStatement));
+
+			// Generate the class itself
+			StringWriter classCode = new StringWriter();
 
 			// Class name
-			result.AppendLine(string.Format("class {0} ", ClassName));
-			result.AppendLine("{");
+			classCode.WriteLine("class {0} ", ClassName);
+			classCode.WriteLine("{");
 
 			// Class body parts declaration
-			StringBuilder properties = new StringBuilder();
-			StringBuilder constructorSignature = new StringBuilder(string.Format("\tpublic {0}(", ClassName));
-			StringBuilder constructorBody = new StringBuilder();
+			StringBuilder constructorSignature = new StringBuilder(string.Format("\tpublic {0}(", ClassName)); // This has to be a StringBuilder because of the Remove() class later on
+			StringWriter properties = new StringWriter();
+			StringWriter constructorBody = new StringWriter();
 
 			// Data member signature handling
 			foreach (string signature in Signatures)
@@ -127,39 +136,54 @@ namespace cscz
 				if (CreateProperties)
 				{
 					// Private data member
-					result.AppendLine(string.Format("\tprivate {0} {1};", datatypeName, privateDataMemberName));
+					classCode.WriteLine("\tprivate {0} {1};", datatypeName, privateDataMemberName);
 
 					// Public property associated with above private data member
-					properties.AppendLine(string.Format("\tpublic {0} {1}", datatypeName, publicDataMemberName));
-					properties.AppendLine(string.Format("\t{{"));
-					properties.AppendLine(string.Format("\t\tget {{ return {0}; }}", privateDataMemberName));
-					properties.AppendLine(string.Format("\t\tset {{ {0} = value; }}", privateDataMemberName));
-					properties.AppendLine(string.Format("\t}}"));
+					properties.WriteLine("\tpublic {0} {1}", datatypeName, publicDataMemberName);
+					properties.WriteLine("\t{{");
+					properties.WriteLine("\t\tget {{ return {0}; }}", privateDataMemberName);
+					properties.WriteLine("\t\tset {{ {0} = value; }}", privateDataMemberName);
+					properties.WriteLine("\t}}");
 
 					// Constructor body
-					constructorBody.AppendLine(string.Format("\t\t{0} = in{0};", publicDataMemberName));
+					constructorBody.WriteLine("\t\t{0} = in{0};", publicDataMemberName);
 				}
 				else
 				{
 					// Constuctor body
-					result.AppendLine(string.Format("\tpublic {0} {1};", datatypeName, publicDataMemberName));
-					constructorBody.AppendLine(string.Format("\t\t{0} = in{0};", publicDataMemberName));
+					classCode.WriteLine("\tpublic {0} {1};", datatypeName, publicDataMemberName);
+					constructorBody.WriteLine("\t\t{0} = in{0};", publicDataMemberName);
 				}
 			}
 
 			// Add the properties to the output
-			result.AppendLine(properties.ToString());
+			classCode.WriteLine(properties.ToString());
 
 			// Add the constructor to the output
 			constructorSignature.Remove(constructorSignature.Length - 2, 2); // Remove the last ", "
 			constructorSignature.Append(")");
-			result.AppendLine(constructorSignature.ToString());
-			result.AppendLine("\t{");
-			result.Append(constructorBody.ToString());
-			result.AppendLine("\t}");
+			classCode.WriteLine(constructorSignature.ToString());
+			classCode.WriteLine("\t{");
+			classCode.Write(constructorBody.ToString());
+			classCode.WriteLine("\t}");
 
 			// Close the class off and end the file
-			result.AppendLine("}");
+			classCode.WriteLine("}");
+
+			StringWriter result = new StringWriter();
+			result.WriteLine(usingStatements);
+
+			if(Namespace == string.Empty)
+			{
+				result.WriteLine(classCode);
+			}
+			else
+			{
+				result.WriteLine("namespace {0}", Namespace);
+				result.WriteLine("{");
+				result.WriteLine("\t" + classCode.ToString().Replace("\n", "\n\t"));
+				result.WriteLine("}");
+			}
 
 			return result.ToString();
 		}
