using System; using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; using System.Diagnostics; using System.IO; namespace cscz { public enum GenerationMode { PrivateVariablesWithProperties, PublicVariables } public class ClassGenerator { /// /// A mapping of namespaces to using shortcuts. /// public Dictionary UsingShortcuts = new Dictionary() { { "c", "System.Collections.Generic" }, { "cc", "System.Collections.Concurrent" }, { "r", "System.Text.RegularExpressions" }, { "n", "System.Net" }, { "s", "System.Net.Sockets" }, { "x", "Microsoft.Xna.Framework" }, { "xg", "Microsoft.Xna.Framework.Graphics" }, { "xs", "Microsoft.Xna.Framework.Storage" }, { "xi", "Microsoft.Xna.Framework.Input" }, { "oo", "OpenTK.Graphics.OpenGL" }, }; /// /// The using statements to add to the generated class. /// public List UsingStatements = new List() { "System" }; public List Signatures = new List(); public string ClassName = "Carrot"; public GenerationMode GenerationMode = GenerationMode.PublicVariables; /// /// Whether to make data members private and create public properties for them instead of making the /// data members public. /// This is read only. Please refer to GenerationMode in order to change this field. /// public bool CreateProperties { get { if (GenerationMode == GenerationMode.PrivateVariablesWithProperties) return true; return false; } } public ClassGenerator () { } public void ParseString(string source) { StringReader lines = new StringReader(source); string nextLine = string.Empty; do { nextLine = lines.ReadLine(); if(nextLine == null) break; if(nextLine.Length == 0) continue; nextLine = nextLine.Trim(); // It's a using statement if(nextLine.StartsWith("- ")) { string[] parts = Regex.Split(nextLine, @"\s+"); UsingStatements.Add(parts[1]); } else if(nextLine.StartsWith("#")) { // It's the class name ClassName = UppercaseFirstLetter(nextLine.TrimStart(new char[] { '#' })).Trim(); } else { Signatures.Add(nextLine.Trim()); } } while(nextLine != null); } public override string ToString() { StringBuilder result = new StringBuilder(); // Using statements foreach(string usingStatement in UsingStatements) result.AppendLine(string.Format("using {0};", expandUsingShortcut(usingStatement))); result.AppendLine(); // Class name result.AppendLine(string.Format("class {0} ", ClassName)); result.AppendLine("{"); // Class body parts declaration StringBuilder properties = new StringBuilder(); StringBuilder constructorSignature = new StringBuilder(string.Format("\tpublic {0}(", ClassName)); StringBuilder constructorBody = new StringBuilder(); // Data member signature handling foreach (string signature in Signatures) { string[] signatureParts = Regex.Split(signature, @"\s+"); string datatypeName = signatureParts[0]; string privateDataMemberName = LowercaseFirstLetter(signatureParts[1]); string publicDataMemberName = UppercaseFirstLetter(signatureParts[1]); constructorSignature.AppendFormat("{0} in{1}, ", datatypeName, publicDataMemberName); if (CreateProperties) { // Private data member result.AppendLine(string.Format("\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}}")); // Constructor body constructorBody.AppendLine(string.Format("\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)); } } // Add the properties to the output result.AppendLine(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}"); // Close the class off and end the file result.AppendLine("}"); return result.ToString(); } protected string expandUsingShortcut(string shortcut) { if (UsingShortcuts.ContainsKey(shortcut)) return UsingShortcuts[shortcut]; else return shortcut; } private string UppercaseFirstLetter(string str) { if (str == null) return null; if (str.Length > 1) return char.ToUpper(str[0]) + str.Substring(1); return str.ToUpper(); } private string LowercaseFirstLetter(string str) { if (str == null) return null; if (str.Length > 1) return char.ToLower(str[0]) + str.Substring(1); return str.ToLower(); } } }