Click here to Skip to main content
15,885,856 members
Articles / Programming Languages / C#

CodeDom Assistant

Rate me:
Please Sign up or sign in to vote.
4.84/5 (26 votes)
21 Sep 20074 min read 137.7K   6.6K   82  
Generating CodeDom Code By Parsing C# or VB
using System;
using System.ComponentModel;
using System.CodeDom;
using System.Collections;
using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.Parser;
using ICSharpCode.NRefactory.Visitors;
using ICSharpCode.NRefactory.PrettyPrinter;

namespace CodeDomAssistant
{
	/// <summary>
    /// Summary description for CodeDomCodeProvider.
	/// </summary>
	public class CodeDomCodeProvider : System.CodeDom.Compiler.CodeDomProvider
	{
        
		public CodeDomCodeProvider()
            : base()
		{
		}

        public override string FileExtension
        {
            get
            {
                return "cs";
            }
        }

        public override System.CodeDom.Compiler.ICodeGenerator CreateGenerator()
        {
            return new CodeGenerator();
        }

        public override System.CodeDom.Compiler.ICodeCompiler CreateCompiler()
        {
            return null;
        }
	}

    /// <summary>
    /// Generate CodeDom into a C# CodeDom Source File
    /// </summary>
    public class CodeGenerator : System.CodeDom.Compiler.ICodeGenerator
    {
        Hashtable codedomVar = new Hashtable(); 

        public CodeGenerator()
            : base()
        {
        }

        /// <summary>
        /// Construct valid C# Name
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        string MakeName(string name)
        {
            name = name.Replace(".", "_");

            return "_" + name;
        }

        /// <summary>
        /// Get Next Variable Name to ensure no collisions
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        string GetNextVar(string name)
        {
            if (name == string.Empty)
            {
                name = "codedom";
            }

            if (codedomVar.ContainsKey(name))
            {
                int id = ((int)codedomVar[name]) + 1;
                codedomVar[name] = id;

                return MakeName(name) + id.ToString();
            }

            codedomVar[name] = 1;

            return MakeName(name) + "1";
        }

        #region ICodeGenerator Members

        public bool Supports(System.CodeDom.Compiler.GeneratorSupport supports)
        {
            // TODO:  Add MyCodeGenerator.Supports implementation
            return true;
        }

        public void GenerateCodeFromType(CodeTypeDeclaration e, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            GenerateCodeTypeDeclaration(null, e, w, o);
        }

        public string CreateValidIdentifier(string value)
        {
            return GetNextVar(value);
        }

        public void GenerateCodeFromNamespace(CodeNamespace e, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            GenerateCodeNamespace(null, e, w, o);
        }

        public void GenerateCodeFromCompileUnit(CodeCompileUnit e, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            GenerateCodeCompileUnit(e, w, o);
        }

        public void GenerateCodeFromExpression(CodeExpression e, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            GenerateCodeExpression(null, e, w, o);
        }

        public void GenerateCodeFromStatement(CodeStatement e, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            GenerateCodeStatement(null, e, w, o);
        }

        public void ValidateIdentifier(string value)
        {
            // TODO:  Add MyCodeGenerator.ValidateIdentifier implementation
        }

        public string GetTypeOutput(CodeTypeReference type)
        {
//            this.GenerateCodeTypeReference(null, type, w, o);
            // TODO:  Add MyCodeGenerator.GetTypeOutput implementation
            return null;
        }

        public string CreateEscapedIdentifier(string value)
        {
            // TODO:  Add MyCodeGenerator.CreateEscapedIdentifier implementation
            return null;
        }

        public bool IsValidIdentifier(string value)
        {
            // TODO:  Add MyCodeGenerator.IsValidIdentifier implementation
            return false;
        }

        #endregion

        string GenerateCodeAttributeArgument(string context, CodeAttributeArgument argument, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            string name = GetNextVar(argument.Name + "_arg");

            string exprName = GenerateCodeExpression(null, argument.Value, w, o);

            Debug.Assert(exprName != null);

            w.WriteLine(@"CodeAttributeArgument {0} = new CodeAttributeArgument(""{1}"", {2});", name, argument.Name, exprName);
            if (context != null && context.Length > 0)
            {
                w.WriteLine(@"{0}.Add({1});", context, name);
                w.WriteLine();
            }

            return name;
        }

        void GenerateCodeAttributeArguments(string context, CodeAttributeArgumentCollection arguments, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            // arguments
            if (arguments.Count > 0)
            {
                foreach (CodeAttributeArgument arg in arguments)
                {
                    GenerateCodeAttributeArgument(context, arg, w, o);
                }
            }
        }

        string GenerateCodeAttributeDeclaration(string context, CodeAttributeDeclaration attribute, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            string name = GetNextVar(attribute.Name + "_attr");

            w.WriteLine(@"CodeAttributeDeclaration {0} = new CodeAttributeDeclaration(""{1}"");", name, attribute.Name);
            this.GenerateCodeAttributeArguments(string.Format(@"{0}.Arguments"), attribute.Arguments, w, o);

            if (context != null && context.Length > 0)
            {
                w.WriteLine(@"{0}.Add({1});", context, name);
                w.WriteLine();
            }

            return name;
        }

        void GenerateCodeAttributeDeclarations(string context, CodeAttributeDeclarationCollection attributes, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            // attributes
            if (attributes.Count > 0)
            {
                foreach (CodeAttributeDeclaration attr in attributes)
                {
                    GenerateCodeAttributeDeclaration(context, attr, w, o);
                }
            }
        }

        string GenerateCodeCatchClause(string context, CodeCatchClause catchclause, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            string name = GetNextVar(catchclause.LocalName + "_exception");

            w.WriteLine(@"CodeCatchClause {0} = new CodeCatchClause();", name);

            if (catchclause.LocalName != null && catchclause.LocalName.Length > 0)
            {
                w.WriteLine(@"{0}.LocalName = ""{1}"";", name, catchclause.LocalName);
            }

            w.WriteLine(@"{0}.CatchExceptionType = {1};", name, this.GenerateCodeTypeReference(null, catchclause.CatchExceptionType, w, o));

            GenerateCodeStatements(string.Format(@"{0}.Statements", name), catchclause.Statements, w, o);

            if (context != null && context.Length > 0)
            {
                w.WriteLine(@"{0}.Add({1});", context, name);
                w.WriteLine();
            }

            return name;
        }

        void GenerateCodeCatchClauses(string context, CodeCatchClauseCollection catchclauses, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            // catchclauses
            if (catchclauses.Count > 0)
            {
                foreach (CodeCatchClause catchclause in catchclauses)
                {
                    GenerateCodeCatchClause(context, catchclause, w, o);
                }
            }
        }

        string GenerateCodeComment(string context, CodeComment comment, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            string name = GetNextVar("comment");

            w.WriteLine(@"CodeComment {0} = new CodeComment();", name);

            if (comment.DocComment)
            {
                w.WriteLine(@"{0}.DocComment = {1};", name, comment.DocComment.ToString().ToLower());
            }

            if (comment.Text != null && comment.Text.Length > 0)
            {
                w.WriteLine(@"{0}.Text = ""{1}"";", name, comment.Text);
            }

            if (context != null && context.Length > 0)
            {
                w.WriteLine(@"{0}.Add({1});", context, name);
                w.WriteLine();
            }

            return name;
        }

        void GenerateCodeComments(string context, CodeCommentStatementCollection comments, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            // comments
            if (comments.Count > 0)
            {
                foreach (CodeCommentStatement comment in comments)
                {
                    w.WriteLine(@"{0}.Add(new CodeCommentStatement(""{1}"", {2}));", context, comment.Comment.Text, comment.Comment.DocComment);
                }
            }
        }

