using System;
using System.IO;
using System.Text;
using System.Diagnostics;
using System.CodeDom.Compiler;
using AnticipatingMinds.Genesis.CodeDOM;
namespace AnticipatingMinds.Genesis.Effectors{
/// <summary>
/// Summary description for CSharpCodeGenerator.
/// </summary>
[System.Security.Permissions.StrongNameIdentityPermissionAttribute(System.Security.Permissions.SecurityAction.LinkDemand,
PublicKey=
"00240000048000009400000006020000002400005253413100040000010001009D309779C258129573FC313836474C75C4CE9F4" +
"107524FA0B9A6DB2E52754459C5A8946E4CBD5B98ACDB2413C5AFD38C1DF00C9A946713E867237B47F9D9CC473D4A853EACBEAB" +
"799EC0A271B468D4B6D52301A414A7772F05FEBD2BA7D0A2835F0D45E401C3C37F9E7B991D29F07DA88E20BB3839A34A2739AB6" +
"56B5204C8BC")]
public sealed class CSharpCodeGenerator
{
#region C# Code generation Methods
static private void GenerateAttributeCode(CodeAttribute attribute,IndentedTextWriter textWriter)
{
textWriter.Write("[");
textWriter.Write(attribute.AttributeType.TypeName);
textWriter.Write("(");
bool firstArgument = true;
foreach(CodeElement argument in attribute.Arguments)
{
if(!firstArgument)
textWriter.Write(", ");
else
firstArgument = false;
GenerateCode(argument,textWriter);
}
textWriter.WriteLine(")]");
}
static private void GenerateArgumentCode(CodeArgument argument,IndentedTextWriter textWriter)
{
if(argument.Modifier == CodeArgument.CodeArgumentModifier.Out)
textWriter.Write("out ");
if(argument.Modifier == CodeArgument.CodeArgumentModifier.Ref)
textWriter.Write("ref ");
GenerateCode(argument.Value,textWriter);
}
static private void GenerateTypeMethodDeclaration(CodeTypeMethodDeclaration methodDeclaration,IndentedTextWriter textWriter)
{
foreach(CodeAttribute attrbute in methodDeclaration.Attributes)
{
GenerateCode(attrbute,textWriter);
textWriter.WriteLine();
}
GenerateTypeMemberDeclarationModifiers(methodDeclaration.Modifiers,textWriter);
if(methodDeclaration is CodeTypeDestructorDeclaration)
textWriter.Write("~");
if(methodDeclaration.ReturnType != null)
{
GenerateCode(methodDeclaration.ReturnType,textWriter);
textWriter.Write(" ");
}
if((methodDeclaration is CodeTypeConstructorDeclaration) || (methodDeclaration is CodeTypeDestructorDeclaration))
textWriter.Write(methodDeclaration.DeclaringType.Name + "(");
else
textWriter.Write(methodDeclaration.Name + "(");
bool firstParameter = true;
foreach(CodeElement parameter in methodDeclaration.Parameters)
{
if(!firstParameter)
textWriter.Write(", ");
else
firstParameter = false;
GenerateCode(parameter,textWriter);
}
textWriter.Write(")");
if((methodDeclaration is CodeTypeConstructorDeclaration) && (methodDeclaration as CodeTypeConstructorDeclaration).InitializerType != CodeTypeConstructorDeclaration.ConstructorInitializerType.None)
{
CodeTypeConstructorDeclaration constructorDeclaration = methodDeclaration as CodeTypeConstructorDeclaration;
if(constructorDeclaration.InitializerType == CodeTypeConstructorDeclaration.ConstructorInitializerType.Base)
textWriter.Write(" : base(");
else
textWriter.Write(" : this(");
bool bFirstParameter = true;
foreach(CodeArgument arg in constructorDeclaration.InitializerArguments)
{
if(bFirstParameter)
bFirstParameter = false;
else
textWriter.Write(", ");
GenerateCode(arg,textWriter);
}
textWriter.Write(")");
}
if(methodDeclaration.Statements == null)
{
textWriter.WriteLine(";");
return;
}
textWriter.WriteLine("");
textWriter.WriteLine("{");
textWriter.Indent+=4;
foreach(CodeElement statement in methodDeclaration.Statements.Statements)
{
GenerateCode(statement,textWriter);
}
textWriter.Indent-=4;
textWriter.WriteLine("}");
}
static private void GenerateTypePropertyDeclaration(CodeTypePropertyDeclaration propertyDeclaration,IndentedTextWriter textWriter)
{
textWriter.WriteLine();
foreach(CodeAttribute attrbute in propertyDeclaration.Attributes)
{
GenerateCode(attrbute,textWriter);
textWriter.WriteLine();
}
GenerateTypeMemberDeclarationModifiers(propertyDeclaration.Modifiers,textWriter);
GenerateCode(propertyDeclaration.ReturnType,textWriter);
textWriter.Write(" ");
textWriter.WriteLine(propertyDeclaration.Name);
bool isAbstract = (propertyDeclaration.Modifiers & CodeTypeMemberDeclaration.MemberDeclarationModifiers.Abstract) != 0;
textWriter.WriteLine("{");
textWriter.Indent+=4;
if(propertyDeclaration.GetAccessorStatements != null)
{
foreach(CodeAttribute attrbute in propertyDeclaration.GetAccessorAttributes)
{
GenerateCode(attrbute,textWriter);
textWriter.WriteLine();
}
textWriter.Write("get");
if(isAbstract && propertyDeclaration.GetAccessorStatements.Statements.Count == 0)
{
textWriter.WriteLine(";");
}
else
{
textWriter.WriteLine();
textWriter.WriteLine("{");
textWriter.Indent+=4;
foreach(CodeElement statement in propertyDeclaration.GetAccessorStatements.Statements)
{
GenerateCode(statement,textWriter);
}
//get close
textWriter.Indent-=4;
textWriter.WriteLine("}");
}
}
if(propertyDeclaration.SetAccessorStatements != null)
{
foreach(CodeAttribute attrbute in propertyDeclaration.SetAccessorAttributes)
{
GenerateCode(attrbute,textWriter);
textWriter.WriteLine();
}
textWriter.Write("set");
if(isAbstract && propertyDeclaration.SetAccessorStatements.Statements.Count == 0)
{
textWriter.WriteLine(";");
}
else
{
textWriter.WriteLine();
textWriter.WriteLine("{");
textWriter.Indent+=4;
foreach(CodeElement statement in propertyDeclaration.SetAccessorStatements.Statements)
{
GenerateCode(statement,textWriter);
textWriter.WriteLine("");
}
//Set close
textWriter.Indent-=4;
textWriter.WriteLine("}");
}
}
//Property close
textWriter.Indent-=4;
textWriter.WriteLine("}");
}
static private void GenerateTypeDelegateDeclaration(CodeTypeDelegateDeclaration delegateDeclaration,IndentedTextWriter textWriter)
{
foreach(CodeAttribute attrbute in delegateDeclaration.Attributes)
{
GenerateCode(attrbute,textWriter);
textWriter.WriteLine();
}
GenerateTypeDeclarationModifiers(delegateDeclaration.Modifiers,textWriter);
textWriter.Write("delegate ");
GenerateCode(delegateDeclaration.ReturnType,textWriter);
textWriter.Write(" ");
textWriter.Write(delegateDeclaration.Name);
textWriter.Write("(");
bool firstParameter = true;
foreach(CodeElement parameter in delegateDeclaration.Parameters)
{
if(!firstParameter)
textWriter.Write(", ");
else
firstParameter = false;
GenerateCode(parameter,textWriter);
}
textWriter.WriteLine(");");
}
static private void GenerateBinaryOperatorCode(CodeBinaryOperatorType binaryOperator,IndentedTextWriter textWriter)
{
switch(binaryOperator)
{
case CodeBinaryOperatorType.Addition:
{
textWriter.Write("+");
break;
}
case CodeBinaryOperatorType.AdditionAssignment:
{
textWriter.Write("+=");
break;
}
case CodeBinaryOperatorType.As:
{
textWriter.Write("as");
break;
}
case CodeBinaryOperatorType.Assign:
{
textWriter.Write("=");
break;
}
case CodeBinaryOperatorType.BitwiseAnd:
{
textWriter.Write("&");
break;
}
case CodeBinaryOperatorType.BitwiseAndAssignment:
{
textWriter.Write("&=");
break;
}
case CodeBinaryOperatorType.BitwiseOr:
{
textWriter.Write("|");
break;
}
case CodeBinaryOperatorType.BitwiseOrAssignment:
{
textWriter.Write("|=");
break;
}
case CodeBinaryOperatorType.Division:
{
textWriter.Write("/");
break;
}
case CodeBinaryOperatorType.DivisionAssignment:
{
textWriter.Write("/=");
break;
}
case CodeBinaryOperatorType.Equality:
{
textWriter.Write("==");
break;
}
case CodeBinaryOperatorType.ExclusiveOr:
{
textWriter.Write("^");
break;
}
case CodeBinaryOperatorType.ExclusiveOrAssignment:
{
textWriter.Write("^=");
break;
}
case CodeBinaryOperatorType.GreaterThan:
{
textWriter.Write(">");
break;
}
case CodeBinaryOperatorType.GreaterThanOrEqual:
{
textWriter.Write(">=");
break;
}
case CodeBinaryOperatorType.Inequality:
{
textWriter.Write("!=");
break;
}
case CodeBinaryOperatorType.Is:
{
textWriter.Write("is");
break;
}
case CodeBinaryOperatorType.LeftShift:
{
textWriter.Write("<<");
break;
}
case CodeBinaryOperatorType.LeftShiftAssignment:
{
textWriter.Write("<<=");
break;
}
case CodeBinaryOperatorType.LessThan:
{
textWriter.Write("<");
break;
}
case CodeBinaryOperatorType.LessThanOrEqual:
{
textWriter.Write("<=");
break;
}
case CodeBinaryOperatorType.LogicalAnd:
{
textWriter.Write("&&");
break;
}
case CodeBinaryOperatorType.LogicalOr:
{
textWriter.Write("||");
break;
}
case CodeBinaryOperatorType.MemberSelection:
{
Debug.Assert(false,"Just curiouse where is it used?");
textWriter.Write(".");
break;
}
case CodeBinaryOperatorType.Modulus:
{
textWriter.Write("%");
break;
}
case CodeBinaryOperatorType.ModulusAssignment:
{
textWriter.Write("%=");
break;
}
case CodeBinaryOperatorType.MultiplicationAssignment:
{
textWriter.Write("*=");
break;
}
case CodeBinaryOperatorType.Multiply:
{
textWriter.Write("*");
break;
}
case CodeBinaryOperatorType.None:
{
textWriter.Write("");
break;
}
case CodeBinaryOperatorType.Question:
{
textWriter.Write("?");
break;
}
case CodeBinaryOperatorType.RightShift:
{
textWriter.Write(">>");
break;
}
case CodeBinaryOperatorType.RightShiftAssignment:
{
textWriter.Write(">>=");
break;
}
case CodeBinaryOperatorType.Subtraction:
{
textWriter.Write("-");
break;
}
case CodeBinaryOperatorType.SubtractionAssignment:
{
textWriter.Write("-=");
break;
}
}
}
static private void GenerateUnaryOperatorCode(CodeUnaryOperatorType unaryOperator,IndentedTextWriter textWriter)
{
switch(unaryOperator)
{
case CodeUnaryOperatorType.AddressOf:
{
textWriter.Write("&");
break;
}
case CodeUnaryOperatorType.Checked:
{
textWriter.Write("checked");
break;
}
case CodeUnaryOperatorType.False:
{
textWriter.Write("false");
break;
}
case CodeUnaryOperatorType.LogicalNot:
{
textWriter.Write("!");
break;
}
case CodeUnaryOperatorType.None:
{
textWriter.Write("");
break;
}
case CodeUnaryOperatorType.OnesComplement:
{
textWriter.Write("~");
break;
}
case CodeUnaryOperatorType.PointerDereference:
{
textWriter.Write("*");
break;
}
case CodeUnaryOperatorType.PostfixDecrement:
{
textWriter.Write("--");
break;
}
case CodeUnaryOperatorType.PostfixIncrement:
{
textWriter.Write("++");
break;
}
case CodeUnaryOperatorType.PrefixDecrement:
{
textWriter.Write("--");
break;
}
case CodeUnaryOperatorType.PrefixIncrement:
{
textWriter.Write("++");
break;
}
case CodeUnaryOperatorType.SizeOf:
{
textWriter.Write("sizeof");
break;
}
case CodeUnaryOperatorType.True:
{
textWriter.Write("true");
break;
}
case CodeUnaryOperatorType.TypeOf:
{
textWriter.Write("typeof");
break;
}
case CodeUnaryOperatorType.UnaryNegation:
{
textWriter.Write("-");
break;
}
case CodeUnaryOperatorType.UnaryPlus:
{
textWriter.Write("");
break;
}
case CodeUnaryOperatorType.Unchecked:
{
textWriter.Write("unchecked");
break;
}
}
}
static private void GenerateExpressionCode(CodeExpression codeElement,IndentedTextWriter textWriter)
{
#region CodePrimitiveExpression
if(codeElement is CodePrimitiveExpression)
{
CodePrimitiveExpression primitive = codeElement as CodePrimitiveExpression;
if(primitive.Value == null)
{
textWriter.Write("null");
return;
}
if(primitive.Value is System.Boolean)
{
if((bool) primitive.Value)
textWriter.Write("true");
else
textWriter.Write("false");
return;
}
if(primitive.Value is System.String)
{
if(primitive.Format == CodePrimitiveExpressionFormat.VerbatimString)
textWriter.Write(String.Format("@\"{0}\"",primitive.Value as string));
else
textWriter.Write(String.Format("\"{0}\"",primitive.Value as string));
return;
}
if(primitive.Value is System.Char)
{
if(primitive.Format == CodePrimitiveExpressionFormat.HexidecimalEscapeSequence)
{
textWriter.Write(String.Format(@"'\x{0:X}'",(int)(char)primitive.Value));
}
else
if(primitive.Format == CodePrimitiveExpressionFormat.UnicodeEscapeSequence)
{
textWriter.Write(String.Format(@"'\u{0:X}'",(int)(char)primitive.Value));
}
else
{
switch((char)primitive.Value)
{
case '\'':
{
textWriter.Write(@"'\''");
break;
}
case '\"':
{
textWriter.Write(@"'\""'");
break;
}
case '\\':
{
textWriter.Write(@"'\\'");
break;
}
case '\0':
{
textWriter.Write(@"'\0'");
break;
}
case '\a':
{
textWriter.Write(@"'\a'");
break;
}
case '\b':
{
textWriter.Write(@"'\b'");
break;
}
case '\f':
{
textWriter.Write(@"'\f'");
break;
}
case '\n':
{
textWriter.Write(@"'\n'");
break;
}
case '\r':
{
textWriter.Write(@"'\r'");
break;
}
case '\t':
{
textWriter.Write(@"'\t'");
break;
}
case '\v':
{
textWriter.Write(@"'\v'");
break;
}
default:
{
textWriter.Write(String.Format("'{0}'",Char.ToString((char)primitive.Value)));
break;
}
}
}
return;
}
if(primitive.Value is System.Int32 ||
primitive.Value is System.Int64 ||
primitive.Value is System.UInt32 ||
primitive.Value is System.UInt64 ||
primitive.Value is System.Single ||
primitive.Value is System.Double ||
primitive.Value is System.Decimal)
{
string numberString;
if(primitive.Format == CodePrimitiveExpressionFormat.HexidecimalNumber)
{
//well, this moronic formatting does not do negative hex numbers....
bool isNegative = false;
if((primitive.Value is System.Int64))
{
long number = (long)primitive.Value;
if(number < 0)
{
isNegative = true;
number = -1*number;
}
numberString = String.Format("{0:X}",number);
}
else if((primitive.Value is System.Int32))
{
int number = (int)primitive.Value;
if(number < 0)
{
isNegative = true;
number = -1*number;
}
numberString = String.Format("{0:X}",number);
}
else
{
numberString = String.Format("{0:X}",primitive.Value);
}
numberString = numberString.Insert(0,"0x");
if(isNegative)
numberString = numberString.Insert(0,"-");
}
else
{
numberString = String.Format("{0:G}",primitive.Value);
}
textWriter.Write(numberString);
if(primitive.Value is System.UInt32 || primitive.Value is System.UInt64)
textWriter.Write("U");
if(primitive.Value is System.UInt64 || primitive.Value is System.Int64)
textWriter.Write("L");
if(primitive.Value is System.Single && numberString.IndexOf(".") == -1)
textWriter.Write("F");
if(primitive.Value is System.Double)
textWriter.Write("D");
if(primitive.Value is System.Decimal)
textWriter.Write("M");
return;
}
textWriter.Write(primitive.Value.ToString());
return;
}
#endregion
#region CodeBinaryExpression
if(codeElement is CodeBinaryExpression)
{
CodeBinaryExpression binaryExpression = codeElement as CodeBinaryExpression;
GenerateCode(binaryExpression.LeftOperand,textWriter);
textWriter.Write(" ");
GenerateBinaryOperatorCode(binaryExpression.Operator,textWriter);
textWriter.Write(" ");
GenerateCode(binaryExpression.RightOperand,textWriter);
return;
}
#endregion
#region CodeVariableReferenceExpression
if(codeElement is CodeVariableReferenceExpression)
{
CodeVariableReferenceExpression varReference = codeElement as CodeVariableReferenceExpression;
textWriter.Write(varReference.VariableName);
return;
}
#endregion
#region CodeExpressionStatement
#endregion
#region CodeUnaryExpression
if(codeElement is CodeUnaryExpression)
{
CodeUnaryExpression unaryExpression = codeElement as CodeUnaryExpression;
if(unaryExpression.Operator == CodeUnaryOperatorType.SizeOf ||
unaryExpression.Operator == CodeUnaryOperatorType.TypeOf ||
unaryExpression.Operator == CodeUnaryOperatorType.Checked ||
unaryExpression.Operator == CodeUnaryOperatorType.Unchecked)
{
GenerateUnaryOperatorCode(unaryExpression.Operator,textWriter);
textWriter.Write("(");
GenerateCode(unaryExpression.Operand,textWriter);
textWriter.Write(")");
return;
}
if(unaryExpression.Operator == CodeUnaryOperatorType.PostfixIncrement ||
unaryExpression.Operator == CodeUnaryOperatorType.PostfixDecrement)
{
GenerateCode(unaryExpression.Operand,textWriter);
GenerateUnaryOperatorCode(unaryExpression.Operator,textWriter);
return;
}
GenerateUnaryOperatorCode(unaryExpression.Operator,textWriter);
if(unaryExpression.Operand != null)
GenerateCode(unaryExpression.Operand,textWriter);
return;
}
#endregion
#region CodeTypeReferenceExpression
if(codeElement is CodeTypeReferenceExpression)
{
CodeTypeReferenceExpression typeReference = codeElement as CodeTypeReferenceExpression;
GenerateCode(typeReference.ReferencedType,textWriter);
return;
}
#endregion
#region CodeIndexerExpression
if(codeElement is CodeIndexerInvokeExpression)
{
CodeIndexerInvokeExpression expression = codeElement as CodeIndexerInvokeExpression;
if(expression.IndexerReferenceExpression != null)
GenerateCode(expression.IndexerReferenceExpression,textWriter);
textWriter.Write("[");
bool firstArgument = true;
foreach(CodeArgument argument in expression.Arguments)
{
if(firstArgument)
firstArgument= false;
else
textWriter.Write(", ");
GenerateCode(argument,textWriter);
}
textWriter.Write("]");
return;
}
#endregion
#region CodePropertyReferenceExpression
if(codeElement is CodeNamedReferenceExpression)
{
CodeNamedReferenceExpression reference = codeElement as CodeNamedReferenceExpression;
if(reference.TargetObject != null)
{
GenerateCode(reference.TargetObject,textWriter);
textWriter.Write(".");
}
textWriter.Write(reference.Name);
return;
}
#endregion
#region CodeMethodInvokeExpression
if(codeElement is CodeMethodInvokeExpression)
{
CodeMethodInvokeExpression invokeMethod = codeElement as CodeMethodInvokeExpression;
if(invokeMethod.MethodReferenceExpression != null)
GenerateCode(invokeMethod.MethodReferenceExpression,textWriter);
textWriter.Write("(");
bool bFirstParameter = true;
foreach(CodeArgument arg in invokeMethod.Arguments)
{
if(bFirstParameter)
bFirstParameter = false;
else
textWriter.Write(", ");
GenerateCode(arg,textWriter);
}
textWriter.Write(")");
return;
}
#endregion
#region CodeParenthesizedExpression
if(codeElement is CodeParenthesizedExpression)
{
CodeParenthesizedExpression parenthesizedExpression = codeElement as CodeParenthesizedExpression;
textWriter.Write("(");
GenerateCode(parenthesizedExpression.Expression,textWriter);
textWriter.Write(")");
return;
}
#endregion
#region CodeThisReferenceExpression
if(codeElement is CodeThisReferenceExpression)
{
textWriter.Write("this");
return;
}
#endregion
#region CodeBaseReferenceExpression
if(codeElement is CodeBaseReferenceExpression)
{
textWriter.Write("base");
return;
}
#endregion
#region CodeNullReferenceExpression
if(codeElement is CodeNullReferenceExpression)
{
textWriter.Write("null");
return;
}
#endregion
#region CodeTypeCastExpression
if(codeElement is CodeTypeCastExpression)
{
CodeTypeCastExpression expression = codeElement as CodeTypeCastExpression;
textWriter.Write("(");
GenerateCode(expression.TargetType,textWriter);
textWriter.Write(") ");
GenerateCode(expression.Expression,textWriter);
return;
}
#endregion
#region CodeExpressionSnippet
if(codeElement is CodeExpressionSnippet)
{
textWriter.Write((codeElement as CodeExpressionSnippet).Text);
return;
}
#endregion
#region CodeMethodParameterReferenceExpression
if(codeElement is CodeMethodParameterReferenceExpression)
{
CodeMethodParameterReferenceExpression reference = codeElement as CodeMethodParameterReferenceExpression;
textWriter.Write(reference.ParameterName);
return;
}
#endregion
#region CodeArrayCreateExpression
if(codeElement is CodeArrayCreateExpression)
{
CodeArrayCreateExpression expression = codeElement as CodeArrayCreateExpression;
textWriter.Write("new ");
GenerateCode(expression.CreateType.ArrayElementType,textWriter);
textWriter.Write("[");
for(int sizeInitializerIndex = 0; sizeInitializerIndex < expression.Size;sizeInitializerIndex++)
{
if(sizeInitializerIndex != 0)
textWriter.Write(",");
//Sometimes number of explicit size initilizer expressiosn less
//than number of dimensions
//consider: new string[] {""}
//here dimention is one, but there are no initializers
if(sizeInitializerIndex < expression.SizeInitializers.Count)
GenerateCode(expression.SizeInitializers[sizeInitializerIndex],textWriter);
}
textWriter.Write("]");
if(expression.Initializer != null)
{
GenerateCode(expression.Initializer,textWriter);
}
return;
}
#endregion
#region CodeArrayInitializerExpression
if(codeElement is CodeArrayInitializerExpression)
{
CodeArrayInitializerExpression expression = codeElement as CodeArrayInitializerExpression;
textWriter.Write(" { ");
bool firstInitializer = true;
foreach(CodeExpression init in expression.Initializers)
{
if(firstInitializer)
firstInitializer= false;
else
textWriter.Write(", ");
GenerateCode(init,textWriter);
}
textWriter.Write(" }");
return;
}
#endregion
#region CodeObjectCreateExpression
if(codeElement is CodeObjectCreateExpression)
{
CodeObjectCreateExpression expression = codeElement as CodeObjectCreateExpression;
textWriter.Write("new ");
GenerateCode(expression.CreateType,textWriter);
textWriter.Write("(");
bool bFirstParameter = true;
foreach(CodeArgument arg in expression.Arguments)
{
if(bFirstParameter)
bFirstParameter = false;
else
textWriter.Write(", ");
GenerateCode(arg,textWriter);
}
textWriter.Write(")");
return;
}
#endregion
#region CodeConditionalExpression
if(codeElement is CodeConditionalExpression)
{
CodeConditionalExpression conditionalExpression = codeElement as CodeConditionalExpression;
GenerateCode(conditionalExpression.Condition,textWriter);
textWriter.Write(" ? ");
GenerateCode(conditionalExpression.TrueExpression,textWriter);
textWriter.Write(" : ");
GenerateCode(conditionalExpression.FalseExpression,textWriter);
return;
}
#endregion
Debug.Assert(false,"Add new code generator for specified type");
}
static private void GenerateStatementCode(CodeStatement codeElement,IndentedTextWriter textWriter)
{
GenerateStatementCode(codeElement,textWriter,true);
}
static private void GenerateStatementCode(CodeStatement codeElement,IndentedTextWriter textWriter,bool finishWithSemicolon)
{
#region CodeExpressionStatement
if(codeElement is CodeExpressionStatement)
{
CodeExpressionStatement expressionStatement = codeElement as CodeExpressionStatement;
GenerateCode(expressionStatement.Expression,textWriter);
if(finishWithSemicolon)
textWriter.WriteLine(";");
return;
}
#endregion
#region CodeVariableDeclarationStatement
if(codeElement is CodeVariableDeclarationStatement)
{
CodeVariableDeclarationStatement variableDeclaration = codeElement as CodeVariableDeclarationStatement;
GenerateCode(variableDeclaration.DeclarationType,textWriter);
textWriter.Write(" ");
bool firstDeclaration = true;
foreach(CodeVariableDeclarationMember decmember in variableDeclaration.DeclaredVariables)
{
if(firstDeclaration)
{
firstDeclaration = false;
}
else
{
textWriter.Write(", ");
}
GenerateCode(decmember,textWriter);
}
if(finishWithSemicolon)
textWriter.WriteLine(";");
return;
}
#endregion
#region CodeReturnStatement
if(codeElement is CodeReturnStatement)
{
CodeReturnStatement statement = codeElement as CodeReturnStatement;
textWriter.Write("return ");
if(statement.Expression != null)
GenerateCode(statement.Expression,textWriter);
if(finishWithSemicolon)
textWriter.WriteLine(";");
return;
}
#endregion
#region CodeIfSatement
if(codeElement is CodeIfStatement)
{
CodeIfStatement statement = codeElement as CodeIfStatement;
textWriter.Write("if (");
GenerateCode(statement.Condition,textWriter);
textWriter.Write(")");
textWriter.WriteLine("");
if(statement.TrueStatement is CodeStatementBlock)
{
GenerateCode(statement.TrueStatement,textWriter);
}
else
{
textWriter.Indent+=4;
GenerateCode(statement.TrueStatement,textWriter);
textWriter.Indent-=4;
}
if(statement.FalseStatement != null)
{
textWriter.WriteLine("else");
if(statement.FalseStatement is CodeStatementBlock)
{
GenerateCode(statement.FalseStatement ,textWriter);
}
else
{
textWriter.Indent+=4;
GenerateCode(statement.FalseStatement ,textWriter);
textWriter.Indent-=4;
}
}
return;
}
#endregion
#region CodeBreakStatement
if(codeElement is CodeBreakStatement)
{
textWriter.WriteLine("break;");
return;
}
#endregion
#region CodeSwitchStatement
if(codeElement is CodeSwitchStatement)
{
CodeSwitchStatement statement = codeElement as CodeSwitchStatement;
textWriter.Write("switch (");
GenerateCode(statement.SwitchExpression,textWriter);
textWriter.WriteLine(")");
textWriter.WriteLine("{");
textWriter.Indent+=4;
foreach(CodeElement element in statement.Cases)
GenerateCode(element,textWriter);
if(statement.DefaultCaseStatements != null)
{
textWriter.WriteLine("default :");
textWriter.Indent+=4;
foreach(CodeElement element in statement.DefaultCaseStatements)
GenerateCode(element,textWriter);
textWriter.Indent-=4;
}
textWriter.Indent-=4;
textWriter.WriteLine("}");
return;
}
#endregion
#region CodeContinueStatement
if(codeElement is CodeContinueStatement)
{
textWriter.WriteLine("continue;");
return;
}
#endregion textWriter.WriteLine(codeElement.ToString());
#region CodeTryStatement
if(codeElement is CodeTryStatement)
{
CodeTryStatement statement = codeElement as CodeTryStatement;
textWriter.WriteLine("try");
GenerateCode(statement.Statements,textWriter);
foreach(CodeElement element in statement.CatchClauses)
GenerateCode(element,textWriter);
if(statement.FinallyClause != null)
{
textWriter.WriteLine("finally");
GenerateCode(statement.FinallyClause.Statements,textWriter);
}
return;
}
#endregion
#region CodeThrowStatement
if(codeElement is CodeThrowStatement)
{
CodeThrowStatement statement = codeElement as CodeThrowStatement;
textWriter.Write("throw ");
if(statement.ToThrow != null)
GenerateCode(statement.ToThrow,textWriter);
if(finishWithSemicolon)
textWriter.WriteLine(";");
return;
}
#endregion
#region CodeForStatement
if(codeElement is CodeForStatement)
{
CodeForStatement statement = codeElement as CodeForStatement;
textWriter.Write("for(");
bool firstInitializer = true;
foreach(CodeElement initializer in statement.Initializers)
{
if(!firstInitializer)
textWriter.Write(", ");
else
firstInitializer = false;
if(initializer is CodeVariableDeclarationStatement)
{
CodeVariableDeclarationStatement variableDeclaration = initializer as CodeVariableDeclarationStatement;
GenerateCode(variableDeclaration.DeclarationType,textWriter);
textWriter.Write(" ");
bool firstDeclaration = true;
foreach(CodeVariableDeclarationMember decmember in variableDeclaration.DeclaredVariables)
{
if(firstDeclaration)
{
firstDeclaration = false;
}
else
{
textWriter.Write(", ");
}
GenerateCode(decmember,textWriter);
}
continue;
}
if(initializer is CodeExpressionStatement)
{
GenerateCode((initializer as CodeExpressionStatement).Expression,textWriter);
continue;
}
Debug.Assert(false,"Only var declarations & expressions are allowed in 'for' initializers section");
}
textWriter.Write("; ");
if(statement.Condition != null)
GenerateCode(statement.Condition,textWriter);
textWriter.Write("; ");
bool firstIterator = true;
foreach(CodeElement iterator in statement.Iterators)
{
if(!firstIterator)
textWriter.Write(", ");
else
firstIterator = false;
if(iterator is CodeExpressionStatement)
{
GenerateCode((iterator as CodeExpressionStatement).Expression,textWriter);
continue;
}
Debug.Assert(false,"Only expressions are allowed in 'for' initializers section");
}
textWriter.WriteLine(")");
if(statement.Statement is CodeStatementBlock)
{
GenerateCode(statement.Statement,textWriter);
}
else
{
textWriter.Indent+=4;
GenerateCode(statement.Statement,textWriter);
textWriter.Indent-=4;
}
return;
}
#endregion
#region CodeForEachStatement
if(codeElement is CodeForEachStatement)
{
CodeForEachStatement statement = codeElement as CodeForEachStatement;
textWriter.Write("foreach(");
GenerateCode(statement.Type,textWriter);
textWriter.Write(" ");
textWriter.Write(statement.IteratorName);
textWriter.Write(" in ");
GenerateCode(statement.IteratedCollection,textWriter);
textWriter.WriteLine(")");
if(statement.Statement is CodeStatementBlock)
{
GenerateCode(statement.Statement,textWriter);
}
else
{
textWriter.Indent+=4;
GenerateCode(statement.Statement,textWriter);
textWriter.Indent-=4;
}
return;
}
#endregion
#region CodeWhileStatement
if(codeElement is CodeWhileStatement)
{
CodeWhileStatement statement = codeElement as CodeWhileStatement;
textWriter.Write("while (");
GenerateCode(statement.Condition,textWriter);
textWriter.WriteLine(" )");
GenerateCode(statement.Statement,textWriter);
return;
}
#endregion
#region CodeDoStatement
if(codeElement is CodeDoStatement)
{
CodeDoStatement statement = codeElement as CodeDoStatement;
textWriter.WriteLine("do {");
textWriter.Indent+=4;
GenerateCode(statement.Statement,textWriter);
textWriter.Indent-=4;
textWriter.Write("} while ( ");
GenerateCode(statement.Condition,textWriter);
textWriter.WriteLine(" );");
return;
}
#endregion
#region CodeLockSatement
if(codeElement is CodeLockStatement)
{
CodeLockStatement statement = codeElement as CodeLockStatement;
textWriter.Write("lock(");
GenerateCode(statement.Expression,textWriter);
textWriter.WriteLine(")");
if(statement.Statement is CodeStatementBlock)
{
GenerateCode(statement.Statement,textWriter);
}
else
{
textWriter.Indent+=4;
GenerateCode(statement.Statement,textWriter);
textWriter.Indent-=4;
}
return;
}
#endregion
#region CodeEmptyStatement
if(codeElement is CodeEmptyStatement)
{
textWriter.WriteLine(";");
return;
}
#endregion
#region CodeGotoStatement
if(codeElement is CodeGotoStatement)
{
CodeGotoStatement gotoStatement = codeElement as CodeGotoStatement;
textWriter.Write("goto ");
textWriter.Write(gotoStatement.TargetLabel);
if(finishWithSemicolon)
textWriter.WriteLine(";");
return;
}
#endregion
#region CodeLabelStatement
if(codeElement is CodeLabelStatement)
{
CodeLabelStatement labelStatement = codeElement as CodeLabelStatement;
textWriter.Write(labelStatement.Label);
textWriter.WriteLine(":");
return;
}
#endregion
#region CodeStatementBlock
if(codeElement is CodeStatementBlock)
{
CodeStatementBlock block = codeElement as CodeStatementBlock;
textWriter.WriteLine("{");
textWriter.Indent+=4;
foreach(CodeStatement statement in block.Statements)
GenerateCode(statement,textWriter);
textWriter.Indent-=4;
textWriter.WriteLine("}");
return;
}
#endregion
#region CodeUsingStatement
if(codeElement is CodeUsingStatement)
{
CodeUsingStatement codeUsingStatement = codeElement as CodeUsingStatement;
textWriter.Write("using(");
GenerateStatementCode(codeUsingStatement.ResourceAquisition,textWriter,false);
textWriter.WriteLine(")");
if(codeUsingStatement.Statement is CodeStatementBlock)
{
GenerateCode(codeUsingStatement.Statement,textWriter);
}
else
{
textWriter.Indent+=4;
GenerateCode(codeUsingStatement.Statement,textWriter);
textWriter.Indent-=4;
}
return;
}
#endregion
#region CodeStatementSnippet
if(codeElement is CodeStatementSnippet)
{
CodeStatementSnippet snippet = codeElement as CodeStatementSnippet;
textWriter.Write(snippet.Text);
return;
}
#endregion
Debug.Assert(false,"What statement did I miss?");
}
static private void GenerateTypeDeclarationModifiers(CodeTypeDeclaration.TypeDeclarationModifiers modifiers,IndentedTextWriter textWriter)
{
if((modifiers & CodeTypeDeclaration.TypeDeclarationModifiers.Public) != 0)
textWriter.Write("public ");
if((modifiers & CodeTypeDeclaration.TypeDeclarationModifiers.Family) != 0)
textWriter.Write("protected ");
if((modifiers & CodeTypeDeclaration.TypeDeclarationModifiers.Private) != 0)
textWriter.Write("private ");
if((modifiers & CodeTypeDeclaration.TypeDeclarationModifiers.Assembly) != 0)
textWriter.Write("internal ");
if((modifiers & CodeTypeDeclaration.TypeDeclarationModifiers.New) != 0)
textWriter.Write("new ");
if((modifiers & CodeTypeDeclaration.TypeDeclarationModifiers.FamilyAndAssembly) != 0)
textWriter.Write("protected internal ");
if((modifiers & CodeTypeDeclaration.TypeDeclarationModifiers.Abstract) != 0)
textWriter.Write("abstract ");
if((modifiers & CodeTypeDeclaration.TypeDeclarationModifiers.Sealed) != 0)
textWriter.Write("sealed ");
if((modifiers & CodeTypeDeclaration.TypeDeclarationModifiers.Unsafe) != 0)
textWriter.Write("unsafe ");
}
static private void GenerateTypeMemberDeclarationModifiers(CodeTypeMemberDeclaration.MemberDeclarationModifiers modifiers,IndentedTextWriter textWriter)
{
CodeTypeMemberDeclaration.MemberDeclarationModifiers currentModifiers = modifiers;
while(true)
{
if((currentModifiers & CodeTypeMemberDeclaration.MemberDeclarationModifiers.Private) != 0)
{
currentModifiers &= ~CodeTypeMemberDeclaration.MemberDeclarationModifiers.Private;
textWriter.Write("private ");
continue;
}
if((currentModifiers & CodeTypeMemberDeclaration.MemberDeclarationModifiers.Public) != 0)
{
currentModifiers &= ~CodeTypeMemberDeclaration.MemberDeclarationModifiers.Public;
textWriter.Write("public ");
continue;
}
if((currentModifiers & CodeTypeMemberDeclaration.MemberDeclarationModifiers.Protected) != 0)
{
currentModifiers &= ~CodeTypeMemberDeclaration.MemberDeclarationModifiers.Protected;
textWriter.Write("protected ");
continue;
}
if((currentModifiers & CodeTypeMemberDeclaration.MemberDeclarationModifiers.Abstract) != 0)
{
currentModifiers &= ~CodeTypeMemberDeclaration.MemberDeclarationModifiers.Abstract;
textWriter.Write("abstract ");
continue;
}
if((currentModifiers & CodeTypeMemberDeclaration.MemberDeclarationModifiers.Assembly) != 0)
{
currentModifiers &= ~CodeTypeMemberDeclaration.MemberDeclarationModifiers.Assembly;
textWriter.Write("internal ");
continue;
}
if((currentModifiers & CodeTypeMemberDeclaration.MemberDeclarationModifiers.Const) != 0)
{
currentModifiers &= ~CodeTypeMemberDeclaration.MemberDeclarationModifiers.Const;
textWriter.Write("const ");
continue;
}
if((currentModifiers & CodeTypeMemberDeclaration.MemberDeclarationModifiers.ReadOnly) != 0)
{
currentModifiers &= ~CodeTypeMemberDeclaration.MemberDeclarationModifiers.ReadOnly;
textWriter.Write("readonly ");
continue;
}
if((currentModifiers & CodeTypeMemberDeclaration.MemberDeclarationModifiers.Extern) != 0)
{
currentModifiers &= ~CodeTypeMemberDeclaration.MemberDeclarationModifiers.Extern;
textWriter.Write("extern ");
continue;
}
if((currentModifiers & CodeTypeMemberDeclaration.MemberDeclarationModifiers.ProtectedAndAssembly) != 0)
{
currentModifiers &= ~CodeTypeMemberDeclaration.MemberDeclarationModifiers.ProtectedAndAssembly;
textWriter.Write("protected internal ");
continue;
}
if((currentModifiers & CodeTypeMemberDeclaration.MemberDeclarationModifiers.New) != 0)
{
currentModifiers &= ~CodeTypeMemberDeclaration.MemberDeclarationModifiers.New;
textWriter.Write("new ");
continue;
}
if((currentModifiers & CodeTypeMemberDeclaration.MemberDeclarationModifiers.Override) != 0)
{
currentModifiers &= ~CodeTypeMemberDeclaration.MemberDeclarationModifiers.Override;
textWriter.Write("override ");
continue;
}
if((currentModifiers & CodeTypeMemberDeclaration.MemberDeclarationModifiers.Sealed) != 0)
{
currentModifiers &= ~CodeTypeMemberDeclaration.MemberDeclarationModifiers.Sealed;
textWriter.Write("sealed ");
continue;
}
if((currentModifiers & CodeTypeMemberDeclaration.MemberDeclarationModifiers.Static) != 0)
{
currentModifiers &= ~CodeTypeMemberDeclaration.MemberDeclarationModifiers.Static;
textWriter.Write("static ");
continue;
}
if((currentModifiers & CodeTypeMemberDeclaration.MemberDeclarationModifiers.Unsafe) != 0)
{
currentModifiers &= ~CodeTypeMemberDeclaration.MemberDeclarationModifiers.Unsafe;
textWriter.Write("unsafe ");
continue;
}
if((currentModifiers & CodeTypeMemberDeclaration.MemberDeclarationModifiers.Virtual) != 0)
{
currentModifiers &= ~CodeTypeMemberDeclaration.MemberDeclarationModifiers.Virtual;
textWriter.Write("virtual ");
continue;
}
if((currentModifiers & CodeTypeMemberDeclaration.MemberDeclarationModifiers.Volatile) != 0)
{
currentModifiers &= ~CodeTypeMemberDeclaration.MemberDeclarationModifiers.Volatile;
textWriter.Write("volatile ");
continue;
}
break;
}
}
static private void GenerateCommentsCode(CodeComment comment,IndentedTextWriter textWriter)
{
if(comment.Comment != null)
GenerateCode(comment.Comment,textWriter);
switch(comment.Style)
{
case CodeComment.CodeCommentStyle.SingleLine:
{
foreach(String line in comment.Lines)
textWriter.WriteLine("//" + line);
break;
}
case CodeComment.CodeCommentStyle.Documentation:
{
foreach(String line in comment.Lines)
textWriter.WriteLine("///" + line);
break;
}
case CodeComment.CodeCommentStyle.Multiline:
{
textWriter.Write("/*");
if(comment.Lines.Count == 1)
{
textWriter.Write(comment.Lines[0]);
textWriter.Write("*/");
}
else
{
foreach(String line in comment.Lines)
textWriter.WriteLine(line);
textWriter.WriteLine("*/");
}
break;
}
}
}
static private void GenerateCommentsCode(CodeCommentCollection comments,IndentedTextWriter textWriter)
{
foreach(CodeComment comment in comments)
{
GenerateCommentsCode(comment,textWriter);
}
}
static private void GenerateNamespaceImportCode(CodeNamespaceImport namespaceImport,IndentedTextWriter textWriter)
{
string code;
if(namespaceImport.Alias.Length == 0)
code = String.Format("using {0};",namespaceImport.ImportedName);
else
code = String.Format("using {0} = {1};",namespaceImport.Alias,namespaceImport.ImportedName);
textWriter.WriteLine(code);
}
static private void GenerateNamespaceCode(CodeNamespace codeNamespace,IndentedTextWriter textWriter)
{
//generate namespace import first
foreach(CodeNamespaceImport namespaceImport in codeNamespace.Imports)
GenerateNamespaceImportCode(namespaceImport,textWriter);
if(codeNamespace.Imports.Count != 0)
textWriter.WriteLine("");
//generate namespace itself and than call for generating its members
if(codeNamespace.Name.Length != 0)
{
textWriter.WriteLine("namespace " + codeNamespace.Name);
textWriter.WriteLine("{");
textWriter.Indent+=4;
}
//generate nested namespaces first
foreach(CodeNamespace nestedNamespace in codeNamespace.NestedNamespaces)
GenerateCode(nestedNamespace,textWriter);
//Now generate types
foreach(CodeTypeDeclaration declaredType in codeNamespace.DeclaredTypes)
GenerateCode(declaredType,textWriter);
if(codeNamespace.Name.Length != 0)
{
textWriter.Indent-=4;
textWriter.WriteLine("}");
}
}
static private void GenerateTypeFieldDeclaration(CodeTypeFieldDeclaration fieldDeclaration,IndentedTextWriter textWriter)
{
foreach(CodeAttribute attrbute in fieldDeclaration.Attributes)
{
GenerateCode(attrbute,textWriter);
textWriter.WriteLine();
}
GenerateTypeMemberDeclarationModifiers(fieldDeclaration.Modifiers,textWriter);
GenerateCode(fieldDeclaration.DeclarationType,textWriter);
textWriter.Write(" ");
bool firstDeclaration = true;
foreach(CodeVariableDeclarationMember declarationMember in fieldDeclaration.DeclaredFields)
{
if(firstDeclaration)
{
firstDeclaration = false;
}
else
{
textWriter.Write(", ");
}
GenerateCode(declarationMember,textWriter);
}
textWriter.WriteLine(";");
}
static private void GenerateTypeEventDeclaration(CodeTypeEventDeclaration eventDeclaration,IndentedTextWriter textWriter)
{
foreach(CodeAttribute attrbute in eventDeclaration.Attributes)
{
GenerateCode(attrbute,textWriter);
textWriter.WriteLine();
}
GenerateTypeMemberDeclarationModifiers(eventDeclaration.Modifiers,textWriter);
textWriter.Write("event ");
GenerateCode(eventDeclaration.DeclarationType,textWriter);
textWriter.Write(" ");
textWriter.WriteLine(eventDeclaration.Name);
bool isAbstract = (eventDeclaration.Modifiers & CodeTypeMemberDeclaration.MemberDeclarationModifiers.Abstract) != 0;
textWriter.WriteLine("{");
textWriter.Indent+=4;
if(eventDeclaration.AddAccessorStatements != null)
{
foreach(CodeAttribute attrbute in eventDeclaration.AddAccessorAttributes)
{
GenerateCode(attrbute,textWriter);
textWriter.WriteLine();
}
textWriter.Write("add");
if(isAbstract && eventDeclaration.AddAccessorStatements.Statements.Count == 0)
{
textWriter.WriteLine(";");
}
else
{
textWriter.WriteLine();
textWriter.WriteLine("{");
textWriter.Indent+=4;
foreach(CodeElement statement in eventDeclaration.AddAccessorStatements.Statements)
{
GenerateCode(statement,textWriter);
}
//get close
textWriter.Indent-=4;
textWriter.WriteLine("}");
}
}
if(eventDeclaration.RemoveAccessorStatements != null)
{
foreach(CodeAttribute attrbute in eventDeclaration.RemoveAccessorAttributes)
{
GenerateCode(attrbute,textWriter);
textWriter.WriteLine();
}
textWriter.Write("add");
if(isAbstract && eventDeclaration.RemoveAccessorStatements.Statements.Count == 0)
{
textWriter.WriteLine(";");
}
else
{
textWriter.WriteLine();
textWriter.WriteLine("{");
textWriter.Indent+=4;
foreach(CodeElement statement in eventDeclaration.RemoveAccessorStatements.Statements)
{
GenerateCode(statement,textWriter);
}
//get close
textWriter.Indent-=4;
textWriter.WriteLine("}");
}
}
//Property close
textWriter.Indent-=4;
textWriter.WriteLine("}");
}
static private void GenerateTypeEventListDeclaration(CodeTypeEventListDeclaration eventListDeclaration,IndentedTextWriter textWriter)
{
foreach(CodeAttribute attrbute in eventListDeclaration.Attributes)
{
GenerateCode(attrbute,textWriter);
textWriter.WriteLine();
}
GenerateTypeMemberDeclarationModifiers(eventListDeclaration.Modifiers,textWriter);
textWriter.Write("event ");
GenerateCode(eventListDeclaration.DeclarationType,textWriter);
textWriter.Write(" ");
bool firstDeclaration = true;
foreach(CodeVariableDeclarationMember declarationMember in eventListDeclaration.DeclaredEvents)
{
if(firstDeclaration)
{
firstDeclaration = false;
}
else
{
textWriter.Write(", ");
}
GenerateCode(declarationMember,textWriter);
}
textWriter.WriteLine(";");
}
static private void GenerateVariableDeclarationMemberCode(CodeVariableDeclarationMember declarationMember,IndentedTextWriter textWriter)
{
textWriter.Write(declarationMember.Name);
if(declarationMember.Initializer != null)
{
textWriter.Write(" = ");
GenerateCode(declarationMember.Initializer,textWriter);
}
}
static private void GenerateStructDeclarationCode(CodeStructDeclaration structDeclaration,IndentedTextWriter textWriter)
{
//Attributes first
foreach(CodeAttribute attribute in structDeclaration.Attributes)
{
GenerateCode(attribute,textWriter);
textWriter.WriteLine();
}
GenerateTypeDeclarationModifiers(structDeclaration.Modifiers,textWriter);
textWriter.Write("struct ");
textWriter.Write(structDeclaration.Name);
if(structDeclaration.Interfaces.Count != 0)
{
textWriter.Write(" : ");
bool firstBase = true;
foreach(CodeTypeReference baseType in structDeclaration.Interfaces)
{
if(!firstBase)
{
textWriter.Write(", ");
}
else
{
firstBase = false;
}
GenerateCode(baseType,textWriter);
}
}
textWriter.WriteLine("");
textWriter.WriteLine("{");
textWriter.Indent+=4;
foreach(CodeElement nestedType in structDeclaration.NestedTypes)
{
GenerateCode(nestedType,textWriter);
textWriter.WriteLine("");
}
foreach(CodeElement typeMember in structDeclaration.Members)
{
GenerateCode(typeMember,textWriter);
}
textWriter.Indent-=4;
textWriter.WriteLine("}");
textWriter.WriteLine("");
}
static private void GenerateClassDeclarationCode(CodeClassDeclaration classDeclaration,IndentedTextWriter textWriter)
{
//Attributes first
foreach(CodeAttribute attribute in classDeclaration.Attributes)
{
GenerateCode(attribute,textWriter);
textWriter.WriteLine();
}
GenerateTypeDeclarationModifiers(classDeclaration.Modifiers,textWriter);
textWriter.Write("class ");
textWriter.Write(classDeclaration.Name);
if(classDeclaration.BaseTypes.Count != 0)
{
textWriter.Write(" : ");
bool firstBase = true;
foreach(CodeTypeReference baseType in classDeclaration.BaseTypes)
{
if(!firstBase)
{
textWriter.Write(", ");
}
else
{
firstBase = false;
}
GenerateCode(baseType,textWriter);
}
}
textWriter.WriteLine("");
textWriter.WriteLine("{");
textWriter.Indent+=4;
foreach(CodeElement nestedType in classDeclaration.NestedTypes)
{
GenerateCode(nestedType,textWriter);
textWriter.WriteLine("");
}
foreach(CodeElement typeMember in classDeclaration.Members)
{
GenerateCode(typeMember,textWriter);
}
textWriter.Indent-=4;
textWriter.WriteLine("}");
textWriter.WriteLine("");
}
static private void GenerateInterfaceDeclarationCode(CodeInterfaceDeclaration interfaceDeclaration,IndentedTextWriter textWriter)
{
//Attributes first
foreach(CodeAttribute attribute in interfaceDeclaration.Attributes)
{
GenerateCode(attribute,textWriter);
textWriter.WriteLine();
}
GenerateTypeDeclarationModifiers(interfaceDeclaration.Modifiers,textWriter);
textWriter.Write("interface ");
textWriter.Write(interfaceDeclaration.Name);
if(interfaceDeclaration.Interfaces.Count != 0)
{
textWriter.Write(" : ");
bool firstBase = true;
foreach(CodeTypeReference baseType in interfaceDeclaration.Interfaces)
{
if(!firstBase)
{
textWriter.Write(", ");
}
else
{
firstBase = false;
}
GenerateCode(baseType,textWriter);
}
}
textWriter.WriteLine("");
textWriter.WriteLine("{");
textWriter.Indent+=4;
foreach(CodeElement typeMember in interfaceDeclaration.Members)
GenerateCode(typeMember,textWriter);
textWriter.Indent-=4;
textWriter.WriteLine("}");
textWriter.WriteLine("");
}
static private void GenerateEnumDeclarationCode(CodeEnumDeclaration enumDeclaration,IndentedTextWriter textWriter)
{
//Attributes first
foreach(CodeAttribute attribute in enumDeclaration.Attributes)
{
GenerateCode(attribute,textWriter);
textWriter.WriteLine();
}
GenerateTypeDeclarationModifiers(enumDeclaration.Modifiers,textWriter);
textWriter.Write("enum ");
textWriter.Write(enumDeclaration.Name);
if(enumDeclaration.EnumBase != null)
{
textWriter.Write(" : ");
GenerateCode(enumDeclaration.EnumBase,textWriter);
}
textWriter.WriteLine("");
textWriter.WriteLine("{");
textWriter.Indent+=4;
foreach(CodeEnumMember enumMember in enumDeclaration.Members)
{
textWriter.Write(enumMember.Name);
if(enumMember.Value != null)
{
textWriter.Write(" = ");
GenerateCode(enumMember.Value,textWriter);
}
textWriter.WriteLine(",");
}
textWriter.Indent-=4;
textWriter.WriteLine("}");
textWriter.WriteLine("");
}
static private void GenerateTypeReferenceCode(CodeTypeReference typeReference,IndentedTextWriter textWriter)
{
if(typeReference.IsArray)
{
GenerateTypeReferenceCode(typeReference.ArrayElementType,textWriter);
textWriter.Write("[]");
return;
}
if(typeReference.IsPointer)
{
GenerateTypeReferenceCode(typeReference.PointerType,textWriter);
textWriter.Write("*");
return;
}
switch(typeReference.TypeName)
{
case "System.Void":
{
textWriter.Write("void");
break;
}
case "System.String":
{
textWriter.Write("string");
break;
}
case "System.Boolean":
{
textWriter.Write("bool");
break;
}
case "System.Int32":
{
textWriter.Write("int");
break;
}
case "System.Int64":
{
textWriter.Write("long");
break;
}
default:
{
textWriter.Write(typeReference.TypeName);
break;
}
}
}
static private void GenerateCode(CodeElement codeElement,IndentedTextWriter textWriter)
{
//Always write comments first if they exist
if(codeElement.Comment != null)
{
GenerateCommentsCode(codeElement.Comment,textWriter);
if(codeElement.Comment.Style == CodeComment.CodeCommentStyle.Multiline && codeElement.Comment.Lines.Count == 1 &&
(codeElement is CodeNamespace || codeElement is CodeStatement || codeElement is CodeTypeDeclaration || codeElement is CodeTypeMemberDeclaration))
{
textWriter.WriteLine();
}
}
if(codeElement.DocumentationComment != null)
GenerateCommentsCode(codeElement.DocumentationComment,textWriter);
#region CodeComment
if(codeElement is CodeComment)
{
GenerateCommentsCode(codeElement as CodeComment,textWriter);
return;
}
#endregion
#region Namespace
if(codeElement is CodeNamespace)
{
GenerateNamespaceCode(codeElement as CodeNamespace,textWriter);
return;
}
if(codeElement is CodeNamespaceImport)
{
GenerateNamespaceImportCode(codeElement as CodeNamespaceImport,textWriter);
return;
}
#endregion
#region CodeClassDeclaration
if(codeElement is CodeClassDeclaration)
{
GenerateClassDeclarationCode(codeElement as CodeClassDeclaration,textWriter);
return;
}
#endregion
#region GenerateStructDeclarationCode
if(codeElement is CodeStructDeclaration)
{
GenerateStructDeclarationCode(codeElement as CodeStructDeclaration,textWriter);
return;
}
#endregion
#region CodeInterfaceDeclaration
if(codeElement is CodeInterfaceDeclaration)
{
GenerateInterfaceDeclarationCode(codeElement as CodeInterfaceDeclaration,textWriter);
return;
}
#endregion
#region CodeAttribute
if(codeElement is CodeAttribute)
{
GenerateAttributeCode(codeElement as CodeAttribute,textWriter);
return;
}
#endregion
#region CodeArgument
if(codeElement is CodeArgument)
{
GenerateArgumentCode(codeElement as CodeArgument,textWriter);
return;
}
#endregion
#region CodeTypeFieldDeclaration
if(codeElement is CodeTypeFieldDeclaration)
{
GenerateTypeFieldDeclaration(codeElement as CodeTypeFieldDeclaration,textWriter);
return;
}
#endregion
#region CodeTypeReference
if(codeElement is CodeTypeReference)
{
GenerateTypeReferenceCode(codeElement as CodeTypeReference,textWriter);
return;
}
if(codeElement is CodeVariableDeclarationMember)
{
GenerateVariableDeclarationMemberCode(codeElement as CodeVariableDeclarationMember,textWriter);
return;
}
#endregion
#region CodeTypeMethodDeclaration
if(codeElement is CodeTypeMethodDeclaration)
{
GenerateTypeMethodDeclaration(codeElement as CodeTypeMethodDeclaration,textWriter);
return;
}
#endregion
#region CodeEnumDeclaration
if(codeElement is CodeEnumDeclaration)
{
GenerateEnumDeclarationCode(codeElement as CodeEnumDeclaration,textWriter);
return;
}
#endregion
#region CodeMethodParameter
if(codeElement is CodeMethodParameter)
{
CodeMethodParameter parameter = codeElement as CodeMethodParameter;
foreach(CodeAttribute attribute in parameter.Attributes)
GenerateCode(attribute,textWriter);
if(parameter.Type.TypeName != "System.Void")
GenerateCode(parameter.Type,textWriter);
textWriter.Write(" " + parameter.Name);
return;
}
#endregion
#region CodeTypePropertyDeclaration
if(codeElement is CodeTypePropertyDeclaration)
{
GenerateTypePropertyDeclaration(codeElement as CodeTypePropertyDeclaration,textWriter);
return;
}
#endregion
#region CodeTypeDelegateDeclaration
if(codeElement is CodeTypeDelegateDeclaration)
{
GenerateTypeDelegateDeclaration(codeElement as CodeTypeDelegateDeclaration,textWriter);
return;
}
#endregion
#region CodeExpression
if(codeElement is CodeExpression)
{
GenerateExpressionCode(codeElement as CodeExpression,textWriter);
return;
}
#endregion CodeExpression
#region CodeSwitchCase
if(codeElement is CodeSwitchCase)
{
CodeSwitchCase statement = codeElement as CodeSwitchCase;
textWriter.Write("case ");
GenerateCode(statement.Expression,textWriter);
textWriter.WriteLine(" :");
textWriter.Indent+=4;
foreach(CodeStatement switchStatement in statement.Statements)
GenerateCode(switchStatement,textWriter);
textWriter.Indent-=4;
return;
}
#endregion
#region CodeStatement
if(codeElement is CodeStatement)
{
GenerateStatementCode(codeElement as CodeStatement,textWriter);
return;
}
#endregion CodeExpression
#region CodeCatchClause
if(codeElement is CodeCatchClause)
{
CodeCatchClause statement = codeElement as CodeCatchClause;
textWriter.Write("catch");
if(statement.CatchExceptionType != null)
{
textWriter.Write("(");
GenerateCode(statement.CatchExceptionType,textWriter);
if(statement.LocalName != null && statement.LocalName.Length != 0)
{
textWriter.Write(" ");
textWriter.Write(statement.LocalName);
}
textWriter.WriteLine(")");
}
else
{
textWriter.WriteLine();
}
GenerateCode(statement.Statements,textWriter);
return;
}
#endregion
#region CodeTypeEventListDeclaration
if(codeElement is CodeTypeEventListDeclaration)
{
GenerateTypeEventListDeclaration(codeElement as CodeTypeEventListDeclaration,textWriter);
return;
}
#endregion
#region CodeTypeEventDeclaration
if(codeElement is CodeTypeEventDeclaration)
{
GenerateTypeEventDeclaration(codeElement as CodeTypeEventDeclaration,textWriter);
return;
}
#endregion
textWriter.WriteLine("<" + codeElement.ToString() + ">");
return;
}
public static StringBuilder GenerateCode(CodeElementCollectionBase codeElements)
{
return GenerateCode(codeElements,0);
}
public static StringBuilder GenerateCode(CodeElementCollectionBase codeElements,int initialIndent)
{
//Generate code to add
StringBuilder codeStringBuilder = new StringBuilder();
using(TextWriter textWriter = new StringWriter(codeStringBuilder))
using(IndentedTextWriter writer = new IndentedTextWriter(textWriter," "))
{
writer.Indent = initialIndent;
foreach(CodeElement codeElement in codeElements)
{
GenerateCode(codeElement,writer);
}
}
return codeStringBuilder;
}
public static StringBuilder GenerateCode(CodeElement codeElement)
{
return GenerateCode(codeElement,0);
}
public static StringBuilder GenerateCode(CodeElement codeElement,int initialIndent)
{
//Generate code to add
StringBuilder codeStringBuilder = new StringBuilder();
using(TextWriter textWriter = new StringWriter(codeStringBuilder))
using(IndentedTextWriter writer = new IndentedTextWriter(textWriter," "))
{
writer.Indent = initialIndent;
GenerateCode(codeElement,writer);
}
return codeStringBuilder;
}
#endregion Code generation Methods
}
}
|