using System; using System.CodeDom; using System.Collections; namespace nGineer { public class CodeDOMGenerator { #region [ Seed ] private static long m_Seed = 0L; private static long Seed { get { return m_Seed++; } } #endregion #region [ Common Constants ] private const string CreateDomMethodName = "CreateDom"; private const string NameSpaceName = "GeneratedCode"; private const string NamePropertyName = "Name"; private const string ValuePropertyName = "Value"; private const string CommentsPropertyName = "Comments"; private const string AttributesPropertyName = "Attributes"; private const string CustomAttributesPropertyName = "CustomAttributes"; private const string LinePragmaPropertyName = "LinePragma"; private const string MembersPropertyName = "Members"; private const string ReturnTypePropertyName = "ReturnType"; private const string ParametersPropertyName = "Parameters"; #endregion #region [ Type State Machine ] private static CodeExpression CreateDom(CodeTypeDeclaration parentDeclaration, object o) { if (o is string) { return CreatePrimitive(((string)(o))); } else if (o is CodeNamespace) { return CreateDom(parentDeclaration, ((CodeNamespace)(o))); } else if (o is CodeAttributeDeclaration) { return CreateDom(parentDeclaration, ((CodeAttributeDeclaration)(o))); } else if (o is CodeAttributeArgument) { return CreateDom(parentDeclaration, ((CodeAttributeArgument)(o))); } else if (o is CodeExpression) { return CreateDom(parentDeclaration, ((CodeExpression)(o))); } else if (o is CodeStatement) { return CreateDom(parentDeclaration, ((CodeStatement)(o))); } else if (o is CodeNamespaceImport) { return CreateDom(((CodeNamespaceImport)(o))); } else if (o is CodeTypeDeclaration) { return CreateDom(parentDeclaration, ((CodeTypeDeclaration)(o))); } else if (o is CodeTypeReference) { return CreateDom(((CodeTypeReference)(o))); } else if (o is CodeMemberEvent) { return CreateDom(parentDeclaration, ((CodeMemberEvent)(o))); } else if (o is CodeMemberField) { return CreateDom(parentDeclaration, ((CodeMemberField)(o))); } else if (o is CodeConstructor) { return CreateDom(parentDeclaration, ((CodeConstructor)(o))); } else if (o is CodeEntryPointMethod) { return CreateDom(parentDeclaration, ((CodeEntryPointMethod)(o))); } else if (o is CodeTypeConstructor) { return CreateDom(parentDeclaration, ((CodeTypeConstructor)(o))); } else if (o is CodeMemberMethod) { return CreateDom(parentDeclaration, ((CodeMemberMethod)(o))); } else if (o is CodeMemberProperty) { return CreateDom(parentDeclaration, ((CodeMemberProperty)(o))); } else if (o is CodeSnippetTypeMember) { return CreateDom(((CodeSnippetTypeMember)(o))); } else if (o is CodeTypeDelegate) { return CreateDom(parentDeclaration, ((CodeTypeDelegate)(o))); } else if (o is CodeTypeDeclaration) { return CreateDom(parentDeclaration, ((CodeTypeDeclaration)(o))); } else if (o is CodeCatchClause) { if (((CodeCatchClause)(o)).Statements.Count > 0) { CodeExpression[] statementsExpressionCreates = new CodeExpression[((CodeCatchClause)(o)).Statements.Count]; for (int i = 0; i < ((CodeCatchClause)(o)).Statements.Count; i++) { statementsExpressionCreates[i] = CreateDom(parentDeclaration, ((CodeCatchClause)(o)).Statements[i]); } return new CodeObjectCreateExpression(typeof(CodeCatchClause), new CodePrimitiveExpression(((CodeCatchClause)(o)).LocalName), CreateDom(parentDeclaration, ((CodeCatchClause)(o)).CatchExceptionType), new CodeArrayCreateExpression(typeof(CodeStatement), statementsExpressionCreates)); } else { return new CodeObjectCreateExpression(typeof(CodeCatchClause), new CodePrimitiveExpression(((CodeCatchClause)(o)).LocalName), CreateDom(parentDeclaration, ((CodeCatchClause)(o)).CatchExceptionType)); } } throw new NotSupportedException(); } #endregion #region [ CodeCompileUnit ] private const string CompileUnitVariableName = "compileUnit"; private const string CodeCompileUnitTypeName = "CodeCompileUnit"; private const string AssemblyCustomAttributesPropertyName = "AssemblyCustomAttributes"; private const string NameSpacesPropertyName = "Namespaces"; private const string ReferencedAssembliesPropertyName = "ReferencedAssemblies"; public static CodeCompileUnit CreateDom(System.CodeDom.CodeCompileUnit unit) { CodeTypeDeclaration declaration = new CodeTypeDeclaration(CodeCompileUnitTypeName); CodeMemberMethod createDom = CreateDomMethod(); createDom.ReturnType = new CodeTypeReference(typeof(CodeCompileUnit)); // CodeCompileUnit compileUnit = new CodeCompileUnit(); createDom.Statements.Add(CreateDomCreateObjectStatement(CompileUnitVariableName, typeof(CodeCompileUnit))); // AssemblyCustomAttributes if (unit.AssemblyCustomAttributes.Count > 0) { createDom.Statements.Add(CreateAddRangeExpression(CompileUnitVariableName, AssemblyCustomAttributesPropertyName, declaration, unit.AssemblyCustomAttributes, typeof(CodeAttributeDeclaration))); } // Namespaces if (unit.Namespaces.Count > 0) { createDom.Statements.Add(CreateAddRangeExpression(CompileUnitVariableName, NameSpacesPropertyName, declaration, unit.Namespaces, typeof(CodeNamespace))); } // References if (unit.ReferencedAssemblies.Count > 0) { createDom.Statements.Add(new CodeMethodInvokeExpression(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression(CompileUnitVariableName), ReferencedAssembliesPropertyName), CollectionAddRangeMethodName, CreateDom(declaration, unit.ReferencedAssemblies, typeof(string)))); } // return compileUnit; createDom.Statements.Add(CreateReturnStatement(CompileUnitVariableName)); declaration.Members.Add(createDom); CodeNamespace nameSpace = new CodeNamespace(NameSpaceName); Console.WriteLine("Seed: " + Seed); System.CodeDom.CodeCompileUnit ccu = new CodeCompileUnit(); ccu.Namespaces.Add(nameSpace); nameSpace.Types.Add(declaration); return ccu; } #endregion #region [ CodeNamespace ] private const string CodeNamespaceVariableName = "codeNamespace"; private const string ImportsPropertyName = "Imports"; private const string TypesPropertyName = "Types"; private static CodeExpression CreateDom(CodeTypeDeclaration parentDeclaration, CodeNamespace cn) { CodeTypeDeclaration decl = new CodeTypeDeclaration(MakeSafe(cn.Name + "_CodeNamespace")); CodeMemberMethod createDom = CreateDomMethod(); createDom.ReturnType = new CodeTypeReference(typeof(CodeNamespace)); createDom.Statements.Add(CreateDomCreateObjectStatement(CodeNamespaceVariableName, typeof(CodeNamespace))); // Name if (cn.Name != null) { createDom.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(CodeNamespaceVariableName), NamePropertyName), CreatePrimitive(cn.Name))); } // Comments if (cn.Comments.Count > 0) { createDom.Statements.Add(CreateAddRangeExpression(CodeNamespaceVariableName, CommentsPropertyName, decl, cn.Comments, typeof(CodeCommentStatement))); } // Imports if (cn.Imports.Count > 0) { createDom.Statements.Add(CreateAddRangeExpression(CodeNamespaceVariableName, ImportsPropertyName, decl, cn.Imports, typeof(CodeNamespaceImport))); } // Types if (cn.Types.Count > 0) { createDom.Statements.Add(CreateAddRangeExpression(CodeNamespaceVariableName, TypesPropertyName, decl, cn.Types, typeof(CodeTypeDeclaration))); } createDom.Statements.Add(CreateReturnStatement(CodeNamespaceVariableName)); decl.Members.Add(createDom); parentDeclaration.Members.Add(decl); return CreateDeclarationMethodReferenceExpression(decl); } #endregion #region [ CodeTypeMember ] private static CodeStatementCollection CreateCommonCodeTypeMemberProperties(string name, CodeTypeMember ctm, CodeTypeDeclaration decl) { CodeStatementCollection collection = new CodeStatementCollection(); #region Name if (ctm.Name != null) { collection.Add(new CodeAssignStatement(new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(name), NamePropertyName), CreatePrimitive(ctm.Name))); } #endregion #region Comments if (ctm.Comments.Count > 0) { collection.Add(CreateAddRangeExpression(name, CommentsPropertyName, decl, ctm.Comments, typeof(CodeCommentStatement))); } #endregion #region Attributes if (((int)(ctm.Attributes)) != 0) { collection.Add(new CodeAssignStatement(new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(name), AttributesPropertyName), CreateEnum(((int)(ctm.Attributes)), typeof(MemberAttributes)))); } #endregion #region CustomAttributes if (ctm.CustomAttributes.Count > 0) { collection.Add(CreateAddRangeExpression(name, CustomAttributesPropertyName, decl, ctm.CustomAttributes, typeof(CodeAttributeDeclaration))); } #endregion #region LinePragma if (ctm.LinePragma != null) { collection.Add(new CodeAssignStatement(new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(name), LinePragmaPropertyName), CreateDom(ctm.LinePragma))); } #endregion return collection; } #endregion #region [ CodeTypeDelegate ] private const string CodeTypeDelegateVariableName = "codeTypeDelegate"; private static CodeExpression CreateDom(CodeTypeDeclaration parentDeclaration, CodeTypeDelegate ctd) { CodeTypeDeclaration decl = new CodeTypeDeclaration(MakeSafe(ctd.Name + "_CodeTypeDelegate")); CodeMemberMethod createDom = CreateDomMethod(); createDom.ReturnType = new CodeTypeReference(typeof(CodeTypeDelegate)); createDom.Statements.Add(CreateDomCreateObjectStatement(CodeTypeDelegateVariableName, typeof(CodeTypeDelegate))); createDom.Statements.AddRange(CreateCommonCodeTypeDeclarationProperties(CodeTypeDelegateVariableName, ctd, decl)); #region ReturnType if (ctd.ReturnType != null) { createDom.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(CodeTypeDelegateVariableName), ReturnTypePropertyName), CreateDom(ctd.ReturnType))); } #endregion #region Parameters if (ctd.Parameters.Count > 0) { createDom.Statements.AddRange(CreateCodeParameterDeclarationExpressionCollection(new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(CodeTypeDelegateVariableName), ParametersPropertyName), ctd.Parameters)); } #endregion createDom.Statements.Add(CreateReturnStatement(CodeTypeDelegateVariableName)); decl.Members.Add(createDom); parentDeclaration.Members.Add(decl); return CreateDeclarationMethodReferenceExpression(decl); } #endregion #region [ CodeTypeDeclaration ] private const string CodeTypeDeclarationVariableName = "codeTypeDeclaration"; private const string BaseTypesPropertyName = "BaseTypes"; private const string IsClassPropertyName = "IsClass"; private const string IsEnumPropertyName = "IsEnum"; private const string IsStructPropertyName = "IsStruct"; private const string IsInterfacePropertyName = "IsInterface"; private const string TypeAttributesPropertyName = "TypeAttributes"; private static CodeStatementCollection CreateCommonCodeTypeDeclarationProperties(string name, CodeTypeDeclaration ctd, CodeTypeDeclaration decl) { CodeStatementCollection collection = new CodeStatementCollection(); collection.AddRange(CreateCommonCodeTypeMemberProperties(name, ctd, decl)); #region TypeAttributes if (((int)(ctd.TypeAttributes)) != 0) { collection.Add(new CodeAssignStatement(new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(CodeTypeDeclarationVariableName), TypeAttributesPropertyName), CreateEnum(((int)(ctd.TypeAttributes)), typeof(System.Reflection.TypeAttributes)))); } #endregion #region BaseTypes if (ctd.BaseTypes.Count > 0) { collection.Add(CreateAddRangeExpression(CodeTypeDeclarationVariableName, BaseTypesPropertyName, decl, ctd.BaseTypes, typeof(CodeTypeReference))); } #endregion #region IsClass if (ctd.IsClass) { collection.Add(new CodeAssignStatement(new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(CodeTypeDeclarationVariableName), IsClassPropertyName), CreatePrimitive(ctd.IsClass))); } #endregion #region IsEnum if (ctd.IsEnum) { collection.Add(new CodeAssignStatement(new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(CodeTypeDeclarationVariableName), IsEnumPropertyName), CreatePrimitive(ctd.IsEnum))); } #endregion #region IsInterface if (ctd.IsInterface) { collection.Add(new CodeAssignStatement(new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(CodeTypeDeclarationVariableName), IsInterfacePropertyName), CreatePrimitive(ctd.IsInterface))); } #endregion #region IsStruct if (ctd.IsStruct) { collection.Add(new CodeAssignStatement(new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(CodeTypeDeclarationVariableName), IsStructPropertyName), CreatePrimitive(ctd.IsStruct))); } #endregion #region Members if (ctd.Members.Count > 0) { collection.Add(CreateAddRangeExpression(CodeTypeDeclarationVariableName, MembersPropertyName, decl, ctd.Members, typeof(CodeTypeMember))); } #endregion return collection; } private static CodeExpression CreateDom(CodeTypeDeclaration parentDeclaration, CodeTypeDeclaration ctd) { CodeTypeDeclaration decl = new CodeTypeDeclaration(MakeSafe(ctd.Name + "_CodeTypeDeclaration")); CodeMemberMethod createDom = CreateDomMethod(); createDom.ReturnType = new CodeTypeReference(typeof(CodeTypeDeclaration)); createDom.Statements.Add(CreateDomCreateObjectStatement(CodeTypeDeclarationVariableName, typeof(CodeTypeDeclaration))); createDom.Statements.AddRange(CreateCommonCodeTypeDeclarationProperties(CodeTypeDeclarationVariableName, ctd, decl)); createDom.Statements.Add(CreateReturnStatement(CodeTypeDeclarationVariableName)); decl.Members.Add(createDom); parentDeclaration.Members.Add(decl); return CreateDeclarationMethodReferenceExpression(decl); } #endregion #region [ CodeMemberProperty ] private const string CodeMemberPropertyVariableName = "codeMemberProperty"; private const string HasSetPropertyName = "HasSet"; private const string HasGetPropertyName = "HasGet"; private const string GetStatementsPropertyName = "GetStatements"; private const string SetStatementsPropertyName = "SetStatements"; private static CodeExpression CreateDom(CodeTypeDeclaration parentDeclaration, CodeMemberProperty cmp) { CodeTypeDeclaration decl = new CodeTypeDeclaration(MakeSafe(cmp.Name + "_CodeMemberProperty")); CodeMemberMethod createDom = CreateDomMethod(); createDom.ReturnType = new CodeTypeReference(typeof(CodeMemberProperty)); createDom.Statements.Add(CreateDomCreateObjectStatement(CodeMemberPropertyVariableName, typeof(CodeMemberProperty))); createDom.Statements.AddRange(CreateCommonCodeTypeMemberProperties(CodeMemberPropertyVariableName, cmp, decl)); #region ImplementationTypes if (cmp.ImplementationTypes.Count > 0) { createDom.Statements.Add(CreateAddRangeExpression(CodeMemberPropertyVariableName, ImplementationTypesPropertyName, decl, cmp.ImplementationTypes, typeof(CodeTypeReference))); } #endregion #region PrivateImplementationType if (cmp.PrivateImplementationType != null) { createDom.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(CodeMemberPropertyVariableName), PrivateImplementationTypePropertyName), CreateDom(cmp.PrivateImplementationType))); } #endregion #region Type if (cmp.Type != null) { createDom.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(CodeMemberPropertyVariableName), TypePropertyName), CreateDom(cmp.Type))); } #endregion #region Parameters if (cmp.Parameters.Count > 0) { createDom.Statements.AddRange(CreateCodeParameterDeclarationExpressionCollection(new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(CodeMemberPropertyVariableName), ParametersPropertyName), cmp.Parameters)); } #endregion #region HasGet if (cmp.HasGet) { createDom.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(CodeMemberPropertyVariableName), HasGetPropertyName), CreatePrimitive(cmp.HasGet))); createDom.Statements.Add(CreateAddRangeExpression(CodeMemberPropertyVariableName, GetStatementsPropertyName, decl, cmp.GetStatements, typeof(CodeStatement))); } #endregion #region HasSet if (cmp.HasSet) { createDom.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(CodeMemberPropertyVariableName), HasSetPropertyName), CreatePrimitive(cmp.HasSet))); createDom.Statements.Add(CreateAddRangeExpression(CodeMemberPropertyVariableName, SetStatementsPropertyName, decl, cmp.SetStatements, typeof(CodeStatement))); } #endregion createDom.Statements.Add(CreateReturnStatement(CodeMemberPropertyVariableName)); decl.Members.Add(createDom); parentDeclaration.Members.Add(decl); return CreateDeclarationMethodReferenceExpression(decl); } #endregion #region [ CodeMemberField ] private const string CodeMemberFieldVariableName = "codeMemberField"; private const string InitExpressionPropertyName = "InitExpression"; private static CodeExpression CreateDom(CodeTypeDeclaration parentDeclaration, CodeMemberField cmf) { CodeTypeDeclaration decl = new CodeTypeDeclaration(MakeSafe(cmf.Name + "_CodeMemberField")); CodeMemberMethod createDom = CreateDomMethod(); createDom.ReturnType = new CodeTypeReference(typeof(CodeMemberField)); createDom.Statements.Add(CreateDomCreateObjectStatement(CodeMemberFieldVariableName, typeof(CodeMemberField))); createDom.Statements.AddRange(CreateCommonCodeTypeMemberProperties(CodeMemberFieldVariableName, cmf, decl)); #region InitExpression if (cmf.InitExpression != null) { createDom.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(CodeMemberFieldVariableName), InitExpressionPropertyName), CreateDom(decl, cmf.InitExpression))); } #endregion #region Type if (cmf.Type != null) { createDom.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(CodeMemberFieldVariableName), TypePropertyName), CreateDom(cmf.Type))); } #endregion createDom.Statements.Add(CreateReturnStatement(CodeMemberFieldVariableName)); decl.Members.Add(createDom); parentDeclaration.Members.Add(decl); return CreateDeclarationMethodReferenceExpression(decl); } #endregion #region [ CodeMemberEvent ] private const string CodeMemberEventVariableName = "codeMemberEvent"; private const string ImplementationTypesPropertyName = "ImplementationTypes"; private const string TypePropertyName = "Type"; private const string PrivateImplementationTypePropertyName = "PrivateImplementationType"; private static CodeExpression CreateDom(CodeTypeDeclaration parentDeclaration, CodeMemberEvent cme) { CodeTypeDeclaration decl = new CodeTypeDeclaration(MakeSafe(cme.Name + "_CodeMemberEvent")); CodeMemberMethod createDom = CreateDomMethod(); createDom.ReturnType = new CodeTypeReference(typeof(CodeMemberEvent)); createDom.Statements.Add(CreateDomCreateObjectStatement(CodeMemberEventVariableName, typeof(CodeMemberEvent))); createDom.Statements.AddRange(CreateCommonCodeTypeMemberProperties(CodeMemberEventVariableName, cme, decl)); #region Type if (cme.Type != null) { createDom.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(CodeMemberEventVariableName), TypePropertyName), CreateDom(cme.Type))); } #endregion #region ImplementationTypes if (cme.ImplementationTypes.Count > 0) { createDom.Statements.Add(CreateAddRangeExpression(CodeTypeDelegateVariableName, ImplementationTypesPropertyName, decl, cme.ImplementationTypes, typeof(CodeTypeReference))); } #endregion #region PrivateImplementationType if (cme.PrivateImplementationType != null) { createDom.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(CodeMemberEventVariableName), PrivateImplementationTypePropertyName), CreateDom(cme.PrivateImplementationType))); } #endregion createDom.Statements.Add(CreateReturnStatement(CodeMemberEventVariableName)); decl.Members.Add(createDom); parentDeclaration.Members.Add(decl); return CreateDeclarationMethodReferenceExpression(decl); } #endregion #region [ CodeMemberMethod ] private const string CodeMemberMethodVariableName = "codeMemberMethod"; private const string ReturnTypeCustomAttributesPropertyName = "ReturnTypeCustomAttributes"; private const string StatementsPropertyName = "Statements"; private static CodeStatementCollection CreateCommonCodeMemberMethodProperties(string name, CodeMemberMethod cmm, CodeTypeDeclaration decl) { CodeStatementCollection collection = new CodeStatementCollection(); collection.AddRange(CreateCommonCodeTypeMemberProperties(name, cmm, decl)); #region ReturnType if (cmm.ReturnType != null) { collection.Add(new CodeAssignStatement(new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(name), ReturnTypePropertyName), CreateDom(cmm.ReturnType))); } #endregion #region ImplementationTypes if (cmm.ImplementationTypes.Count > 0) { collection.Add(CreateAddRangeExpression(name, ImplementationTypesPropertyName, decl, cmm.ImplementationTypes, typeof(CodeTypeReference))); } #endregion #region PrivateImplementationType if (cmm.PrivateImplementationType != null) { collection.Add(new CodeAssignStatement(new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(name), PrivateImplementationTypePropertyName), CreateDom(cmm.PrivateImplementationType))); } #endregion #region Parameters if (cmm.Parameters.Count > 0) { collection.AddRange(CreateCodeParameterDeclarationExpressionCollection(new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(name), ParametersPropertyName), cmm.Parameters)); } #endregion #region ReturnTypeCustomAttributes if (cmm.ReturnTypeCustomAttributes.Count > 0) { collection.Add(CreateAddRangeExpression(name, ReturnTypeCustomAttributesPropertyName, decl, cmm.ReturnTypeCustomAttributes, typeof(CodeAttributeDeclaration))); } #endregion #region Statements if (cmm.Statements.Count > 0) { collection.Add(CreateAddRangeExpression(name, StatementsPropertyName, decl, cmm.Statements, typeof(CodeStatement))); } #endregion return collection; } private static CodeExpression CreateDom(CodeTypeDeclaration parentDeclaration, CodeMemberMethod cmm) { CodeTypeDeclaration decl = new CodeTypeDeclaration(MakeSafe(cmm.Name + "_CodeMemberMethod")); CodeMemberMethod createDom = CreateDomMethod(); createDom.ReturnType = new CodeTypeReference(typeof(CodeMemberMethod)); createDom.Statements.Add(CreateDomCreateObjectStatement(CodeMemberMethodVariableName, typeof(CodeMemberMethod))); createDom.Statements.AddRange(CreateCommonCodeMemberMethodProperties(CodeMemberMethodVariableName, cmm, decl)); createDom.Statements.Add(CreateReturnStatement(CodeMemberMethodVariableName)); decl.Members.Add(createDom); parentDeclaration.Members.Add(decl); return CreateDeclarationMethodReferenceExpression(decl); } #endregion #region [ CodeConstructor ] private const string CodeConstructorVariableName = "codeConstructor"; private const string BaseConstructorArgsPropertyName = "BaseConstructorArgs"; private const string ChainedConstructorArgsPropertyName = "ChainedConstructorArgs"; private static CodeExpression CreateDom(CodeTypeDeclaration parentDeclaration, CodeConstructor cc) { CodeTypeDeclaration decl = new CodeTypeDeclaration("CodeConstructor" + Seed); CodeMemberMethod createDom = CreateDomMethod(); createDom.ReturnType = new CodeTypeReference(typeof(CodeConstructor)); createDom.Statements.Add(CreateDomCreateObjectStatement(CodeConstructorVariableName, typeof(CodeConstructor))); createDom.Statements.AddRange(CreateCommonCodeMemberMethodProperties(CodeConstructorVariableName, cc, decl)); #region BaseConstructorArgs if (cc.BaseConstructorArgs.Count > 0) { createDom.Statements.Add(CreateAddRangeExpression(CodeConstructorVariableName, BaseConstructorArgsPropertyName, decl, cc.BaseConstructorArgs, typeof(CodeExpression))); } #endregion #region ChainedConstructorArgs if (cc.ChainedConstructorArgs.Count > 0) { createDom.Statements.Add(CreateAddRangeExpression(CodeConstructorVariableName, ChainedConstructorArgsPropertyName, decl, cc.ChainedConstructorArgs, typeof(CodeExpression))); } #endregion createDom.Statements.Add(CreateReturnStatement(CodeConstructorVariableName)); decl.Members.Add(createDom); parentDeclaration.Members.Add(decl); return CreateDeclarationMethodReferenceExpression(decl); } #endregion #region [ CodeEntryPointMethod ] private const string CodeEntryPointMethodVariableName = "codeEntryPointMethod"; private static CodeExpression CreateDom(CodeTypeDeclaration parentDeclaration, CodeEntryPointMethod cepm) { CodeTypeDeclaration decl = new CodeTypeDeclaration("CodeEntryPointMethod" + Seed.ToString()); CodeMemberMethod createDom = CreateDomMethod(); createDom.ReturnType = new CodeTypeReference(typeof(CodeEntryPointMethod)); createDom.Statements.Add(CreateDomCreateObjectStatement(CodeEntryPointMethodVariableName, typeof(CodeEntryPointMethod))); createDom.Statements.AddRange(CreateCommonCodeMemberMethodProperties(CodeEntryPointMethodVariableName, cepm, decl)); createDom.Statements.Add(CreateReturnStatement(CodeEntryPointMethodVariableName)); decl.Members.Add(createDom); parentDeclaration.Members.Add(decl); return CreateDeclarationMethodReferenceExpression(decl); } #endregion #region [ CodeTypeConstructor ] private const string CodeTypeConstructorVariableName = "codeTypeConstructor"; private static CodeExpression CreateDom(CodeTypeDeclaration parentDeclaration, CodeTypeConstructor ctc) { CodeTypeDeclaration decl = new CodeTypeDeclaration("CodeTypeConstructor" + Seed.ToString()); CodeMemberMethod createDom = CreateDomMethod(); createDom.ReturnType = new CodeTypeReference(typeof(CodeTypeConstructor)); createDom.Statements.Add(CreateDomCreateObjectStatement(CodeTypeConstructorVariableName, typeof(CodeTypeConstructor))); createDom.Statements.AddRange(CreateCommonCodeMemberMethodProperties(CodeTypeConstructorVariableName, ctc, decl)); createDom.Statements.Add(CreateReturnStatement(CodeTypeConstructorVariableName)); decl.Members.Add(createDom); parentDeclaration.Members.Add(decl); return CreateDeclarationMethodReferenceExpression(decl); } #endregion #region [ Assisting Methods ] private static string MakeSafe(string name) { string search = name; for (char c = 'a'; c <= 'z'; c++) { search = search.Replace(c, '\\'); } for (char c = 'A'; c <= 'Z'; c++) { search = search.Replace(c, '\\'); } for (char c = '0'; c <= '9'; c++) { search = search.Replace(c, '\\'); } for (int i = 0; i < search.Length; i++) { if (search[i] != '\\') { name = name.Replace(search[i], '_'); } } return name + Seed.ToString(); } private static CodeExpression CreateDeclarationMethodReferenceExpression(CodeTypeDeclaration decl) { return new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(decl.Name), CreateDomMethodName)); } private static CodeMemberMethod CreateDomMethod() { CodeMemberMethod createDom = new CodeMemberMethod(); createDom.Name = CreateDomMethodName; createDom.Attributes &= ~MemberAttributes.AccessMask & ~MemberAttributes.ScopeMask; createDom.Attributes |= MemberAttributes.Public | MemberAttributes.Static; createDom.Comments.Add(new CodeCommentStatement("Creates the code for this code element.")); return createDom; } private static CodeStatement CreateDomCreateObjectStatement(string name, Type type) { return new CodeVariableDeclarationStatement(type, name, new CodeObjectCreateExpression(type)); } private static CodeStatement CreateReturnStatement(string name) { return new CodeMethodReturnStatement(new CodeVariableReferenceExpression(name)); } private static CodeExpression CreateAddRangeExpression(string variableName, string propertyName, CodeTypeDeclaration declaration, System.Collections.IList list, Type singleType) { return new CodeMethodInvokeExpression(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression(variableName), propertyName), CollectionAddRangeMethodName, CreateDom(declaration, list, singleType)); } #endregion #region [ Statements and Expressions ] #region [ CodeStatement ] private static CodeExpression CreateDom(CodeTypeDeclaration parentDeclaration, CodeStatement ce) { if (ce.LinePragma != null) { throw new NotSupportedException("Expression Line Pragmas Not Supported."); } if (ce is CodeAssignStatement) { return new CodeObjectCreateExpression(typeof(CodeAssignStatement), CreateDom(parentDeclaration, ((CodeAssignStatement)(ce)).Left), CreateDom(parentDeclaration, ((CodeAssignStatement)(ce)).Right)); } else if (ce is CodeAttachEventStatement) { return new CodeObjectCreateExpression(typeof(CodeAttachEventStatement), CreateDom(parentDeclaration, ((CodeAttachEventStatement)(ce)).Event), CreateDom(parentDeclaration, ((CodeAttachEventStatement)(ce)).Listener)); } else if (ce is CodeCommentStatement) { return new CodeObjectCreateExpression(typeof(CodeCommentStatement), CreateDom(((CodeCommentStatement)(ce)).Comment)); } else if (ce is CodeConditionStatement) { return new CodeObjectCreateExpression(typeof(CodeConditionStatement), CreateDom(parentDeclaration, ((CodeConditionStatement)(ce)).Condition), CreateDom(parentDeclaration, ((CodeConditionStatement)(ce)).TrueStatements, typeof(CodeStatement)), CreateDom(parentDeclaration, ((CodeConditionStatement)(ce)).FalseStatements, typeof(CodeStatement))); } else if (ce is CodeExpressionStatement) { return new CodeObjectCreateExpression(typeof(CodeExpressionStatement), CreateDom(parentDeclaration, ((CodeExpressionStatement)(ce)).Expression)); } else if (ce is CodeGotoStatement) { return new CodeObjectCreateExpression(typeof(CodeGotoStatement), new CodePrimitiveExpression(((CodeGotoStatement)(ce)).Label)); } else if (ce is CodeIterationStatement) { return new CodeObjectCreateExpression(typeof(CodeIterationStatement), CreateDom(parentDeclaration, ((CodeIterationStatement)(ce)).InitStatement), CreateDom(parentDeclaration, ((CodeIterationStatement)(ce)).TestExpression), CreateDom(parentDeclaration, ((CodeIterationStatement)(ce)).IncrementStatement), CreateDom(parentDeclaration, ((CodeIterationStatement)(ce)).Statements, typeof(CodeStatement))); } else if (ce is CodeLabeledStatement) { return new CodeObjectCreateExpression(typeof(CodeLabeledStatement), new CodePrimitiveExpression(((CodeLabeledStatement)(ce)).Label), CreateDom(parentDeclaration, ((CodeLabeledStatement)(ce)).Statement)); } else if (ce is CodeMethodReturnStatement) { return new CodeObjectCreateExpression(typeof(CodeMethodReturnStatement), CreateDom(parentDeclaration, ((CodeMethodReturnStatement)(ce)).Expression)); } else if (ce is CodeRemoveEventStatement) { return new CodeObjectCreateExpression(typeof(CodeRemoveEventStatement), CreateDom(parentDeclaration, ((CodeRemoveEventStatement)(ce)).Event), CreateDom(parentDeclaration, ((CodeRemoveEventStatement)(ce)).Listener)); } else if (ce is CodeThrowExceptionStatement) { return new CodeObjectCreateExpression(typeof(CodeThrowExceptionStatement), CreateDom(parentDeclaration, ((CodeThrowExceptionStatement)(ce)).ToThrow)); } else if (ce is CodeTryCatchFinallyStatement) { return new CodeObjectCreateExpression(typeof(CodeTryCatchFinallyStatement), CreateDom(parentDeclaration, ((CodeTryCatchFinallyStatement)(ce)).TryStatements, typeof(CodeStatement)), CreateDom(parentDeclaration, ((CodeTryCatchFinallyStatement)(ce)).CatchClauses, typeof(CodeCatchClause)), CreateDom(parentDeclaration, ((CodeTryCatchFinallyStatement)(ce)).FinallyStatements, typeof(CodeStatement))); } else if (ce is CodeVariableDeclarationStatement) { if (((CodeVariableDeclarationStatement)(ce)).InitExpression != null) { return new CodeObjectCreateExpression(typeof(CodeVariableDeclarationStatement), CreateDom(parentDeclaration, ((CodeVariableDeclarationStatement)(ce)).Type), new CodePrimitiveExpression(((CodeVariableDeclarationStatement)(ce)).Name), CreateDom(parentDeclaration, ((CodeVariableDeclarationStatement)(ce)).InitExpression)); } else { return new CodeObjectCreateExpression(typeof(CodeVariableDeclarationStatement), CreateDom(parentDeclaration, ((CodeVariableDeclarationStatement)(ce)).Type), new CodePrimitiveExpression(((CodeVariableDeclarationStatement)(ce)).Name)); } } else if (ce == null) { return new CodePrimitiveExpression(null); } throw new NotSupportedException(); } #endregion #region [ CodeExpression ] private static CodeExpression CreateDom(CodeTypeDeclaration parentDeclaration, CodeExpression ce) { if (ce is CodeArgumentReferenceExpression) { return new CodeObjectCreateExpression(typeof(CodeArgumentReferenceExpression), new CodePrimitiveExpression(((CodeArgumentReferenceExpression)(ce)).ParameterName)); } else if (ce is CodeArrayCreateExpression) { if (((CodeArrayCreateExpression)(ce)).SizeExpression != null) { return new CodeObjectCreateExpression(typeof(CodeArrayCreateExpression), CreateDom(parentDeclaration, ((CodeArrayCreateExpression)(ce)).CreateType), CreateDom(parentDeclaration, ((CodeArrayCreateExpression)(ce)).SizeExpression)); } else if (((CodeArrayCreateExpression)(ce)).Initializers.Count > 0) { CodeExpression[] initializingExpressionCreates = new CodeExpression[((CodeArrayCreateExpression)(ce)).Initializers.Count]; for (int i = 0; i < ((CodeArrayCreateExpression)(ce)).Initializers.Count; i++) { initializingExpressionCreates[i] = CreateDom(parentDeclaration, ((CodeArrayCreateExpression)(ce)).Initializers[i]); } return new CodeObjectCreateExpression(typeof(CodeArrayCreateExpression), CreateDom(parentDeclaration, ((CodeArrayCreateExpression)(ce)).CreateType), new CodeArrayCreateExpression(typeof(CodeExpression), initializingExpressionCreates)); } else { return new CodeObjectCreateExpression(typeof(CodeArrayCreateExpression), CreateDom(parentDeclaration, ((CodeArrayCreateExpression)(ce)).CreateType), new CodePrimitiveExpression(((CodeArrayCreateExpression)(ce)).Size)); } } else if (ce is CodeArrayIndexerExpression) { CodeExpression[] indicesExpressionCreates = new CodeExpression[((CodeArrayIndexerExpression)(ce)).Indices.Count]; for (int i = 0; i < ((CodeArrayIndexerExpression)(ce)).Indices.Count; i++) { indicesExpressionCreates[i] = CreateDom(parentDeclaration, ((CodeArrayIndexerExpression)(ce)).Indices[i]); } return new CodeObjectCreateExpression(typeof(CodeArrayIndexerExpression), CreateDom(parentDeclaration, ((CodeArrayIndexerExpression)(ce)).TargetObject), new CodeArrayCreateExpression(typeof(CodeExpression), indicesExpressionCreates)); } else if (ce is CodeBaseReferenceExpression) { return new CodeObjectCreateExpression(typeof(CodeBaseReferenceExpression)); } else if (ce is CodeBinaryOperatorExpression) { return new CodeObjectCreateExpression(typeof(CodeBinaryOperatorExpression), CreateDom(parentDeclaration, ((CodeBinaryOperatorExpression)(ce)).Left), CreateEnum(((int)(((CodeBinaryOperatorExpression)(ce)).Operator)), typeof(CodeBinaryOperatorType)), CreateDom(parentDeclaration, ((CodeBinaryOperatorExpression)(ce)).Right)); } else if (ce is CodeCastExpression) { return new CodeObjectCreateExpression(typeof(CodeCastExpression), CreateDom(parentDeclaration, ((CodeCastExpression)(ce)).TargetType), CreateDom(parentDeclaration, ((CodeCastExpression)(ce)).Expression)); } else if (ce is CodeDelegateCreateExpression) { return new CodeObjectCreateExpression(typeof(CodeDelegateCreateExpression), CreateDom(parentDeclaration, ((CodeDelegateCreateExpression)(ce)).DelegateType), CreateDom(parentDeclaration, ((CodeDelegateCreateExpression)(ce)).TargetObject), new CodePrimitiveExpression(((CodeDelegateCreateExpression)(ce)).MethodName)); } else if (ce is CodeDelegateInvokeExpression) { if (((CodeDelegateInvokeExpression)(ce)).Parameters.Count > 0) { CodeExpression[] parametersExpressionCreates = new CodeExpression[((CodeDelegateInvokeExpression)(ce)).Parameters.Count]; for (int i = 0; i < ((CodeDelegateInvokeExpression)(ce)).Parameters.Count; i++) { parametersExpressionCreates[i] = CreateDom(parentDeclaration, ((CodeDelegateInvokeExpression)(ce)).Parameters[i]); } return new CodeObjectCreateExpression(typeof(CodeDelegateInvokeExpression), CreateDom(parentDeclaration, ((CodeDelegateInvokeExpression)(ce)).TargetObject), new CodeArrayCreateExpression(typeof(CodeExpression), parametersExpressionCreates)); } else { return new CodeObjectCreateExpression(typeof(CodeDelegateInvokeExpression), CreateDom(parentDeclaration, ((CodeDelegateInvokeExpression)(ce)).TargetObject)); } } else if (ce is CodeDirectionExpression) { return new CodeObjectCreateExpression(typeof(CodeDirectionExpression), CreateEnum(((int)(((CodeDirectionExpression)(ce)).Direction)), typeof(FieldDirection)), CreateDom(parentDeclaration, ((CodeDirectionExpression)(ce)).Expression)); } else if (ce is CodeEventReferenceExpression) { return new CodeObjectCreateExpression(typeof(CodeEventReferenceExpression), CreateDom(parentDeclaration, ((CodeEventReferenceExpression)(ce)).TargetObject), new CodePrimitiveExpression(((CodeEventReferenceExpression)(ce)).EventName)); } else if (ce is CodeFieldReferenceExpression) { return new CodeObjectCreateExpression(typeof(CodeFieldReferenceExpression), CreateDom(parentDeclaration, ((CodeFieldReferenceExpression)(ce)).TargetObject), new CodePrimitiveExpression(((CodeFieldReferenceExpression)(ce)).FieldName)); } else if (ce is CodeIndexerExpression) { CodeExpression[] indicesExpressionCreates = new CodeExpression[((CodeIndexerExpression)(ce)).Indices.Count]; for (int i = 0; i < ((CodeIndexerExpression)(ce)).Indices.Count; i++) { indicesExpressionCreates[i] = CreateDom(parentDeclaration, ((CodeIndexerExpression)(ce)).Indices[i]); } return new CodeObjectCreateExpression(typeof(CodeIndexerExpression), CreateDom(parentDeclaration, ((CodeIndexerExpression)(ce)).TargetObject), new CodeArrayCreateExpression(typeof(CodeExpression), indicesExpressionCreates)); } else if (ce is CodeMethodInvokeExpression) { if (((CodeMethodInvokeExpression)(ce)).Parameters.Count > 0) { CodeExpression[] parametersExpressionCreates = new CodeExpression[((CodeMethodInvokeExpression)(ce)).Parameters.Count]; for (int i = 0; i < ((CodeMethodInvokeExpression)(ce)).Parameters.Count; i++) { parametersExpressionCreates[i] = CreateDom(parentDeclaration, ((CodeMethodInvokeExpression)(ce)).Parameters[i]); } return new CodeObjectCreateExpression(typeof(CodeMethodInvokeExpression), CreateDom(parentDeclaration, ((CodeMethodInvokeExpression)(ce)).Method), new CodeArrayCreateExpression(typeof(CodeExpression), parametersExpressionCreates)); } else { return new CodeObjectCreateExpression(typeof(CodeMethodInvokeExpression), CreateDom(parentDeclaration, ((CodeMethodInvokeExpression)(ce)).Method)); } } else if (ce is CodeMethodReferenceExpression) { return new CodeObjectCreateExpression(typeof(CodeMethodReferenceExpression), CreateDom(parentDeclaration, ((CodeMethodReferenceExpression)(ce)).TargetObject), new CodePrimitiveExpression(((CodeMethodReferenceExpression)(ce)).MethodName)); } else if (ce is CodeObjectCreateExpression) { if (((CodeObjectCreateExpression)(ce)).Parameters.Count > 0) { CodeExpression[] parametersExpressionCreates = new CodeExpression[((CodeObjectCreateExpression)(ce)).Parameters.Count]; for (int i = 0; i < ((CodeObjectCreateExpression)(ce)).Parameters.Count; i++) { parametersExpressionCreates[i] = CreateDom(parentDeclaration, ((CodeObjectCreateExpression)(ce)).Parameters[i]); } return new CodeObjectCreateExpression(typeof(CodeObjectCreateExpression), CreateDom(((CodeObjectCreateExpression)(ce)).CreateType), new CodeArrayCreateExpression(typeof(CodeExpression), parametersExpressionCreates)); } else { return new CodeObjectCreateExpression(typeof(CodeObjectCreateExpression), CreateDom(parentDeclaration, ((CodeObjectCreateExpression)(ce)).CreateType)); } } else if (ce is CodeParameterDeclarationExpression) { throw new NotSupportedException("Wrong turn. This is not the method that handles this kind of object."); } else if (ce is CodePrimitiveExpression) { return new CodeObjectCreateExpression(typeof(CodePrimitiveExpression), new CodePrimitiveExpression(((CodePrimitiveExpression)(ce)).Value)); } else if (ce is CodePropertyReferenceExpression) { return new CodeObjectCreateExpression(typeof(CodePropertyReferenceExpression), CreateDom(parentDeclaration, ((CodePropertyReferenceExpression)(ce)).TargetObject), new CodePrimitiveExpression(((CodePropertyReferenceExpression)(ce)).PropertyName)); } else if (ce is CodePropertySetValueReferenceExpression) { return new CodeObjectCreateExpression(typeof(CodePropertySetValueReferenceExpression)); } else if (ce is CodeThisReferenceExpression) { return new CodeObjectCreateExpression(typeof(CodeThisReferenceExpression)); } else if (ce is CodeTypeOfExpression) { return new CodeObjectCreateExpression(typeof(CodeTypeOfExpression), CreateDom(parentDeclaration, ((CodeTypeOfExpression)(ce)).Type)); } else if (ce is CodeTypeReferenceExpression) { return new CodeObjectCreateExpression(typeof(CodeTypeReferenceExpression), CreateDom(parentDeclaration, ((CodeTypeReferenceExpression)(ce)).Type)); } else if (ce is CodeVariableReferenceExpression) { return new CodeObjectCreateExpression(typeof(CodeVariableReferenceExpression), new CodePrimitiveExpression(((CodeVariableReferenceExpression)(ce)).VariableName)); } else if (ce == null) { return new CodePrimitiveExpression(null); } throw new NotSupportedException(); } #endregion #endregion #region [ Simpler Classes ] #region [ System.Collections.IList ] private const string CollectionAddMethodName = "Add"; private const string CollectionAddRangeMethodName = "AddRange"; private static CodeExpression CreateDom(CodeTypeDeclaration parentDeclaration, System.Collections.IList list, Type expectedType) { CodeArrayCreateExpression listCreate = new CodeArrayCreateExpression(expectedType); foreach (object o in list) { listCreate.Initializers.Add(CreateDom(parentDeclaration, o)); } return listCreate; } #endregion #region [ CodeParameterDeclarationExpressionCollection ] private const string CodeParameterDeclarationExpressionVariableName = "codeParameterDeclarationExpression"; private const string DirectionPropertyName = "Direction"; private static CodeStatementCollection CreateCodeParameterDeclarationExpressionCollection(CodeExpression setTo, CodeParameterDeclarationExpressionCollection cpdec) { CodeStatementCollection collection = new CodeStatementCollection(); for (int i = 0; i < cpdec.Count; i++) { CodeParameterDeclarationExpression expression = cpdec[i]; string curName = CodeParameterDeclarationExpressionVariableName + expression.Name; collection.Add(new CodeVariableDeclarationStatement(typeof(CodeParameterDeclarationExpression), curName, new CodeObjectCreateExpression(typeof(CodeParameterDeclarationExpression), CreateDom(expression.Type), new CodePrimitiveExpression(expression.Name)))); #region CustomAttributes if (expression.CustomAttributes.Count > 0) { collection.Add(CreateAddRangeExpression(curName, CustomAttributesPropertyName, null, expression.CustomAttributes, typeof(CodeAttributeDeclaration))); } #endregion #region Direction if (((int)(expression.Direction)) != 0) { collection.Add(new CodeAssignStatement(new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(curName), DirectionPropertyName), CreateEnum(((int)(expression.Direction)), typeof(FieldDirection)))); } #endregion collection.Add(new CodeMethodInvokeExpression(setTo, CollectionAddMethodName, new CodeVariableReferenceExpression(curName))); } return collection; } #endregion #region [ CodeSnippetTypeMember ] private static CodeExpression CreateDom(CodeSnippetTypeMember cstm) { return new CodeObjectCreateExpression(typeof(CodeSnippetTypeMember), new CodePrimitiveExpression(cstm.Text)); } #endregion #region [ CodeComment ] private static CodeExpression CreateDom(CodeComment cc) { return new CodeObjectCreateExpression(typeof(CodeComment), new CodePrimitiveExpression(cc.Text), new CodePrimitiveExpression(cc.DocComment)); } #endregion #region [ CodeNamespaceImport ] private static CodeExpression CreateDom(CodeNamespaceImport cni) { return new CodeObjectCreateExpression(typeof(CodeNamespaceImport), new CodePrimitiveExpression(cni.Namespace)); } #endregion #region [ CodeTypeReference ] private static CodeExpression CreateDom(CodeTypeReference ctr) { Type t = Type.GetType(ctr.BaseType); if (t == null) { if (ctr.ArrayRank == 0) { return new CodeObjectCreateExpression(typeof(CodeTypeReference), new CodePrimitiveExpression(ctr.BaseType)); } else { return new CodeObjectCreateExpression(typeof(CodeTypeReference), new CodePrimitiveExpression(ctr.BaseType), new CodePrimitiveExpression(ctr.ArrayRank)); } } else { if (ctr.ArrayRank == 0) { return new CodeObjectCreateExpression(typeof(CodeTypeReference), new CodeTypeOfExpression(t)); } else { return new CodeObjectCreateExpression(typeof(CodeTypeReference), new CodeTypeOfExpression(t), new CodePrimitiveExpression(ctr.ArrayRank)); } } } #endregion #region [ CodeLinePragma ] private static CodeExpression CreateDom(CodeLinePragma clp) { return new CodeObjectCreateExpression(typeof(CodeLinePragma), new CodePrimitiveExpression(clp.FileName), new CodePrimitiveExpression(clp.LineNumber)); } #endregion #region [ CodeAttributeDeclaration ] private const string CodeAttributeDeclarationVariableName = "codeAttributeDeclaration"; private const string ArgumentsPropertyName = "Arguments"; private static CodeExpression CreateDom(CodeTypeDeclaration parentDeclaration, CodeAttributeDeclaration cad) { CodeTypeDeclaration decl = new CodeTypeDeclaration("CodeAttributeDeclaration" + Seed); CodeMemberMethod createDom = CreateDomMethod(); createDom.ReturnType = new CodeTypeReference(typeof(CodeAttributeDeclaration)); createDom.Statements.Add(CreateDomCreateObjectStatement(CodeAttributeDeclarationVariableName, typeof(CodeAttributeDeclaration))); // Name if (cad.Name != null) { createDom.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression(CodeAttributeDeclarationVariableName), NamePropertyName), CreatePrimitive(cad.Name))); } // Arguments if (cad.Arguments.Count > 0) { createDom.Statements.Add(CreateAddRangeExpression(CodeAttributeDeclarationVariableName, ArgumentsPropertyName, decl, cad.Arguments, typeof(CodeAttributeArgument))); } createDom.Statements.Add(CreateReturnStatement(CodeAttributeDeclarationVariableName)); decl.Members.Add(createDom); parentDeclaration.Members.Add(decl); return CreateDeclarationMethodReferenceExpression(decl); } #endregion #region [ CodeAttributeArgument ] private const string CodeAttributeArgumentVariableName = "codeAttributeArgument"; private static CodeExpression CreateDom(CodeTypeDeclaration parentDeclaration, CodeAttributeArgument caa) { CodeTypeDeclaration decl = new CodeTypeDeclaration("CodeAttributeArgument" + Seed); CodeMemberMethod createDom = CreateDomMethod(); createDom.ReturnType = new CodeTypeReference(typeof(CodeAttributeArgument)); createDom.Statements.Add(CreateDomCreateObjectStatement(CodeAttributeArgumentVariableName, typeof(CodeAttributeArgument))); // Name if (caa.Name != null) { createDom.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression(CodeAttributeArgumentVariableName), NamePropertyName), CreatePrimitive(caa.Name))); } if (caa.Value != null) { createDom.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression(CodeAttributeArgumentVariableName), ValuePropertyName), CreateDom(decl, caa.Value))); } createDom.Statements.Add(CreateReturnStatement(CodeAttributeArgumentVariableName)); decl.Members.Add(createDom); parentDeclaration.Members.Add(decl); return CreateDeclarationMethodReferenceExpression(decl); } #endregion #region [ Primitive Types ] private static CodeExpression CreatePrimitive(object o) { return new CodePrimitiveExpression(o); } #endregion #endregion #region [ Enums ] private static CodeExpression CreateEnum(int enumValue, Type enumType) { CodeExpression expr = null; SortedList orderedValues = new SortedList(new EnumValueComparer()); foreach (int unsortedValue in Enum.GetValues(enumType)) { if (unsortedValue != 0 && orderedValues[unsortedValue] == null) { orderedValues.Add(unsortedValue, Enum.GetName(enumType, unsortedValue)); } } foreach (int sortedValue in orderedValues.Keys) { if ((enumValue & sortedValue) == sortedValue) { if (expr != null) { expr = new CodeBinaryOperatorExpression(expr, CodeBinaryOperatorType.BitwiseOr, new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(enumType), orderedValues[sortedValue].ToString())); } else { expr = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(enumType), orderedValues[sortedValue].ToString()); } enumValue -= sortedValue; } } if (expr == null) { if (Enum.GetName(enumType, 0) == null) { throw new ArgumentException("enumValue"); } else { return new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(enumType), Enum.GetName(enumType, 0)); } } else { return expr; } } internal class EnumValueComparer : IComparer { public int Compare(object x, object y) { return (((int)(y)) - ((int)(x))); } } #endregion } }