        void GenerateCodeCompileUnit(CodeCompileUnit e, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            string name = this.GetNextVar("compileunit");

            w.WriteLine(@"// CodeDom Compile Unit");
            w.WriteLine(@"CodeCompileUnit {0} = new CodeCompileUnit();", name);

            if (e.ReferencedAssemblies.Count > 0)
            {
                if (o.BlankLinesBetweenMembers)
                {
                    w.WriteLine();
                }

                w.WriteLine(@"// Referenced Assemblies");
                foreach (string refassembly in e.ReferencedAssemblies)
                {
                    w.WriteLine(@"{0}.ReferencedAssemblies.Add(""{1}"");", name, refassembly);
                }
            }

            GenerateCodeNamespaces(string.Format("{0}.Namespaces", name), e.Namespaces, w, o);
        }

        string GenerateCodeEventReferenceExpression(string context, CodeEventReferenceExpression e, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            CodeEventReferenceExpression expr = (CodeEventReferenceExpression)e;

            string name = GetNextVar("event");

            w.WriteLine(@"CodeEventReferenceExpression {0} = new CodeEventReferenceExpression();", name);

            w.WriteLine(@"{0}.EventName = ""{1}"";", name, expr.EventName);
            w.WriteLine(@"{0}.TargetObject = {1};", name, GenerateCodeExpression(null, expr.TargetObject, w, o));

            if (context != null && context.Length > 0)
            {
                w.WriteLine(@"{0}.Add({1});", context, name);
                w.WriteLine();
            }

            return name;
        }

