cscz/cscz/ClassGenerator.cs

192 lines
5.4 KiB
C#

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
{
/// <summary>
/// A mapping of namespaces to using shortcuts.
/// </summary>
public Dictionary<string, string> UsingShortcuts = new Dictionary<string, string>()
{
{ "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" },
};
/// <summary>
/// The using statements to add to the generated class.
/// </summary>
public List<string> UsingStatements = new List<string>()
{
"System"
};
public List<string> Signatures = new List<string>();
public string ClassName = "Carrot";
public GenerationMode GenerationMode = GenerationMode.PublicVariables;
/// <summary>
/// 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.
/// </summary>
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();
}
}
}