        string GenerateCodeExpression(string context, CodeExpression e, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            if (e == null)
            {
                return "null";
            }

            if (e is CodeArrayCreateExpression)
            {
                CodeArrayCreateExpression expr = (CodeArrayCreateExpression)e;

                string name = GetNextVar("arr");

                w.WriteLine(@"CodeArrayCreateExpression {0} = new CodeArrayCreateExpression();", name);

                if (expr.CreateType != null)
                {
                    string type = GenerateCodeTypeReference(null, expr.CreateType, w, o);
                    w.WriteLine(@"{0}.CreateType = {1};", name, type);
                }

                GenerateCodeExpressions(string.Format(@"{0}.Initializers", name), expr.Initializers, w, o);

                w.WriteLine(@"{0}.Size = {1};", name, expr.Size);

                if (expr.SizeExpression != null)
                {
                    string sizeexpr = GenerateCodeExpression(null, expr.SizeExpression, w, o);
                    w.WriteLine(@"{0}.SizeExpression = {1};", name, sizeexpr);
                }

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodeBaseReferenceExpression) 
            {
                CodeBaseReferenceExpression expr = (CodeBaseReferenceExpression)e;

                string name = GetNextVar("base");

                w.WriteLine(@"CodeBaseReferenceExpression {0} = new CodeBaseReferenceExpression();", name);
                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodeBinaryOperatorExpression) 
            {
                CodeBinaryOperatorExpression expr = (CodeBinaryOperatorExpression)e;

                string name = GetNextVar("binop");

                w.WriteLine(@"CodeBinaryOperatorExpression {0} = new CodeBinaryOperatorExpression();", name);

                w.WriteLine(@"{0}.Left = {1};", name, GenerateCodeExpression(null, expr.Left, w, o));
                w.WriteLine(@"{0}.Operator = {1};", name, GetCodeBinaryOperatorType(expr.Operator));
                w.WriteLine(@"{0}.Right = {1};", name, GenerateCodeExpression(null, expr.Right, w, o));

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodeCastExpression) 
            {
                CodeCastExpression expr = (CodeCastExpression)e;

                string name = GetNextVar("cast");

                w.WriteLine(@"CodeCastExpression {0} = new CodeCastExpression();", name);

                w.WriteLine(@"{0}.Expression = {1};", name, GenerateCodeExpression(null, expr.Expression, w, o));
                w.WriteLine(@"{0}.TargetType = {1};", name, this.GenerateCodeTypeReference(null, expr.TargetType, w, o));

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodeDelegateCreateExpression) 
            {
                CodeDelegateCreateExpression expr = (CodeDelegateCreateExpression)e;

                string name = GetNextVar("delegate");

                w.WriteLine(@"CodeDelegateCreateExpression {0} = new CodeDelegateCreateExpression();", name);

                w.WriteLine(@"{0}.DelegateType = {1};", name, this.GenerateCodeTypeReference(null, expr.DelegateType, w, o));
                w.WriteLine(@"{0}.MethodName = ""{1}"";", name, expr.MethodName);
                w.WriteLine(@"{0}.TargetObject = {1};", name, GenerateCodeExpression(null, expr.TargetObject, w, o));

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodeFieldReferenceExpression) 
            {
                CodeFieldReferenceExpression expr = (CodeFieldReferenceExpression)e;

                string name = GetNextVar("field");

                w.WriteLine(@"CodeFieldReferenceExpression {0} = new CodeFieldReferenceExpression();", name);

                w.WriteLine(@"{0}.FieldName = ""{1}"";", name, expr.FieldName);
                w.WriteLine(@"{0}.TargetObject = {1};", name, GenerateCodeExpression(null, expr.TargetObject, w, o));

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodeArgumentReferenceExpression) 
            {
                CodeArgumentReferenceExpression expr = (CodeArgumentReferenceExpression)e;

                string name = GetNextVar("arg");

                w.WriteLine(@"CodeArgumentReferenceExpression {0} = new CodeArgumentReferenceExpression();", name);

                w.WriteLine(@"{0}.ParameterName = ""{1}"";", name, expr.ParameterName);

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodeVariableReferenceExpression) 
            {
                CodeVariableReferenceExpression expr = (CodeVariableReferenceExpression)e;

                string name = GetNextVar("arg");

                w.WriteLine(@"CodeVariableReferenceExpression {0} = new CodeVariableReferenceExpression();", name);

                w.WriteLine(@"{0}.VariableName = ""{1}"";", name, expr.VariableName);

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodeIndexerExpression) 
            {
                CodeIndexerExpression expr = (CodeIndexerExpression)e;

                string name = GetNextVar("index");

                w.WriteLine(@"CodeIndexerExpression {0} = new CodeIndexerExpression();", name);

                GenerateCodeExpressions(string.Format(@"{0}.Indices", name), expr.Indices, w, o);

                w.WriteLine(@"{0}.TargetObject = {1};", name, GenerateCodeExpression(null, expr.TargetObject, w, o));

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodeArrayIndexerExpression) 
            {
                CodeArrayIndexerExpression expr = (CodeArrayIndexerExpression)e;

                string name = GetNextVar("arrindex");

                w.WriteLine(@"CodeArrayIndexerExpression {0} = new CodeArrayIndexerExpression();", name);

                GenerateCodeExpressions(string.Format(@"{0}.Indices", name), expr.Indices, w, o);

                w.WriteLine(@"{0}.TargetObject = {1};", name, GenerateCodeExpression(null, expr.TargetObject, w, o));

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodeSnippetExpression) 
            {
                CodeSnippetExpression expr = (CodeSnippetExpression)e;

                string name = GetNextVar("snippet");

                w.WriteLine(@"CodeSnippetExpression {0} = new CodeSnippetExpression();", name);

                w.WriteLine(@"{0}.Value = ""{1}"";", name, Escape(expr.Value));

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodeMethodInvokeExpression) 
            {
                CodeMethodInvokeExpression expr = (CodeMethodInvokeExpression)e;

                string name = GetNextVar("invoke");

                w.WriteLine(@"CodeMethodInvokeExpression {0} = new CodeMethodInvokeExpression();", name);

                GenerateCodeExpressions(string.Format(@"{0}.Parameters", name), expr.Parameters, w, o);
                
                w.WriteLine(@"{0}.Method = {1};", name, GenerateCodeMethodReferenceExpression(null, expr.Method, w, o));

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodeMethodReferenceExpression) 
            {
                CodeMethodReferenceExpression expr = (CodeMethodReferenceExpression)e;

                string name = GetNextVar("method");

                w.WriteLine(@"CodeMethodReferenceExpression {0} = new CodeMethodReferenceExpression();", name);

                w.WriteLine(@"{0}.MethodName = ""{1}"";", name, expr.MethodName);
                w.WriteLine(@"{0}.TargetObject = {1};", name, GenerateCodeExpression(null, expr.TargetObject, w, o));

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodeEventReferenceExpression) 
            {
                return GenerateCodeEventReferenceExpression(context, (CodeEventReferenceExpression)e, w, o);
            }
            
            if (e is CodeDelegateInvokeExpression) 
            {
                CodeDelegateInvokeExpression expr = (CodeDelegateInvokeExpression)e;

                string name = GetNextVar("invokedelegate");

                w.WriteLine(@"CodeDelegateInvokeExpression {0} = new CodeDelegateInvokeExpression();", name);

                GenerateCodeExpressions(string.Format(@"{0}.Parameters", name), expr.Parameters, w, o);

                w.WriteLine(@"{0}.TargetObject = {1};", name, GenerateCodeExpression(null, expr.TargetObject, w, o));

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodeObjectCreateExpression) 
            {
                CodeObjectCreateExpression expr = (CodeObjectCreateExpression)e;

                string name = GetNextVar("new");

                w.WriteLine(@"CodeObjectCreateExpression {0} = new CodeObjectCreateExpression();", name);

                w.WriteLine(@"{0}.CreateType = {1};", name, GenerateCodeTypeReference(null, expr.CreateType, w, o));
                
                GenerateCodeExpressions(string.Format(@"{0}.Parameters", name), expr.Parameters, w, o);

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodeParameterDeclarationExpression) 
            {
                return GenerateCodeParameterDeclarationExpression(context, (CodeParameterDeclarationExpression)e, w, o);
            }

            if (e is CodeDirectionExpression) 
            {
                CodeDirectionExpression expr = (CodeDirectionExpression)e;

                string name = GetNextVar("dir");

                w.WriteLine(@"CodeDirectionExpression {0} = new CodeDirectionExpression();", name);

                w.WriteLine(@"{0}.Direction = {1};", name, this.GetFieldDirection(expr.Direction));
                w.WriteLine(@"{0}.Expression = {1};", name, GenerateCodeExpression(null, expr.Expression, w, o));

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodePrimitiveExpression) 
            {
                CodePrimitiveExpression expr = (CodePrimitiveExpression)e;

                string name = GetNextVar("value");

                w.WriteLine(@"CodePrimitiveExpression {0} = new CodePrimitiveExpression();", name);

                // TODO - better primitive support
                if (expr.Value == null)
                {
                    w.WriteLine(@"{0}.Value = null;", name);
                }
                else if (expr.Value.GetType() == typeof(System.Char))
                {
                    w.WriteLine(@"{0}.Value = '{1}';", name, expr.Value.ToString());
                }
                else if (expr.Value.GetType() == typeof(System.String))
                {
                    w.WriteLine(@"{0}.Value = ""{1}"";", name, expr.Value.ToString());
                }
                else if (expr.Value.GetType() == typeof(System.Boolean))
                {
                    w.WriteLine(@"{0}.Value = {1};", name, expr.Value.ToString().ToLower());
                }
                else
                {
                    w.WriteLine(@"{0}.Value = {1};", name, expr.Value.ToString());
                }

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodePropertyReferenceExpression) 
            {
                CodePropertyReferenceExpression expr = (CodePropertyReferenceExpression)e;

                string name = GetNextVar("prop");

                w.WriteLine(@"CodePropertyReferenceExpression {0} = new CodePropertyReferenceExpression();", name);

                w.WriteLine(@"{0}.PropertyName = ""{1}"";", name, expr.PropertyName);
                w.WriteLine(@"{0}.TargetObject = {1};", name, GenerateCodeExpression(null, expr.TargetObject, w, o));

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodePropertySetValueReferenceExpression) 
            {
                CodePropertySetValueReferenceExpression expr = (CodePropertySetValueReferenceExpression)e;

                string name = GetNextVar("setprop");

                w.WriteLine(@"CodePropertySetValueReferenceExpression {0} = new CodePropertySetValueReferenceExpression();", name);
                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodeThisReferenceExpression) 
            {
                CodeThisReferenceExpression expr = (CodeThisReferenceExpression)e;

                string name = GetNextVar("this");

                w.WriteLine(@"CodeThisReferenceExpression {0} = new CodeThisReferenceExpression();", name);
                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }
            
            if (e is CodeTypeReferenceExpression) 
            {
                CodeTypeReferenceExpression expr = (CodeTypeReferenceExpression)e;

                string name = GetNextVar("ref");

                w.WriteLine(@"CodeTypeReferenceExpression {0} = new CodeTypeReferenceExpression();", name);

                w.WriteLine(@"{0}.Type = {1};", name, GenerateCodeTypeReference(null, expr.Type, w, o));

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodeTypeOfExpression) 
            {
                CodeTypeOfExpression expr = (CodeTypeOfExpression)e;

                string name = GetNextVar("typeof");

                w.WriteLine(@"CodeTypeOfExpression {0} = new CodeTypeOfExpression();", name);

                w.WriteLine(@"{0}.Type = {1};", name, GenerateCodeTypeReference(null, expr.Type, w, o));

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            Debug.Fail(string.Format("Generator for CodeExpression Type {0} Not Implemented", e.GetType().Name));

            return null;
        }

        void GenerateCodeExpressions(string context, CodeExpressionCollection exprs, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            if (exprs.Count > 0)
            {
                foreach (CodeExpression expr in exprs)
                {
                    GenerateCodeExpression(context, expr, w, o);
                }
            }
        }

        string GenerateCodeDirective(string context, CodeDirective e, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            if (e == null)
            {
                return "null";
            }

            if (e is CodeChecksumPragma)
            {
                CodeChecksumPragma directive = (CodeChecksumPragma)e;

                string name = GetNextVar("checksum");

                w.WriteLine(@"CodeChecksumPragma {0} = new CodeChecksumPragma();", name);

                w.WriteLine(@"{0}.ChecksumAlgorithmId = new Guid(""{1}"");", name, directive.ChecksumAlgorithmId.ToString("B"));
                w.WriteLine(@"{0}.ChecksumData = new byte[] { {1} };", name, GetByteData(directive.ChecksumData));
                w.WriteLine(@"{0}.FileName = ""{1}"";", name, directive.FileName);

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodeRegionDirective)
            {
                CodeRegionDirective directive = (CodeRegionDirective)e;

                string name = GetNextVar("region");

                w.WriteLine(@"CodeRegionDirective {0} = new CodeRegionDirective();", name);

                w.WriteLine(@"{0}.RegionMode = {1};", name, GetCodeRegionMode(directive.RegionMode));
                w.WriteLine(@"{0}.RegionText = ""{1}"";", name, directive.RegionText);

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            Debug.Fail(string.Format("Generator for CodeDirective Type {0} Not Implemented", e.GetType().Name));

            return null;
        }

        void GenerateCodeDirectives(string context, CodeDirectiveCollection directives, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            if (directives.Count > 0)
            {
                foreach (CodeDirective directive in directives)
                {
                    GenerateCodeDirective(context, directive, w, o);
                }
            }
        }

        string GenerateCodeMethodReferenceExpression(string context, CodeMethodReferenceExpression methodref, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            string name = GetNextVar(methodref.MethodName  + "_method");

            w.WriteLine(@"CodeMethodReferenceExpression {0} = new CodeMethodReferenceExpression();", name);

            w.WriteLine(@"{0}.MethodName = ""{1}"";", name, methodref.MethodName);

            w.WriteLine(@"{0}.TargetObject = {1};", name, GenerateCodeExpression(null, methodref.TargetObject, w, o));

            if (context != null && context.Length > 0)
            {
                w.WriteLine(@"{0}.Add({1});", context, name);
                w.WriteLine();
            }

            return name;
        }

        void GenerateCodeNamespaceImports(string context, CodeNamespaceImportCollection imports, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            // imports
            if (imports.Count > 0)
            {
                if (o.BlankLinesBetweenMembers)
                {
                    w.WriteLine();
                }

                w.WriteLine(@"// Imports");
                foreach (CodeNamespaceImport import in imports)
                {
                    w.WriteLine(@"{0}.Add(new CodeNamespaceImport(""{1}""));", context, import.Namespace);
                }
            }
        }

        string GenerateCodeNamespace(string context, CodeNamespace ns, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            if (o.BlankLinesBetweenMembers)
            {
                w.WriteLine();
            }

            w.WriteLine(@"//");
            w.WriteLine(@"// Namespace {0}", ns.Name);
            w.WriteLine(@"//");

            string name = GetNextVar(ns.Name  + "_namespace");

            w.WriteLine(@"CodeNamespace {0} = new CodeNamespace(""{1}"");", name, ns.Name);

            // comments
            GenerateCodeComments(string.Format("{0}.Comments", name), ns.Comments, w, o);

            // imports
            GenerateCodeNamespaceImports(string.Format("{0}.Imports", name), ns.Imports, w, o);

            // Types
            GenerateCodeTypeDeclarations(string.Format("{0}.Types", name), ns.Types, w, o);

            if (context != null && context.Length > 0)
            {
                w.WriteLine(@"{0}.Add({1});", context, name);
                w.WriteLine();
            }

            return name;
        }

        void GenerateCodeNamespaces(string context, CodeNamespaceCollection namespaces, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            if (namespaces.Count > 0)
            {
                if (o.BlankLinesBetweenMembers)
                {
                    w.WriteLine();
                }

                foreach (CodeNamespace ns in namespaces)
                {
                    GenerateCodeNamespace(context, ns, w, o);
                }
            }
        }

        string GenerateCodeParameterDeclarationExpression(string context, CodeParameterDeclarationExpression arg, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            string name = GetNextVar(arg.Name + "_arg");

            w.WriteLine(@"CodeParameterDeclarationExpression {0} = new CodeParameterDeclarationExpression({1}, ""{2}"");", name, this.GenerateCodeTypeReference(null, arg.Type, w, o), arg.Name);

            this.GenerateCodeAttributeDeclarations(string.Format(@"{0}.CustomAttributes", name), arg.CustomAttributes, w, o);

            w.WriteLine(@"{0}.Direction = {1};", name, this.GetFieldDirection(arg.Direction));
            w.WriteLine(@"{0}.Name = ""{1}"";", name, arg.Name);
            w.WriteLine(@"{0}.Type = {1};", name, GenerateCodeTypeReference(null, arg.Type, w, o));

            if (context != null && context.Length > 0)
            {
                w.WriteLine(@"{0}.Add({1});", context, name);
                w.WriteLine();
            }
 
            return name;
        }

        void GenerateCodeParameterDeclarationExpressions(string context, CodeParameterDeclarationExpressionCollection args, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            if (args.Count > 0)
            {
                foreach (CodeParameterDeclarationExpression arg in args)
                {
                    GenerateCodeParameterDeclarationExpression(context, arg, w, o);
                }
            }
        }

        string GenerateCodeStatement(string context, CodeStatement e, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            if (e == null)
            {
                return "null";
            }

            if (e is System.CodeDom.CodeMethodReturnStatement)
            {
                System.CodeDom.CodeMethodReturnStatement stmt = (System.CodeDom.CodeMethodReturnStatement)e;

                string name = GetNextVar("return");

                w.WriteLine(@"CodeMethodReturnStatement {0} = new CodeMethodReturnStatement();", name);

                if (stmt.Expression != null)
                {
                    w.WriteLine(@"{0}.Expression = {1};", name, GenerateCodeExpression(null, stmt.Expression, w, o));
                }

                GenerateCodeDirectives(string.Format(@"{0}.StartDirectives", name), stmt.StartDirectives, w, o);
                GenerateCodeDirectives(string.Format(@"{0}.EndDirectives", name), stmt.EndDirectives, w, o);

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodeCommentStatement) 
            {
                System.CodeDom.CodeCommentStatement stmt = (System.CodeDom.CodeCommentStatement)e;

                string name = GetNextVar("comment");

                w.WriteLine(@"CodeCommentStatement {0} = new CodeCommentStatement();", name);

                w.WriteLine(@"{0}.Comment = {1};", name, GenerateCodeComment(null, stmt.Comment, w, o));

                GenerateCodeDirectives(string.Format(@"{0}.StartDirectives", name), stmt.StartDirectives, w, o);
                GenerateCodeDirectives(string.Format(@"{0}.EndDirectives", name), stmt.EndDirectives, w, o);

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodeMethodReturnStatement) 
            {
                System.CodeDom.CodeMethodReturnStatement stmt = (System.CodeDom.CodeMethodReturnStatement)e;

                string name = GetNextVar("return");

                w.WriteLine(@"CodeMethodReturnStatement {0} = new CodeMethodReturnStatement();", name);

                if (stmt.Expression != null)
                {
                    w.WriteLine(@"{0}.Expression = {1};", name, GenerateCodeExpression(null, stmt.Expression, w, o));
                }

                GenerateCodeDirectives(string.Format(@"{0}.StartDirectives", name), stmt.StartDirectives, w, o);
                GenerateCodeDirectives(string.Format(@"{0}.EndDirectives", name), stmt.EndDirectives, w, o);

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodeConditionStatement) 
            {
                System.CodeDom.CodeConditionStatement stmt = (System.CodeDom.CodeConditionStatement)e;

                string name = GetNextVar("if");

                w.WriteLine(@"CodeConditionStatement {0} = new CodeConditionStatement();", name);

                w.WriteLine(@"{0}.Condition = {1};", name, GenerateCodeExpression(null, stmt.Condition, w, o));

                GenerateCodeStatements(string.Format(@"{0}.TrueStatements", name), stmt.TrueStatements, w, o);
                GenerateCodeStatements(string.Format(@"{0}.FalseStatements", name), stmt.FalseStatements, w, o);

                GenerateCodeDirectives(string.Format(@"{0}.StartDirectives", name), stmt.StartDirectives, w, o);
                GenerateCodeDirectives(string.Format(@"{0}.EndDirectives", name), stmt.EndDirectives, w, o);

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }
            
            if (e is CodeTryCatchFinallyStatement) 
            {
                System.CodeDom.CodeTryCatchFinallyStatement stmt = (System.CodeDom.CodeTryCatchFinallyStatement)e;

                string name = GetNextVar("try");

                w.WriteLine(@"CodeTryCatchFinallyStatement {0} = new CodeTryCatchFinallyStatement();", name);

                GenerateCodeStatements(string.Format(@"{0}.TryStatements", name), stmt.TryStatements, w, o);
                GenerateCodeCatchClauses(string.Format(@"{0}.CatchClauses", name), stmt.CatchClauses, w, o);
                GenerateCodeStatements(string.Format(@"{0}.FinallyStatements", name), stmt.FinallyStatements, w, o);

                GenerateCodeDirectives(string.Format(@"{0}.StartDirectives", name), stmt.StartDirectives, w, o);
                GenerateCodeDirectives(string.Format(@"{0}.EndDirectives", name), stmt.EndDirectives, w, o);

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodeAssignStatement) 
            {
                System.CodeDom.CodeAssignStatement stmt = (System.CodeDom.CodeAssignStatement)e;

                string name = GetNextVar("assign");

                w.WriteLine(@"CodeAssignStatement {0} = new CodeAssignStatement();", name);

                if (stmt.Left != null)
                {
                    w.WriteLine(@"{0}.Left = {1};", name, GenerateCodeExpression(null, stmt.Left, w, o));
                }

                if (stmt.Right != null)
                {
                    w.WriteLine(@"{0}.Right = {1};", name, GenerateCodeExpression(null, stmt.Right, w, o));
                }

                GenerateCodeDirectives(string.Format(@"{0}.StartDirectives", name), stmt.StartDirectives, w, o);
                GenerateCodeDirectives(string.Format(@"{0}.EndDirectives", name), stmt.EndDirectives, w, o);

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodeExpressionStatement) 
            {
                System.CodeDom.CodeExpressionStatement stmt = (System.CodeDom.CodeExpressionStatement)e;

                string name = GetNextVar("expr");

                w.WriteLine(@"CodeExpressionStatement {0} = new CodeExpressionStatement();", name);

                if (stmt.Expression != null)
                {
                    w.WriteLine(@"{0}.Expression = {1};", name, GenerateCodeExpression(null, stmt.Expression, w, o));
                }

                GenerateCodeDirectives(string.Format(@"{0}.StartDirectives", name), stmt.StartDirectives, w, o);
                GenerateCodeDirectives(string.Format(@"{0}.EndDirectives", name), stmt.EndDirectives, w, o);

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodeIterationStatement) 
            {
                System.CodeDom.CodeIterationStatement stmt = (System.CodeDom.CodeIterationStatement)e;

                string name = GetNextVar("for");

                w.WriteLine(@"CodeIterationStatement {0} = new CodeIterationStatement();", name);

                if (stmt.InitStatement != null)
                {
                    w.WriteLine(@"{0}.InitStatement = {1};", name, GenerateCodeStatement(null, stmt.InitStatement, w, o));
                }

                if (stmt.TestExpression != null)
                {
                    w.WriteLine(@"{0}.TestExpression = {1};", name, GenerateCodeExpression(null, stmt.TestExpression, w, o));
                }

                if (stmt.IncrementStatement != null)
                {
                    w.WriteLine(@"{0}.IncrementStatement = {1};", name, GenerateCodeStatement(null, stmt.IncrementStatement, w, o));
                }

                GenerateCodeStatements(string.Format(@"{0}.Statements", name), stmt.Statements, w, o);

                GenerateCodeDirectives(string.Format(@"{0}.StartDirectives", name), stmt.StartDirectives, w, o);
                GenerateCodeDirectives(string.Format(@"{0}.EndDirectives", name), stmt.EndDirectives, w, o);

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }
            
            if (e is CodeThrowExceptionStatement) 
            {
                System.CodeDom.CodeThrowExceptionStatement stmt = (System.CodeDom.CodeThrowExceptionStatement)e;

                string name = GetNextVar("throw");

                w.WriteLine(@"CodeThrowExceptionStatement {0} = new CodeThrowExceptionStatement();", name);

                if (stmt.ToThrow != null)
                {
                    w.WriteLine(@"{0}.ToThrow = {1};", name, GenerateCodeExpression(null, stmt.ToThrow, w, o));
                }

                GenerateCodeDirectives(string.Format(@"{0}.StartDirectives", name), stmt.StartDirectives, w, o);
                GenerateCodeDirectives(string.Format(@"{0}.EndDirectives", name), stmt.EndDirectives, w, o);

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodeSnippetStatement) 
            {
                System.CodeDom.CodeSnippetStatement stmt = (System.CodeDom.CodeSnippetStatement)e;

                string name = GetNextVar("snippet");

                w.WriteLine(@"CodeSnippetStatement {0} = new CodeSnippetStatement();", name);

                if (stmt.Value != null)
                {
                    w.WriteLine(@"{0}.Value = ""{1}"";", name, stmt.Value);
                }

                GenerateCodeDirectives(string.Format(@"{0}.StartDirectives", name), stmt.StartDirectives, w, o);
                GenerateCodeDirectives(string.Format(@"{0}.EndDirectives", name), stmt.EndDirectives, w, o);

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodeVariableDeclarationStatement) 
            {
                System.CodeDom.CodeVariableDeclarationStatement stmt = (System.CodeDom.CodeVariableDeclarationStatement)e;

                string name = GetNextVar("decl");

                w.WriteLine(@"CodeVariableDeclarationStatement {0} = new CodeVariableDeclarationStatement();", name);

                if (stmt.InitExpression != null)
                {
                    w.WriteLine(@"{0}.InitExpression = {1};", name, GenerateCodeExpression(null, stmt.InitExpression, w, o));
                }

                w.WriteLine(@"{0}.Name = ""{1}"";", name, stmt.Name);

                if (stmt.Type != null)
                {
                    w.WriteLine(@"{0}.Type = {1};", name, GenerateCodeTypeReference(null, stmt.Type, w, o));
                }

                GenerateCodeDirectives(string.Format(@"{0}.StartDirectives", name), stmt.StartDirectives, w, o);
                GenerateCodeDirectives(string.Format(@"{0}.EndDirectives", name), stmt.EndDirectives, w, o);

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodeAttachEventStatement) 
            {
                System.CodeDom.CodeAttachEventStatement stmt = (System.CodeDom.CodeAttachEventStatement)e;

                string name = GetNextVar("addevent");

                w.WriteLine(@"CodeAttachEventStatement {0} = new CodeAttachEventStatement();", name);

                if (stmt.Event != null)
                {
                    w.WriteLine(@"{0}.Event = {1};", name, GenerateCodeEventReferenceExpression(null, stmt.Event, w, o));
                }

                if (stmt.Listener != null)
                {
                    w.WriteLine(@"{0}.Listener = {1};", name, GenerateCodeExpression(null, stmt.Listener, w, o));
                }

                GenerateCodeDirectives(string.Format(@"{0}.StartDirectives", name), stmt.StartDirectives, w, o);
                GenerateCodeDirectives(string.Format(@"{0}.EndDirectives", name), stmt.EndDirectives, w, o);

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodeRemoveEventStatement) 
            {
                System.CodeDom.CodeRemoveEventStatement stmt = (System.CodeDom.CodeRemoveEventStatement)e;

                string name = GetNextVar("removeevent");

                w.WriteLine(@"CodeRemoveEventStatement {0} = new CodeRemoveEventStatement();", name);

                if (stmt.Event != null)
                {
                    w.WriteLine(@"{0}.Event = {1};", name, GenerateCodeEventReferenceExpression(null, stmt.Event, w, o));
                }

                if (stmt.Listener != null)
                {
                    w.WriteLine(@"{0}.Listener = {1};", name, GenerateCodeExpression(null, stmt.Listener, w, o));
                }

                GenerateCodeDirectives(string.Format(@"{0}.StartDirectives", name), stmt.StartDirectives, w, o);
                GenerateCodeDirectives(string.Format(@"{0}.EndDirectives", name), stmt.EndDirectives, w, o);

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (e is CodeGotoStatement) 
            {
                System.CodeDom.CodeGotoStatement stmt = (System.CodeDom.CodeGotoStatement)e;

                string name = GetNextVar("goto");

                w.WriteLine(@"CodeGotoStatement {0} = new CodeGotoStatement();", name);

                if (stmt.Label != null)
                {
                    w.WriteLine(@"{0}.Label = ""{1}"";", name, stmt.Label);
                }

                GenerateCodeDirectives(string.Format(@"{0}.StartDirectives", name), stmt.StartDirectives, w, o);
                GenerateCodeDirectives(string.Format(@"{0}.EndDirectives", name), stmt.EndDirectives, w, o);

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }
            
            if (e is CodeLabeledStatement) 
            {
                System.CodeDom.CodeLabeledStatement stmt = (System.CodeDom.CodeLabeledStatement)e;

                string name = GetNextVar("label");

                w.WriteLine(@"CodeLabeledStatement {0} = new CodeLabeledStatement();", name);

                if (stmt.Label != null)
                {
                    w.WriteLine(@"{0}.Label = ""{1}"";", name, stmt.Label);
                }

                if (stmt.Statement != null)
                {
                    w.WriteLine(@"{0}.Statement = {1};", name, GenerateCodeStatement(null, stmt.Statement, w, o));
                }

                GenerateCodeDirectives(string.Format(@"{0}.StartDirectives", name), stmt.StartDirectives, w, o);
                GenerateCodeDirectives(string.Format(@"{0}.EndDirectives", name), stmt.EndDirectives, w, o);

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }
 
            Debug.Fail(string.Format("Generator for CodeStatement {0} Not Implemented", e.GetType().Name));

            return null;
        }

        void GenerateCodeStatements(string context, CodeStatementCollection stmts, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            if (stmts.Count > 0)
            {
                foreach (CodeStatement stmt in stmts)
                {
                    GenerateCodeStatement(context, stmt, w, o);
                }
            }
        }

        string GenerateCodeTypeDeclaration(string context, CodeTypeDeclaration decl, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            if (o.BlankLinesBetweenMembers)
            {
                w.WriteLine();
            }

            w.WriteLine(@"//");

            string decltype = string.Empty;

            if (decl.IsClass)
            {
                decltype = "class";
            }
            else if (decl.IsEnum)
            {
                decltype = "enum";
            }
            else if (decl.IsInterface)
            {
                decltype = "interface";
            }
            else if (decl.IsStruct)
            {
                decltype = "struct";
            }

            w.WriteLine(@"//");
            w.WriteLine(@"// {0} {1}", decltype, decl.Name);
            w.WriteLine(@"//");

            string name = GetNextVar(decl.Name + "_" + decltype);

            w.WriteLine(@"CodeTypeDeclaration {0} = new CodeTypeDeclaration(""{1}"");", name, decl.Name);
            
            w.WriteLine(@"{0}.Attributes = {1};", name, GetMemberAttributes(decl.Attributes));

            if (decl.IsClass)
            {
                w.WriteLine(@"{0}.IsClass = true;", name);
            }
            else if (decl.IsEnum)
            {
                w.WriteLine(@"{0}.IsEnum = true;", name);
            }
            else if (decl.IsInterface)
            {
                w.WriteLine(@"{0}.IsInterface = true;", name);
            }
            else if (decl.IsStruct)
            {
                w.WriteLine(@"{0}.IsStruct = true;", name);
            }
            
            GenerateCodeAttributeDeclarations(string.Format(@"{0}.CustomAttributes", name), decl.CustomAttributes, w, o); 
            
            GenerateCodeTypeReferences(string.Format(@"{0}.BaseTypes", name), decl.BaseTypes, w, o); 
            
            GenerateCodeComments(string.Format(@"{0}.Comments", name), decl.Comments, w, o);

            GenerateCodeTypeMembers(string.Format(@"{0}.Members", name), decl.Members, w, o);

            if (context != null && context.Length > 0)
            {
                w.WriteLine(@"{0}.Add({1});", context, name);
                w.WriteLine();
            }

            return name;
        }

        void GenerateCodeTypeDeclarations(string context, CodeTypeDeclarationCollection types, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            if (types.Count > 0)
            {
                foreach (CodeTypeDeclaration decl in types)
                {
                    GenerateCodeTypeDeclaration(context, decl, w, o);
                }
            }
        }

        string GenerateCodeTypeMember(string context, CodeTypeMember m, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            if (o.BlankLinesBetweenMembers)
            {
                w.WriteLine();
            }


            if (m is CodeConstructor)
            {
                CodeConstructor member = (CodeConstructor)m;

                string name = GetNextVar(member.Name + "_ctor");

                // parameter list
                string parameters = string.Empty;
                foreach (CodeParameterDeclarationExpression param in member.Parameters)
                {
                    if (parameters.Length > 0)
                    {
                        parameters += ", ";
                    }
                    parameters += param.Type.BaseType + " " + param.Name;
                }

                w.WriteLine(@"//");
                w.WriteLine(@"// Constructor({0})", parameters);
                w.WriteLine(@"//");

                w.WriteLine(@"CodeConstructor {0} = new CodeConstructor();", name);

                w.WriteLine(@"{0}.Attributes = {1};", name, this.GetMemberAttributes(member.Attributes));

                GenerateCodeExpressions(string.Format(@"{0}.BaseConstructorArgs", name), member.BaseConstructorArgs, w, o);

                GenerateCodeExpressions(string.Format(@"{0}.ChainedConstructorArgs", name), member.ChainedConstructorArgs, w, o);

                GenerateCodeComments(string.Format(@"{0}.Comments", name), member.Comments, w, o);

                GenerateCodeAttributeDeclarations(string.Format(@"{0}.CustomAttributes", name), member.CustomAttributes, w, o);

                GenerateCodeTypeReferences(string.Format(@"{0}.ImplementationTypes", name), member.ImplementationTypes, w, o);

                // w.WriteLine(@"{0}.Name = ""{1}"";", name, member.Name);

                GenerateCodeParameterDeclarationExpressions(string.Format(@"{0}.Parameters", name), member.Parameters, w, o);

                if (member.PrivateImplementationType != null)
                {
                    w.WriteLine(@"{0}.PrivateImplementationType = {1};", name, GenerateCodeTypeReference(null, member.PrivateImplementationType, w, o));
                }

                if (member.ReturnType != null && member.ReturnType.BaseType != "System.Void")
                {
                    string retname = GenerateCodeTypeReference(null, member.ReturnType, w, o);
                    w.WriteLine(@"{0}.ReturnType = {1};", name, retname);
                }

                GenerateCodeAttributeDeclarations(string.Format(@"{0}.ReturnTypeCustomAttributes", name), member.ReturnTypeCustomAttributes, w, o);

                GenerateCodeStatements(string.Format(@"{0}.Statements", name), member.Statements, w, o);

                GenerateCodeDirectives(string.Format(@"{0}.StartDirectives", name), member.StartDirectives, w, o);
                GenerateCodeDirectives(string.Format(@"{0}.EndDirectives", name), member.EndDirectives, w, o);

                GenerateCodeTypeParameters(string.Format(@"{0}.TypeParameters", name), member.TypeParameters, w, o);

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (m is CodeMemberField)
            {
                CodeMemberField member = (CodeMemberField)m;

                string name = GetNextVar(member.Name + "_field");

                w.WriteLine(@"//");
                w.WriteLine(@"// Field {0}", member.Name);
                w.WriteLine(@"//");

                w.WriteLine(@"CodeMemberField {0} = new CodeMemberField();", name);

                w.WriteLine(@"{0}.Attributes = {1};", name, this.GetMemberAttributes(member.Attributes));

                GenerateCodeComments(string.Format(@"{0}.Comments", name), member.Comments, w, o);

                GenerateCodeAttributeDeclarations(string.Format(@"{0}.CustomAttributes", name), member.CustomAttributes, w, o);

                if (member.InitExpression != null)
                {
                    string init = this.GenerateCodeExpression(null, member.InitExpression, w, o);
                    w.WriteLine(@"{0}.InitExpression = {1};", name, init);
                }

                w.WriteLine(@"{0}.Name = ""{1}"";", name, member.Name);

                if (member.Type != null)
                {
                    string type = this.GenerateCodeTypeReference(null, member.Type, w, o);
                    w.WriteLine(@"{0}.Type = {1};", name, type);
                }

                GenerateCodeDirectives(string.Format(@"{0}.StartDirectives", name), member.StartDirectives, w, o);
                GenerateCodeDirectives(string.Format(@"{0}.EndDirectives", name), member.EndDirectives, w, o);

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (m is CodeMemberEvent)
            {
                CodeMemberEvent member = (CodeMemberEvent)m;

                string name = GetNextVar(member.Name + "_event");

                w.WriteLine(@"//");
                w.WriteLine(@"// Event {0}", member.Name);
                w.WriteLine(@"//");

                w.WriteLine(@"CodeMemberEvent {0} = new CodeMemberEvent();", name);

                w.WriteLine(@"{0}.Attributes = {1};", name, this.GetMemberAttributes(member.Attributes));

                GenerateCodeComments(string.Format(@"{0}.Comments", name), member.Comments, w, o);
              
                GenerateCodeAttributeDeclarations(string.Format(@"{0}.CustomAttributes", name), member.CustomAttributes, w, o);

                w.WriteLine(@"{0}.Name = ""{1}"";", name, member.Name);

                if (member.Type != null)
                {
                    w.WriteLine(@"{0}.Type = {1};", name, GenerateCodeTypeReference(null, member.Type, w, o));
                }

                GenerateCodeTypeReferences(string.Format(@"{0}.ImplementationTypes", name), member.ImplementationTypes, w, o);

                if (member.PrivateImplementationType != null)
                {
                    w.WriteLine(@"{0}.PrivateImplementationType = {1};", name, GenerateCodeTypeReference(null, member.PrivateImplementationType, w, o));
                }

                GenerateCodeDirectives(string.Format(@"{0}.StartDirectives", name), member.StartDirectives, w, o);
                GenerateCodeDirectives(string.Format(@"{0}.EndDirectives", name), member.EndDirectives, w, o);

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (m is CodeMemberProperty)
            {
                CodeMemberProperty member = (CodeMemberProperty)m;

                string name = GetNextVar(member.Name + "_property");

                // parameter list
                string parameters = string.Empty;
                foreach (CodeParameterDeclarationExpression param in member.Parameters)
                {
                    if (parameters.Length > 0)
                    {
                        parameters += ", ";
                    }
                    parameters += param.Type.BaseType + " " + param.Name;
                }

                w.WriteLine(@"//");

                if (parameters.Length == 0)
                    w.WriteLine(@"// Property {0}", member.Name);
                else
                    w.WriteLine(@"// Property {0}[{1}]", member.Name, parameters);

                w.WriteLine(@"//");

                w.WriteLine(@"CodeMemberProperty {0} = new CodeMemberProperty();", name);

                w.WriteLine(@"{0}.Attributes = {1};", name, this.GetMemberAttributes(member.Attributes));

                GenerateCodeComments(string.Format(@"{0}.Comments", name), member.Comments, w, o);

                GenerateCodeAttributeDeclarations(string.Format(@"{0}.CustomAttributes", name), member.CustomAttributes, w, o);

                w.WriteLine(@"{0}.Name = ""{1}"";", name, member.Name);

                w.WriteLine(@"{0}.Type = {1};", name, this.GenerateCodeTypeReference(null, member.Type, w, o));

                GenerateCodeParameterDeclarationExpressions(string.Format(@"{0}.Parameters", name), member.Parameters, w, o);

                w.WriteLine(@"{0}.HasGet = {1};", name, member.HasGet.ToString().ToLower());

                if (member.HasGet)
                {
                    GenerateCodeStatements(string.Format(@"{0}.GetStatements", name), member.GetStatements, w, o);
                }

                w.WriteLine(@"{0}.HasSet = {1};", name, member.HasSet.ToString().ToLower());
                
                if (member.HasSet)
                {
                    GenerateCodeStatements(string.Format(@"{0}.SetStatements", name), member.SetStatements, w, o);
                }

                GenerateCodeTypeReferences(string.Format(@"{0}.ImplementationTypes", name), member.ImplementationTypes, w, o);

                if (member.PrivateImplementationType != null)
                {
                    w.WriteLine(@"{0}.PrivateImplementationType = {1};", name, GenerateCodeTypeReference(null, member.PrivateImplementationType, w, o));
                }

                GenerateCodeDirectives(string.Format(@"{0}.StartDirectives", name), member.StartDirectives, w, o);
                GenerateCodeDirectives(string.Format(@"{0}.EndDirectives", name), member.EndDirectives, w, o);

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;

            }

            if (m is CodeMemberMethod)
            {
                CodeMemberMethod member = (CodeMemberMethod)m;

                string name = GetNextVar(member.Name + "_method");

                // parameter list
                string parameters = string.Empty;
                foreach (CodeParameterDeclarationExpression param in member.Parameters)
                {
                    if (parameters.Length > 0)
                    {
                        parameters += ", ";
                    }
                    parameters += param.Type.BaseType + " " + param.Name;
                }

                w.WriteLine(@"//");
                w.WriteLine(@"// Function {0}({1})", member.Name, parameters);
                w.WriteLine(@"//");

                w.WriteLine(@"CodeMemberMethod {0} = new CodeMemberMethod();", name);

                w.WriteLine(@"{0}.Attributes = {1};", name, this.GetMemberAttributes(member.Attributes));

                GenerateCodeComments(string.Format(@"{0}.Comments", name), member.Comments, w, o);

                GenerateCodeAttributeDeclarations(string.Format(@"{0}.CustomAttributes", name), member.CustomAttributes, w, o);

                w.WriteLine(@"{0}.Name = ""{1}"";", name, member.Name);

                GenerateCodeParameterDeclarationExpressions(string.Format(@"{0}.Parameters", name), member.Parameters, w, o);

                if (member.ReturnType != null && member.ReturnType.BaseType != "System.Void")
                {
                    string retname = GenerateCodeTypeReference(null, member.ReturnType, w, o);
                    w.WriteLine(@"{0}.ReturnType = {1};", name, retname);
                }

                GenerateCodeTypeParameters(string.Format(@"{0}.TypeParameters", name), member.TypeParameters, w, o);

                GenerateCodeAttributeDeclarations(string.Format(@"{0}.ReturnTypeCustomAttributes", name), member.ReturnTypeCustomAttributes, w, o);

                GenerateCodeStatements(string.Format(@"{0}.Statements", name), member.Statements, w, o);

                GenerateCodeTypeReferences(string.Format(@"{0}.ImplementationTypes", name), member.ImplementationTypes, w, o);

                if (member.PrivateImplementationType != null)
                {
                    w.WriteLine(@"{0}.PrivateImplementationType = {1};", name, GenerateCodeTypeReference(null, member.PrivateImplementationType, w, o));
                }

                GenerateCodeDirectives(string.Format(@"{0}.StartDirectives", name), member.StartDirectives, w, o);
                GenerateCodeDirectives(string.Format(@"{0}.EndDirectives", name), member.EndDirectives, w, o);

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            if (m is CodeTypeDelegate)
            {
                CodeTypeDelegate member = (CodeTypeDelegate)m;

                string name = GetNextVar(member.Name + "_delegate");

                // parameter list
                string parameters = string.Empty;
                foreach (CodeParameterDeclarationExpression param in member.Parameters)
                {
                    if (parameters.Length > 0)
                    {
                        parameters += ", ";
                    }
                    parameters += param.Type.BaseType + " " + param.Name;
                }

                w.WriteLine(@"//");
                w.WriteLine(@"// Delegate {0}({1})", member.Name, parameters);
                w.WriteLine(@"//");
                
                w.WriteLine(@"CodeTypeDelegate {0} = new CodeTypeDelegate();", name);

                w.WriteLine(@"{0}.Attributes = {1};", name, this.GetMemberAttributes(member.Attributes));

                GenerateCodeTypeReferences(string.Format(@"{0}.BaseTypes", name), member.BaseTypes, w, o); 

                GenerateCodeComments(string.Format(@"{0}.Comments", name), member.Comments, w, o);

                GenerateCodeAttributeDeclarations(string.Format(@"{0}.CustomAttributes", name), member.CustomAttributes, w, o);

                w.WriteLine(@"{0}.Name = ""{1}"";", name, member.Name);

                if (member.IsClass)
                {
                    w.WriteLine(@"{0}.IsClass = true;", name);
                }

                if (member.IsEnum)
                {
                    w.WriteLine(@"{0}.IsEnum = true;", name);
                }

                if (member.IsInterface)
                {
                    w.WriteLine(@"{0}.IsInterface = true;", name);
                }

                if (member.IsPartial)
                {
                    w.WriteLine(@"{0}.IsPartial = true;", name);
                }

                if (member.IsStruct)
                {
                    w.WriteLine(@"{0}.IsStruct = true;", name);
                }

                GenerateCodeTypeMembers(string.Format(@"{0}.Members", name), member.Members, w, o);

                GenerateCodeParameterDeclarationExpressions(string.Format(@"{0}.Parameters", name), member.Parameters, w, o);

                if (member.ReturnType != null && member.ReturnType.BaseType != "System.Void")
                {
                    string retname = GenerateCodeTypeReference(null, member.ReturnType, w, o);
                    w.WriteLine(@"{0}.ReturnType = {1};", name, retname);
                }

                w.WriteLine(@"{0}.TypeAttributes = {1};", name, GetTypeAttributes(member.TypeAttributes));

                GenerateCodeTypeParameters(string.Format(@"{0}.TypeParameters", name), member.TypeParameters, w, o);

                GenerateCodeDirectives(string.Format(@"{0}.StartDirectives", name), member.StartDirectives, w, o);
                GenerateCodeDirectives(string.Format(@"{0}.EndDirectives", name), member.EndDirectives, w, o);

                if (context != null && context.Length > 0)
                {
                    w.WriteLine(@"{0}.Add({1});", context, name);
                    w.WriteLine();
                }

                return name;
            }

            Debug.Fail(string.Format("Generator for CodeTypeMember {0} Not Implemented", m.GetType().Name));

            return null;
        }

        void GenerateCodeTypeMembers(string context, CodeTypeMemberCollection members, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            if (members.Count > 0)
            {
                foreach (CodeTypeMember member in members)
                {
                    GenerateCodeTypeMember(context, member, w, o);
                }
            }
        }

        string GenerateCodeTypeParameter(string context, CodeTypeParameter param, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            string name = GetNextVar(param.Name + "_param");

            w.WriteLine(@"CodeTypeParameter {0} = new CodeTypeParameter();", name);

            GenerateCodeTypeReferences(string.Format(@"{0}.Constraints", context), param.Constraints, w, o); 

            GenerateCodeAttributeDeclarations(string.Format(@"{0}.CustomAttributes", name), param.CustomAttributes, w, o);

            w.WriteLine(@"{0}.HasConstructorConstraint = {1};", name, param.HasConstructorConstraint.ToString().ToLower());

            w.WriteLine(@"{0}.Name = ""{1}"";", name, param.Name);

            if (context != null && context.Length > 0)
            {
                w.WriteLine(@"{0}.Add({1});", context, name);
                w.WriteLine();
            }

            return name;
        }

        void GenerateCodeTypeParameters(string context, CodeTypeParameterCollection @params, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            if (@params.Count > 0)
            {
                foreach (CodeTypeParameter param in @params)
                {
                    GenerateCodeTypeParameter(context, param, w, o);
                }
            }
        }

        string GenerateCodeTypeReference(string context, CodeTypeReference typeref, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            string name = GetNextVar(typeref.BaseType + "_type");

            CodeTypeReference elementType = typeref.ArrayElementType;
            if (elementType == null)
            {
                w.WriteLine(@"CodeTypeReference {0} = new CodeTypeReference(""{1}"");", name, typeref.BaseType);
            }
            else
            {
                w.WriteLine(@"CodeTypeReference {0} = new CodeTypeReference(""{1}"", {2});", name, typeref.BaseType, typeref.ArrayRank);

                GenerateCodeTypeReference(string.Format(@"{0}.ArrayElementType", context), typeref.ArrayElementType, w, o); 
            }

            if (context != null && context.Length > 0)
            {
                w.WriteLine(@"{0}.Add({1});", context, name);
                w.WriteLine();
            }

            return name;
        }

        void GenerateCodeTypeReferences(string context, CodeTypeReferenceCollection typerefs, System.IO.TextWriter w, System.CodeDom.Compiler.CodeGeneratorOptions o)
        {
            if (typerefs.Count > 0)
            {
                foreach (CodeTypeReference typeref in typerefs)
                {
                    GenerateCodeTypeReference(context, typeref, w, o);
                }
            }
        }

        string GetMemberAttributes(MemberAttributes attributes)
        {
            string val = string.Empty;
            System.CodeDom.MemberAttributes[] attrs = (System.CodeDom.MemberAttributes[])Enum.GetValues(typeof(System.CodeDom.MemberAttributes));
            foreach (System.CodeDom.MemberAttributes attr in attrs)
            {
                if ((attr & attributes) == attr)
                {
                    if (val.Length != 0)
                        val += "|";
                    val += "MemberAttributes." + attr.ToString();
                }
            }

            if (val.Length == 0)
            {
                val = "MemberAttributes.Private";
            }

            return val;
        }

        string GetTypeAttributes(System.Reflection.TypeAttributes attributes)
        {
            string val = string.Empty;
            System.Reflection.TypeAttributes[] attrs = (System.Reflection.TypeAttributes[])Enum.GetValues(typeof(System.Reflection.TypeAttributes));
            foreach (System.Reflection.TypeAttributes attr in attrs)
            {
                if ((attr & attributes) == attr)
                {
                    if (val.Length != 0)
                        val += "|";
                    val += "System.Reflection.TypeAttributes." + attr.ToString();
                }
            }

            if (val.Length == 0)
            {
                val = "System.Reflection.TypeAttributes.Private";
            }

            return val;
        }

        string GetFieldDirection(FieldDirection attributes)
        {
            string val = string.Empty;
            System.CodeDom.FieldDirection[] attrs = (System.CodeDom.FieldDirection[])Enum.GetValues(typeof(System.CodeDom.FieldDirection));
            foreach (System.CodeDom.FieldDirection attr in attrs)
            {
                if ((attr & attributes) == attr)
                {
                    if (val.Length != 0)
                        val += "|";
                    val += "FieldDirection." + attr.ToString();
                }
            }

            if (val.Length == 0)
            {
                val = "FieldDirection.In";
            }

            return val;
        }

        string GetCodeRegionMode(CodeRegionMode attributes)
        {
            string val = string.Empty;
            System.CodeDom.CodeRegionMode[] attrs = (System.CodeDom.CodeRegionMode[])Enum.GetValues(typeof(System.CodeDom.CodeRegionMode));
            foreach (System.CodeDom.CodeRegionMode attr in attrs)
            {
                if ((attr & attributes) == attr)
                {
                    if (val.Length != 0)
                        val += "|";
                    val += "CodeRegionMode." + attr.ToString();
                }
            }

            if (val.Length == 0)
            {
                return "CodeRegionMode.None";
            }

            return val;
        }

        string GetCodeBinaryOperatorType(CodeBinaryOperatorType op)
        {
            return "CodeBinaryOperatorType." + op.ToString();
        }

        string Escape(string value)
        {
            return value;
        }

        string GetByteData(byte[] data)
        {
            if (data == null)
            {
                return "null";
            }

            string expr = "new byte[] { ";
            for (int i = 0; i < data.Length; i++)
            {
                if (i > 0)
                {
                    expr += ", ";
                }

                expr += "0x" + data[i].ToString("X2") ;
            }

            expr += " }";

            return expr;
        }
    }

    /// <summary>
    /// Output Option
    /// </summary>
    public class OutputClass
    {
        string name = string.Empty;
        AbstractAstTransformer transformer = null;
        IOutputAstVisitor prettyprinter = null;
        bool cantestcodedom = false;

        System.CodeDom.Compiler.CodeDomProvider codedomprovider = null;
        int savefilterindex = 0;

        public OutputClass()
        {
        }

        public OutputClass(string name, AbstractAstTransformer visitor, IOutputAstVisitor prettyprinter, int savefilterindex)
        {
            this.name = name;
            this.transformer = visitor;
            this.prettyprinter = prettyprinter;
            this.savefilterindex = savefilterindex;
        }

        public OutputClass(string name, System.CodeDom.Compiler.CodeDomProvider codedomprovider, int savefilterindex)
        {
            this.name = name;
            this.codedomprovider = codedomprovider;
            this.savefilterindex = savefilterindex;
        }

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        public AbstractAstTransformer CreateTransformer()
        {
            if (transformer == null)
            {
                return null;
            }

            return (AbstractAstTransformer)transformer.GetType().Assembly.CreateInstance(transformer.GetType().FullName);
        }

        public IOutputAstVisitor CreatePrettyPrinter()
        {
            if (prettyprinter == null)
            {
                return null;
            }

            return (IOutputAstVisitor)prettyprinter.GetType().Assembly.CreateInstance(prettyprinter.GetType().FullName);
        }


        public System.CodeDom.Compiler.CodeDomProvider CodeDomProvider
        {
            get { return codedomprovider; }
            set { codedomprovider = value; }
        }

        public int SaveFilterIndex
        {
            get { return savefilterindex; }
            set { savefilterindex = value; }
        }

        public bool CanTestCodeDom
        {
            get { return cantestcodedom; }
            set { cantestcodedom = value; }
        }

        public override string ToString()
        {
            return name;
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Australia Australia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions