Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / XamlBuildTask / Microsoft / Build / Tasks / Xaml / ClassGenerator.cs / 1589821 / ClassGenerator.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace Microsoft.Build.Tasks.Xaml { using System; using System.CodeDom; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Xml.Linq; using System.Reflection; using System.Xaml; using System.Xaml.Schema; using System.Windows.Markup; using System.Runtime; using System.Globalization; using System.Diagnostics.CodeAnalysis; using System.CodeDom.Compiler; using System.Runtime.InteropServices; using System.Xml; class ClassGenerator { static CodeThisReferenceExpression CodeThis = new CodeThisReferenceExpression(); IExceptionLogger buildLogger; CodeDomProvider codeDomProvider; public ClassGenerator(IExceptionLogger buildLogger, CodeDomProvider codeDomProvider) { this.buildLogger = buildLogger; this.codeDomProvider = codeDomProvider; } public CodeCompileUnit Generate(ClassData classData) { if (classData == null) { throw FxTrace.Exception.ArgumentNull("classData"); } CodeCompileUnit result = new CodeCompileUnit(); // Add global namespace CodeNamespace globalNamespace = new CodeNamespace(); result.Namespaces.Add(globalNamespace); CodeTypeDeclaration classDeclaration = GenerateClass(classData); if (!String.IsNullOrEmpty(classData.Namespace)) { // Add namespace the class is defined in CodeNamespace classNamespace = new CodeNamespace(classData.Namespace); result.Namespaces.Add(classNamespace); classNamespace.Types.Add(classDeclaration); } else { // Add class to global namespace globalNamespace.Types.Add(classDeclaration); } return result; } CodeTypeDeclaration GenerateClass(ClassData classData) { CodeTypeDeclaration result = GenerateClassDeclaration(classData); result.Members.Add(new CodeMemberField() { Name = "_contentLoaded", Type = new CodeTypeReference(typeof(bool)) }); // Generate fields that match x:Name objects var fields = classData.NamedObjects; var memberFields = new List(); foreach (NamedObject field in fields) { CodeMemberField fieldMember = GenerateField(field, classData); memberFields.Add(fieldMember); result.Members.Add(fieldMember); } // Generate properties if (classData.Members != null) { foreach (PropertyDefinition property in classData.Members.Values) { CodeTypeMember[] propertyMembers = GenerateProperty(property, classData); result.Members.AddRange(propertyMembers); } } // Generate all x:Code foreach (string code in classData.CodeSnippets) { CodeSnippetTypeMember codeSnippet = new CodeSnippetTypeMember(code); result.Members.Add(codeSnippet); } // Generate InitializeComponent method CodeMemberMethod initializeMethod = GenerateInitializeMethod(classData, memberFields); result.Members.Add(initializeMethod); // Generate helper method to look up assembly resources result.Members.Add(GenerateFindResourceMethod(classData)); // Generate ISupportInitialize implementation result.BaseTypes.Add(new CodeTypeReference(typeof(ISupportInitialize))); result.Members.AddRange(GenerateISupportInitializeImpl(initializeMethod)); // Generate public parameterless constructor if user-provided source file does not exist if (!classData.SourceFileExists) { result.Members.Add(GenerateConstructorImpl(initializeMethod)); } return result; } CodeTypeDeclaration GenerateClassDeclaration(ClassData classData) { if (!this.codeDomProvider.IsValidIdentifier(classData.Name)) { throw FxTrace.Exception.AsError( this.buildLogger.LogException( new InvalidOperationException(SR.InvalidIdentifiers(classData.Name)), classData.FileName)); } // <%= visibility%> partial class <%= className %> : <%= type %> // { // } // CodeTypeDeclaration rootType = new CodeTypeDeclaration() { Name = classData.Name, IsPartial = true, TypeAttributes = GetTypeAttributes(classData.Visibility) }; if (classData.Attributes != null && classData.Attributes.Count > 0) { CodeAttributeDeclarationCollection attributeCollection = GetAttributeDeclarations(classData.Attributes, classData); if (attributeCollection != null && attributeCollection.Count > 0) { rootType.CustomAttributes.AddRange(attributeCollection); } } string baseClrTypeName; bool isLocal = false; if (!XamlBuildTaskServices.TryGetClrTypeName(classData.RootTypeName, classData.RootNamespace, out baseClrTypeName, out isLocal)) { throw FxTrace.Exception.AsError( this.buildLogger.LogException( new InvalidOperationException(SR.TaskCannotResolveType(XamlBuildTaskServices.GetFullTypeName(classData.RootTypeName))), classData.FileName)); } classData.RequiresCompilationPass2 |= isLocal; if (classData.TypeArguments.Count == 0) { rootType.BaseTypes.Add(baseClrTypeName); } else { CodeTypeReference baseType = new CodeTypeReference(baseClrTypeName); AddTypeArguments(baseType, classData.TypeArguments, classData); rootType.BaseTypes.Add(baseType); } Type baseClrType = classData.RootTypeName.UnderlyingType; if (baseClrType != null) { if (!IsComVisible(baseClrType)) { CodeAttributeDeclaration comVisibleFalseDeclaration = new CodeAttributeDeclaration("System.Runtime.InteropServices.ComVisible", new CodeAttributeArgument(new CodePrimitiveExpression(false))); rootType.CustomAttributes.Add(comVisibleFalseDeclaration); } } return rootType; } CodeAttributeDeclarationCollection GetAttributeDeclarations(IList attributes, ClassData classData) { CodeAttributeDeclarationCollection attributeCollection = new CodeAttributeDeclarationCollection(); foreach (AttributeData attrib in attributes) { string clrTypeName; bool isLocal = false; if (!XamlBuildTaskServices.TryGetClrTypeName(attrib.Type, classData.RootNamespace, out clrTypeName, out isLocal)) { throw FxTrace.Exception.AsError( this.buildLogger.LogException( new InvalidOperationException(SR.TaskCannotResolveType(XamlBuildTaskServices.GetFullTypeName(attrib.Type))), classData.FileName)); } classData.RequiresCompilationPass2 |= isLocal; CodeAttributeArgument[] arguments = new CodeAttributeArgument[attrib.Parameters.Count + attrib.Properties.Count]; int i; for (i = 0; i < attrib.Parameters.Count; i++) { arguments[i] = new CodeAttributeArgument(GetCodeExpressionForAttributeArgument(attrib.Parameters[i], classData)); } foreach (AttributeParameterInfo property in attrib.Properties) { arguments[i] = new CodeAttributeArgument(property.Name, GetCodeExpressionForAttributeArgument(property, classData)); i++; } attributeCollection.Add(new CodeAttributeDeclaration(new CodeTypeReference(clrTypeName), arguments)); } return attributeCollection; } CodeExpression GetCodeExpressionForAttributeArgument(AttributeParameterInfo paramInfo, ClassData classData) { CodeExpression codeExp; if (paramInfo.IsArray) { CodeExpression[] codeInitializationArray; if (paramInfo.ArrayContents.Count > 0) { codeInitializationArray = new CodeExpression[paramInfo.ArrayContents.Count]; for (int i = 0; i < paramInfo.ArrayContents.Count; i++) { codeInitializationArray[i] = GetCodeExpressionForAttributeArgument(paramInfo.ArrayContents[i], classData); } codeExp = new CodeArrayCreateExpression(paramInfo.Type, codeInitializationArray); } else { codeExp = new CodeArrayCreateExpression(paramInfo.Type); } } else { if (paramInfo.Value == null) { codeExp = new CodePrimitiveExpression(null); } else if (typeof(Type).IsAssignableFrom(paramInfo.Type)) { codeExp = new CodeTypeOfExpression(paramInfo.Value); } else if (paramInfo.Type == typeof(String)) { codeExp = new CodePrimitiveExpression(paramInfo.Value); } else if (paramInfo.Type == typeof(bool)) { if (paramInfo.Value == "true") { codeExp = new CodePrimitiveExpression(true); } else { codeExp = new CodePrimitiveExpression(false); } } else { codeExp = new CodeSnippetExpression(paramInfo.Value); } } return codeExp; } bool IsComVisible(Type t) { IList cads = CustomAttributeData.GetCustomAttributes(t); bool found = false; bool visible = false; foreach (var cad in cads) { if (cad.Constructor.DeclaringType == typeof(ComVisibleAttribute)) { found = true; visible = (bool)cad.ConstructorArguments[0].Value; if (!visible) { return false; } } } if (found) { return true; } cads = CustomAttributeData.GetCustomAttributes(t.Assembly); foreach (var cad in cads) { if (cad.Constructor.DeclaringType == typeof(ComVisibleAttribute)) { found = true; visible = (bool)cad.ConstructorArguments[0].Value; if (!visible) { return false; } } } return true; } void AddTypeArguments(CodeTypeReference baseType, IList typeArguments, ClassData classData) { foreach (XamlType argument in typeArguments) { string clrTypeName; bool isLocal = false; if (!XamlBuildTaskServices.TryGetClrTypeName(argument, classData.RootNamespace, out clrTypeName, out isLocal)) { throw FxTrace.Exception.AsError( this.buildLogger.LogException( new InvalidOperationException(SR.TaskCannotResolveType(XamlBuildTaskServices.GetFullTypeName(argument))), classData.FileName)); } classData.RequiresCompilationPass2 |= isLocal; CodeTypeReference typeReference = new CodeTypeReference(clrTypeName); if (argument.TypeArguments.Count > 0) { AddTypeArguments(typeReference, argument.TypeArguments, classData); } baseType.TypeArguments.Add(typeReference); } } private CodeMemberField GenerateField(NamedObject fieldData, ClassData classData) { CodeTypeReference fieldCodeType = null; if (!GetCodeTypeReferenceFromXamlType(fieldData.TypeName, classData, out fieldCodeType)) { throw FxTrace.Exception.AsError( this.buildLogger.LogException( new InvalidOperationException(SR.TaskCannotResolveFieldType(XamlBuildTaskServices.GetFullTypeName(fieldData.TypeName), fieldData.Name)), classData.FileName)); } if (!this.codeDomProvider.IsValidIdentifier(fieldData.Name)) { throw FxTrace.Exception.AsError( this.buildLogger.LogException( new InvalidOperationException(SR.InvalidIdentifiers(fieldData.Name)), classData.FileName)); } // <%= fieldData.Visibility %> WithEvents <%= fieldData.Type %> <%= fieldData.Name %>; // CodeMemberField field = new CodeMemberField() { Name = fieldData.Name, Type = fieldCodeType, Attributes = GetMemberAttributes(fieldData.Visibility) }; field.UserData["WithEvents"] = true; return field; } CodeMemberMethod GenerateInitializeMethod(ClassData classData, List memberFields) { // /// InitializeComponent // [DebuggerNonUserCodeAttribute] // public void InitializeComponent() { // CodeMemberMethod initializeMethod = new CodeMemberMethod() { Name = "InitializeComponent", Attributes = MemberAttributes.Public | MemberAttributes.Final, CustomAttributes = { new CodeAttributeDeclaration(new CodeTypeReference(typeof(DebuggerNonUserCodeAttribute))) } }; initializeMethod.Comments.AddRange(GenerateXmlComments(initializeMethod.Name)); // if (__contentLoaded) { return; } initializeMethod.Statements.Add( new CodeConditionStatement() { Condition = new CodeBinaryOperatorExpression() { Left = new CodeFieldReferenceExpression() { FieldName = "_contentLoaded", TargetObject = new CodeThisReferenceExpression() }, Operator = CodeBinaryOperatorType.ValueEquality, Right = new CodePrimitiveExpression(true) }, TrueStatements = { new CodeMethodReturnStatement() } } ); // __contentLoaded = true; initializeMethod.Statements.Add( new CodeAssignStatement() { Left = new CodeFieldReferenceExpression() { FieldName = "_contentLoaded", TargetObject = new CodeThisReferenceExpression() }, Right = new CodePrimitiveExpression(true) } ); // string resourceName = FindResource(); CodeVariableReferenceExpression resourceNameVar = initializeMethod.Statements.DeclareVar( typeof(string), "resourceName", new CodeMethodInvokeExpression() { Method = new CodeMethodReferenceExpression() { MethodName = "FindResource", TargetObject = new CodeThisReferenceExpression(), }, } ); // Stream initializeXaml = typeof(<%= className %>).Assembly.GetManifestResourceStream(resourceName); // CodeVariableReferenceExpression initializeXamlVar = initializeMethod.Statements.DeclareVar( typeof(Stream), "initializeXaml", new CodeMethodInvokeExpression() { Method = new CodeMethodReferenceExpression() { MethodName = "GetManifestResourceStream", TargetObject = new CodePropertyReferenceExpression() { PropertyName = "Assembly", TargetObject = new CodeTypeOfExpression() { Type = new CodeTypeReference(classData.Name) } } }, Parameters = { new CodeVariableReferenceExpression(resourceNameVar.VariableName), } } ); // var reader = new System.Xaml.XamlXmlReader(new System.IO.StreamReader(initializeXaml)); // CodeVariableReferenceExpression xmlReaderVar = initializeMethod.Statements.DeclareVar( typeof(XmlReader), "xmlReader", new CodePrimitiveExpression(null)); CodeVariableReferenceExpression xamlReaderVar = initializeMethod.Statements.DeclareVar( typeof(XamlReader), "reader", new CodePrimitiveExpression(null)); CodeVariableReferenceExpression objWriterVar = initializeMethod.Statements.DeclareVar( typeof(XamlObjectWriter), "objectWriter", new CodePrimitiveExpression(null)); // Enclose in try finally block // This is to call Dispose on the xmlReader in the finally block, which is the CodeDom way of the C# "using" block CodeTryCatchFinallyStatement tryCatchFinally = new CodeTryCatchFinallyStatement(); tryCatchFinally.TryStatements.AddRange(GetInitializeMethodTryStatements(xmlReaderVar, xamlReaderVar, objWriterVar, initializeXamlVar, classData, memberFields)); tryCatchFinally.FinallyStatements.AddRange(GetInitializeMethodFinallyStatements(xmlReaderVar, xamlReaderVar, objWriterVar)); initializeMethod.Statements.Add(tryCatchFinally); return initializeMethod; } CodeStatementCollection GetInitializeMethodTryStatements(CodeExpression xmlReaderVar, CodeExpression xamlReaderVar, CodeExpression objWriterVar, CodeExpression initializeXamlVar, ClassData classData, ListmemberFields) { CodeStatementCollection tryStatements = new CodeStatementCollection(); // System.Xaml.XamlSchemaContext schemaContext = _XamlStaticHelperNamespace._XamlStaticHelper.SchemaContext; CodeVariableReferenceExpression SchemaContextReference = new CodeVariableReferenceExpression(classData.HelperClassFullName + ".SchemaContext"); CodeVariableReferenceExpression SchemaContext = tryStatements.DeclareVar(typeof(XamlSchemaContext), "schemaContext", SchemaContextReference); // xmlReader = System.Xml.XmlReader.Create(initializeXaml); CodeExpression xmlReader = new CodeMethodInvokeExpression( new CodeMethodReferenceExpression() { MethodName = "System.Xml.XmlReader.Create" }, initializeXamlVar); tryStatements.Add(new CodeAssignStatement(xmlReaderVar, xmlReader)); // System.Xaml.XamlXmlReaderSettings readerSettings = new System.Xaml.XamlXmlReaderSettings(); CodeVariableReferenceExpression readerSettingsVar = tryStatements.DeclareVar( typeof(XamlXmlReaderSettings), "readerSettings", typeof(XamlXmlReaderSettings).New()); // readerSettings.LocalAssembly = System.Reflection.Assembly.GetExecutingAssembly(); tryStatements.Add( new CodeAssignStatement( new CodePropertyReferenceExpression(readerSettingsVar, "LocalAssembly"), new CodeMethodInvokeExpression( new CodeMethodReferenceExpression() { MethodName = "System.Reflection.Assembly.GetExecutingAssembly" }))); // readerSettings.AllowProtectedMembersOnRoot = true; tryStatements.Add( new CodeAssignStatement( new CodePropertyReferenceExpression(readerSettingsVar, "AllowProtectedMembersOnRoot"), new CodePrimitiveExpression(true))); // reader = new System.Xaml.XamlXmlReader(xmlReader, schemaContext, readerSettings); CodeExpression newReader = typeof(XamlXmlReader).New(xmlReaderVar, SchemaContext, readerSettingsVar); tryStatements.Add(new CodeAssignStatement(xamlReaderVar, newReader)); // XamlObjectWriterSettings writerSettings = new XamlObjectWriterSettings(); CodeVariableReferenceExpression writerSettingsVar = tryStatements.DeclareVar( typeof(XamlObjectWriterSettings), "writerSettings", typeof(XamlObjectWriterSettings).New()); // writerSettings.RootObjectInstance = this; tryStatements.Add(new CodeAssignStatement() { Left = writerSettingsVar.Property("RootObjectInstance"), Right = CodeThis }); // writerSettings.AccessLevel = System.Xaml.Permissions.XamlAccessLevel.PrivateAccessTo(typeof( )); tryStatements.Add(new CodeAssignStatement() { Left = writerSettingsVar.Property("AccessLevel"), Right = new CodeMethodInvokeExpression( new CodeMethodReferenceExpression() { MethodName = "System.Xaml.Permissions.XamlAccessLevel.PrivateAccessTo" }, new CodeTypeOfExpression(classData.Name) ) }); // var writer = new XamlObjectWriter(schemaContext, settings); // CodeExpression newObjectWriter = typeof(XamlObjectWriter).New(SchemaContext, writerSettingsVar); tryStatements.Add(new CodeAssignStatement(objWriterVar, newObjectWriter)); // XamlServices.Transform(reader, writer); // tryStatements.Add( new CodeMethodInvokeExpression( new CodeMethodReferenceExpression() { MethodName = "System.Xaml.XamlServices.Transform" }, xamlReaderVar, objWriterVar )); // For all fields generated, generate the wireup to get the value from xaml. For eg, for a field of type "Bar" and name "Baz": // Baz = ((Tests.Build.Tasks.Xaml.Bar)(objectWriter.RootNameScope.FindName("Baz"))); if (memberFields != null && memberFields.Count > 0) { foreach (var field in memberFields) { tryStatements.Add( new CodeAssignStatement( new CodeVariableReferenceExpression(field.Name), new CodeCastExpression( field.Type, new CodeMethodInvokeExpression( new CodePropertyReferenceExpression(objWriterVar, "RootNameScope"), "FindName", new CodePrimitiveExpression(field.Name))))); } } return tryStatements; } CodeStatementCollection GetInitializeMethodFinallyStatements(CodeExpression xmlReaderVar, CodeExpression xamlReaderVar, CodeExpression objWriterVar) { CodeStatementCollection finallyStatements = new CodeStatementCollection(); CodeConditionStatement xmlReaderNotNull = new CodeConditionStatement(); xmlReaderNotNull.Condition = new CodeBinaryOperatorExpression(xmlReaderVar, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)); CodeCastExpression iDisposibleCastXmlReader = new CodeCastExpression(typeof(IDisposable), xmlReaderVar); xmlReaderNotNull.TrueStatements.Add(new CodeMethodInvokeExpression(iDisposibleCastXmlReader, "Dispose")); finallyStatements.Add(xmlReaderNotNull); CodeConditionStatement xamlReaderNotNull = new CodeConditionStatement(); xamlReaderNotNull.Condition = new CodeBinaryOperatorExpression(xamlReaderVar, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)); CodeCastExpression iDisposibleCastXamlReader = new CodeCastExpression(typeof(IDisposable), xamlReaderVar); xamlReaderNotNull.TrueStatements.Add(new CodeMethodInvokeExpression(iDisposibleCastXamlReader, "Dispose")); finallyStatements.Add(xamlReaderNotNull); CodeConditionStatement objWriterNotNull = new CodeConditionStatement(); objWriterNotNull.Condition = new CodeBinaryOperatorExpression(objWriterVar, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)); CodeCastExpression iDisposibleCastObjWriter = new CodeCastExpression(typeof(IDisposable), objWriterVar); objWriterNotNull.TrueStatements.Add(new CodeMethodInvokeExpression(iDisposibleCastObjWriter, "Dispose")); finallyStatements.Add(objWriterNotNull); return finallyStatements; } CodeMemberMethod GenerateFindResourceMethod(ClassData classData) { // static string FindResource() { // CodeMemberMethod findResourceMethod = new CodeMemberMethod() { Name = "FindResource", Attributes = MemberAttributes.Private | MemberAttributes.Final, ReturnType = new CodeTypeReference(typeof(string)), }; // string[] resources = typeof(<%= className %>).Assembly.GetManifestResourceNames(); // CodeVariableReferenceExpression resourcesVar = findResourceMethod.Statements.DeclareVar( typeof(string[]), "resources", new CodeMethodInvokeExpression() { Method = new CodeMethodReferenceExpression() { MethodName = "GetManifestResourceNames", TargetObject = new CodePropertyReferenceExpression() { PropertyName = "Assembly", TargetObject = new CodeTypeOfExpression() { Type = new CodeTypeReference(classData.Name) } } }, } ); // for (int i = 0; i < resources.Length; i++) { // string resource = resources[i]; // if (resource.Contains(searchString)) { // return resource; // } // } findResourceMethod.Statements.Add( new CodeIterationStatement() { InitStatement = new CodeVariableDeclarationStatement() { Type = new CodeTypeReference(typeof(int)), Name = "i", InitExpression = new CodePrimitiveExpression(0), }, TestExpression = new CodeBinaryOperatorExpression() { Left = new CodeVariableReferenceExpression("i"), Operator = CodeBinaryOperatorType.LessThan, Right = new CodePropertyReferenceExpression() { TargetObject = new CodeVariableReferenceExpression(resourcesVar.VariableName), PropertyName = "Length", }, }, IncrementStatement = new CodeAssignStatement() { Left = new CodeVariableReferenceExpression("i"), Right = new CodeBinaryOperatorExpression() { Left = new CodeVariableReferenceExpression("i"), Operator = CodeBinaryOperatorType.Add, Right = new CodePrimitiveExpression(1), } }, Statements = { new CodeVariableDeclarationStatement() { Type = new CodeTypeReference(typeof(string)), Name = "resource", InitExpression = new CodeArrayIndexerExpression( new CodeVariableReferenceExpression(resourcesVar.VariableName), new CodeVariableReferenceExpression("i")), }, new CodeConditionStatement() { Condition = new CodeBinaryOperatorExpression() { Left = new CodeMethodInvokeExpression() { Method = new CodeMethodReferenceExpression() { TargetObject = new CodeVariableReferenceExpression("resource"), MethodName = "Contains", }, Parameters = { new CodePrimitiveExpression("." + classData.MarkupFileName), }, }, Operator = CodeBinaryOperatorType.BooleanOr, Right = new CodeMethodInvokeExpression() { Method = new CodeMethodReferenceExpression() { TargetObject = new CodeVariableReferenceExpression("resource"), MethodName = "Equals", }, Parameters = { new CodePrimitiveExpression(classData.MarkupFileName), }, } }, TrueStatements = { new CodeMethodReturnStatement() { Expression = new CodeVariableReferenceExpression("resource"), } } } }, } ); // throw new InvalidOperationException("Resource not found."); // findResourceMethod.Statements.Add( new CodeThrowExceptionStatement() { ToThrow = new CodeObjectCreateExpression() { CreateType = new CodeTypeReference(typeof(InvalidOperationException)), Parameters = { new CodePrimitiveExpression("Resource not found."), } } } ); return findResourceMethod; } CodeTypeMember[] GenerateISupportInitializeImpl(CodeMemberMethod initializeMethod) { CodeTypeReference ifaceType = new CodeTypeReference(typeof(ISupportInitialize)); // Suppress Code Analysis violation errors arising from defining interface methods explicitly. // CodeAttributeArgument[] suppressMessageArguments = { new CodeAttributeArgument(new CodePrimitiveExpression("Microsoft.Design")), new CodeAttributeArgument(new CodePrimitiveExpression("CA1033")) }; CodeAttributeDeclaration suppressMessageDeclaration = new CodeAttributeDeclaration("System.Diagnostics.CodeAnalysis.SuppressMessage", suppressMessageArguments); // void ISupportInitialize.BeginInit() {} // CodeMemberMethod beginMethod = new CodeMemberMethod() { PrivateImplementationType = ifaceType, Name = "BeginInit", }; beginMethod.CustomAttributes.Add(suppressMessageDeclaration); // void ISupportInitialize.EndInit() // { // this.InitializeComponent(); // } // CodeMemberMethod endMethod = new CodeMemberMethod() { PrivateImplementationType = ifaceType, Name = "EndInit", Statements = { CodeThis.Invoke(initializeMethod.Name) }, }; endMethod.CustomAttributes.Add(suppressMessageDeclaration); return new CodeMemberMethod[] { beginMethod, endMethod }; } CodeConstructor GenerateConstructorImpl(CodeMemberMethod initializeMethod) { // <%= className %>() // { // this.InitializeComponent(); // } // CodeConstructor constructor = new CodeConstructor() { Attributes = MemberAttributes.Public, Statements = { CodeThis.Invoke(initializeMethod.Name) } }; return constructor; } CodeTypeMember[] GenerateProperty(PropertyDefinition property, ClassData classData) { // CodeTypeReference propertyCodeType = null; if (!GetCodeTypeReferenceFromXamlType(property.Type, classData, out propertyCodeType)) { throw FxTrace.Exception.AsError( this.buildLogger.LogException( new InvalidOperationException(SR.TaskCannotResolvePropertyType(XamlBuildTaskServices.GetFullTypeName(property.Type), property.Name)), classData.FileName)); } if(!this.codeDomProvider.IsValidIdentifier(property.Name)) { throw FxTrace.Exception.AsError( this.buildLogger.LogException( new InvalidOperationException(SR.InvalidIdentifiers(property.Name)), classData.FileName)); } // private <%= property.Type %> _<%= property.Name %>; // CodeMemberField fieldMember = new CodeMemberField() { Attributes = MemberAttributes.Private, Name = "_" + property.Name, Type = propertyCodeType }; // public <%= property.Type %> <%= property.Name %> { // get { return this._<%= property.Name %>; } // set { this._<%= property.Name %> = value; } // } // CodeMemberProperty propertyMember = new CodeMemberProperty() { Attributes = MemberAttributes.Final, Name = property.Name, Type = propertyCodeType, GetStatements = { new CodeMethodReturnStatement(CodeThis.Field(fieldMember.Name)) }, SetStatements = { new CodeAssignStatement() { Left = CodeThis.Field(fieldMember.Name), Right = new CodeVariableReferenceExpression("value") } } }; propertyMember.Attributes |= GetMemberAttributes(property.Modifier); if (property.Attributes != null && property.Attributes.Count > 0) { CodeAttributeDeclarationCollection attributeCollection = GetAttributeDeclarations(property.Attributes, classData); if (attributeCollection != null && attributeCollection.Count > 0) { propertyMember.CustomAttributes.AddRange(attributeCollection); } } return new CodeTypeMember[] { fieldMember, propertyMember }; } bool GetCodeTypeReferenceFromXamlType(XamlType xamlType, ClassData classData, out CodeTypeReference codeTypeReference) { codeTypeReference = null; string propClrTypeName; bool isLocal = false; if (!XamlBuildTaskServices.TryGetClrTypeName(xamlType, classData.RootNamespace, out propClrTypeName, out isLocal)) { return false; } classData.RequiresCompilationPass2 |= isLocal; codeTypeReference = new CodeTypeReference(propClrTypeName); if (!GetTypeArgumentFromXamlType(codeTypeReference, xamlType, classData)) { return false; } return true; } bool GetTypeArgumentFromXamlType(CodeTypeReference codeTypeReference, XamlType xamlType, ClassData classData) { // // Depending on the name passed into the CodeTypeReference // constructor the type args may already be populated if (codeTypeReference.TypeArguments != null && codeTypeReference.TypeArguments.Count == 0 && xamlType.TypeArguments != null && xamlType.TypeArguments.Count > 0) { foreach (XamlType argumentTypeReference in xamlType.TypeArguments) { CodeTypeReference argumentCodeTypeReference = null; if (!GetCodeTypeReferenceFromXamlType(argumentTypeReference, classData, out argumentCodeTypeReference)) { return false; } codeTypeReference.TypeArguments.Add(argumentCodeTypeReference); } } return true; } [SuppressMessage(FxCop.Category.Globalization, "CA1303", Justification = "Literals are used as comments in generated code.")] private CodeCommentStatement[] GenerateXmlComments(string comment) { // /// // /// <%= comment %> // /// return new CodeCommentStatement[] { new CodeCommentStatement("", true), new CodeCommentStatement(comment, true), new CodeCommentStatement(" ", true) }; } MemberAttributes GetMemberAttributes(string modifier) { if (!string.IsNullOrEmpty(modifier)) { if (string.Equals(modifier, XamlBuildTaskServices.PrivateModifier, StringComparison.OrdinalIgnoreCase)) { return MemberAttributes.Private; } else if (string.Equals(modifier, XamlBuildTaskServices.PublicModifier, StringComparison.OrdinalIgnoreCase)) { return MemberAttributes.Public; } else if (string.Equals(modifier, XamlBuildTaskServices.ProtectedModifier, StringComparison.OrdinalIgnoreCase)) { return MemberAttributes.Family; } else if (string.Equals(modifier, XamlBuildTaskServices.InternalModifier, StringComparison.OrdinalIgnoreCase)) { return MemberAttributes.Assembly; } else if (string.Equals(modifier, XamlBuildTaskServices.ProtectedInternalModifier, StringComparison.OrdinalIgnoreCase)) { return MemberAttributes.FamilyOrAssembly; } else if (string.Equals(modifier, XamlBuildTaskServices.ProtectedAndInternalModifier, StringComparison.OrdinalIgnoreCase)) { return MemberAttributes.FamilyAndAssembly; } else { throw FxTrace.Exception.AsError( this.buildLogger.LogException( new InvalidOperationException(SR.FieldModifierNotSupported(modifier)))); } } return MemberAttributes.Public; } TypeAttributes GetTypeAttributes(string modifier) { if (!string.IsNullOrEmpty(modifier)) { if (string.Equals(modifier, XamlBuildTaskServices.InternalClassModifier, StringComparison.OrdinalIgnoreCase)) { return TypeAttributes.NotPublic; } else if (string.Equals(modifier, XamlBuildTaskServices.PublicClassModifier, StringComparison.OrdinalIgnoreCase)) { return TypeAttributes.Public; } else { throw FxTrace.Exception.AsError( this.buildLogger.LogException( new InvalidOperationException(SR.ClassModifierNotSupported(modifier)))); } } return TypeAttributes.Public; } public CodeCompileUnit GenerateHelperClass(string namespaceName, string className, IListloadedAssemblyList) { CodeCompileUnit result = new CodeCompileUnit(); // Add global namespace CodeNamespace classNamespace = new CodeNamespace(namespaceName); result.Namespaces.Add(classNamespace); CodeTypeDeclaration classDeclaration = GenerateHelperClassBody(className, loadedAssemblyList); classNamespace.Types.Add(classDeclaration); return result; } CodeTypeDeclaration GenerateHelperClassBody(string className, IList loadedAssemblyList) { // <%= visibility%> partial class <%= className %> : <%= type %> // { // } // CodeTypeDeclaration result = new CodeTypeDeclaration() { Name = className, TypeAttributes = TypeAttributes.NotPublic, }; CodeTypeMember[] schemaContextMembers = GenerateSchemaContext(); result.Members.AddRange(schemaContextMembers); CodeTypeMember[] assemblyListMembers = GenerateAssemblyListProperty(); result.Members.AddRange(assemblyListMembers); // Generate helper Loadassembly method to go through all the assemblies and load them result.Members.Add(GenerateLoadAssembliesMethod(loadedAssemblyList)); // Generate helper load to load assemblies correctly result.Members.Add(GenerateLoadMethod()); return result; } CodeTypeMember[] GenerateAssemblyListProperty() { ////Generate the following code: //private static System.Collections.Generic.IList assemblyListField; //internal static System.Collections.Generic.IList AssemblyList { // get { // if ((assemblyListField == null)) { // assemblyListField = LoadAssemblies(); // } // return assemblyListField; // } //} CodeMemberField assemblyListField = new CodeMemberField() { Name = "assemblyListField", Type = new CodeTypeReference(typeof(IList )), Attributes = MemberAttributes.Private | MemberAttributes.Static }; CodeVariableReferenceExpression assemblyList = new CodeVariableReferenceExpression("assemblyListField"); CodeMemberProperty AssemblyList = new CodeMemberProperty() { Name = "AssemblyList", Type = new CodeTypeReference(typeof(IList )), Attributes = MemberAttributes.Assembly | MemberAttributes.Static, }; CodeConditionStatement assemblyListNull = new CodeConditionStatement( new CodeBinaryOperatorExpression(assemblyList, CodeBinaryOperatorType.IdentityEquality, new CodePrimitiveExpression(null)), new CodeAssignStatement(assemblyList, new CodeMethodInvokeExpression { Method = new CodeMethodReferenceExpression { MethodName = "LoadAssemblies" } })); AssemblyList.GetStatements.Add(assemblyListNull); AssemblyList.GetStatements.Add(new CodeMethodReturnStatement(assemblyList)); return new CodeTypeMember[] { assemblyListField, AssemblyList }; } CodeTypeMember[] GenerateSchemaContext() { ////Generate the following code: //private static System.WeakReference schemaContextField; //internal static System.Xaml.XamlSchemaContext SchemaContext { //get { // System.Xaml.XamlSchemaContext xsc = null; // if ((schemaContextField != null)) { // xsc = ((System.Xaml.XamlSchemaContext)(schemaContextField.Target)); // if ((xsc != null)) { // return xsc; // } // } // if ((AssemblyList.Count > 0)) { // xsc = new System.Xaml.XamlSchemaContext(AssemblyList); // } // else { // xsc = new System.Xaml.XamlSchemaContext(); // } // schemaContextField = new System.WeakReference(xsc); // return xsc; //} CodeMemberField schemaContextField = new CodeMemberField() { Name = "schemaContextField", Type = new CodeTypeReference(typeof(WeakReference)), Attributes = MemberAttributes.Private | MemberAttributes.Static, }; CodeVariableReferenceExpression schemaContext = new CodeVariableReferenceExpression("schemaContextField"); CodeMemberProperty SchemaContext = new CodeMemberProperty() { Name = "SchemaContext", Type = new CodeTypeReference(typeof(XamlSchemaContext)), Attributes = MemberAttributes.Assembly | MemberAttributes.Static, }; CodeVariableReferenceExpression xsc = SchemaContext.GetStatements.DeclareVar(typeof(XamlSchemaContext), "xsc", new CodePrimitiveExpression(null)); CodeConditionStatement getSchemaContextIfNotNull = new CodeConditionStatement(); CodeBinaryOperatorExpression schemaContextNotNull = new CodeBinaryOperatorExpression(schemaContext, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)); getSchemaContextIfNotNull.Condition = schemaContextNotNull; CodeAssignStatement assignSchemaContext = new CodeAssignStatement(xsc, new CodeCastExpression(typeof(XamlSchemaContext), new CodePropertyReferenceExpression(schemaContext, "Target"))); CodeConditionStatement xscReturnIfNotNull = new CodeConditionStatement( new CodeBinaryOperatorExpression(xsc, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)), new CodeMethodReturnStatement(xsc)); getSchemaContextIfNotNull.TrueStatements.Add(assignSchemaContext); getSchemaContextIfNotNull.TrueStatements.Add(xscReturnIfNotNull); SchemaContext.GetStatements.Add(getSchemaContextIfNotNull); CodeVariableReferenceExpression AssemblyList = new CodeVariableReferenceExpression("AssemblyList"); CodeConditionStatement initSchemaContext = new CodeConditionStatement(); initSchemaContext.Condition = new CodeBinaryOperatorExpression( new CodePropertyReferenceExpression(AssemblyList, "Count"), CodeBinaryOperatorType.GreaterThan, new CodePrimitiveExpression(0)); initSchemaContext.TrueStatements.Add(new CodeAssignStatement(xsc, typeof(XamlSchemaContext).New(AssemblyList))); initSchemaContext.FalseStatements.Add(new CodeAssignStatement(xsc, typeof(XamlSchemaContext).New())); SchemaContext.GetStatements.Add(initSchemaContext); CodeAssignStatement assignSchemaContextField = new CodeAssignStatement(schemaContext, typeof(WeakReference).New(xsc)); SchemaContext.GetStatements.Add(assignSchemaContextField); SchemaContext.GetStatements.Add(new CodeMethodReturnStatement(xsc)); return new CodeTypeMember[] { schemaContextField, SchemaContext }; } CodeMemberMethod GenerateLoadMethod() { ////Generate the following code: //private static System.Reflection.Assembly Load(string assemblyNameVal) { // System.Reflection.AssemblyName assemblyName = new System.Reflection.AssemblyName(assemblyNameVal); // byte[] publicKeyToken = assemblyName.GetPublicKeyToken(); // System.Reflection.Assembly asm = null; // try { // asm = System.Reflection.Assembly.Load(assemblyName.FullName); // } // catch (System.Exception ) { // System.Reflection.AssemblyName shortName = new System.Reflection.AssemblyName(assemblyName.Name); // if ((publicKeyToken != null)) { // shortName.SetPublicKeyToken(publicKeyToken); // } // asm = System.Reflection.Assembly.Load(shortName); // } // return asm; //} CodeMemberMethod loadMethod = new CodeMemberMethod() { Name = "Load", Attributes = MemberAttributes.Private | MemberAttributes.Static, ReturnType = new CodeTypeReference(typeof(Assembly)) }; loadMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(string), "assemblyNameVal")); CodeVariableReferenceExpression assemblyNameVal = new CodeVariableReferenceExpression("assemblyNameVal"); CodeExpression initAssemblyName = typeof(AssemblyName).New(assemblyNameVal); CodeVariableReferenceExpression assemblyName = loadMethod.Statements.DeclareVar(typeof(AssemblyName), "assemblyName", initAssemblyName); CodeVariableReferenceExpression publicKeyToken = loadMethod.Statements.DeclareVar(typeof(byte[]), "publicKeyToken", new CodeMethodInvokeExpression() { Method = new CodeMethodReferenceExpression() { MethodName = "GetPublicKeyToken", TargetObject = assemblyName, }, } ); CodeVariableReferenceExpression asm = loadMethod.Statements.DeclareVar(typeof(Assembly), "asm", new CodePrimitiveExpression(null)); CodeExpression publicKeyTokenNotNullExp = new CodeBinaryOperatorExpression(publicKeyToken, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)); CodeTryCatchFinallyStatement tryCatchExp = new CodeTryCatchFinallyStatement(); tryCatchExp.TryStatements.Add(new CodeAssignStatement(asm, new CodeMethodInvokeExpression( new CodeMethodReferenceExpression() { MethodName = "System.Reflection.Assembly.Load" }, new CodePropertyReferenceExpression(assemblyName, "FullName") ) )); CodeCatchClause catchClause = new CodeCatchClause(); CodeVariableReferenceExpression shortName = catchClause.Statements.DeclareVar(typeof(AssemblyName), "shortName", typeof(AssemblyName).New(new CodePropertyReferenceExpression(assemblyName, "Name"))); CodeConditionStatement setPublicKeyTokenExp = new CodeConditionStatement(); setPublicKeyTokenExp.Condition = publicKeyTokenNotNullExp; setPublicKeyTokenExp.TrueStatements.Add( new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(shortName, "SetPublicKeyToken"), publicKeyToken) ); catchClause.Statements.Add(setPublicKeyTokenExp); catchClause.Statements.Add(new CodeAssignStatement(asm, new CodeMethodInvokeExpression( new CodeMethodReferenceExpression() { MethodName = "System.Reflection.Assembly.Load" }, shortName ) )); tryCatchExp.CatchClauses.Add(catchClause); loadMethod.Statements.Add(tryCatchExp); loadMethod.Statements.Add(new CodeMethodReturnStatement(asm)); return loadMethod; } CodeMemberMethod GenerateLoadAssembliesMethod(IEnumerable references) { //// Generate the following code: //private static System.Collections.Generic.IList LoadAssemblies() { // System.Collections.Generic.IList assemblyList = new System.Collections.Generic.List (); // // assemblyList.Add(Load(<%= AssemblyFullName %>); // ... // assemblyList.Add(Assembly.GetExecutingAssembly()); // return assemblyList; //} CodeMemberMethod loadAssembliesMethod = new CodeMemberMethod() { Name = "LoadAssemblies", Attributes = MemberAttributes.Private | MemberAttributes.Static, ReturnType = new CodeTypeReference(typeof(IList )), }; CodeVariableReferenceExpression assemblyList = loadAssembliesMethod.Statements.DeclareVar(typeof(IList ), "assemblyList", typeof(List ).New()); foreach (var reference in references) { loadAssembliesMethod.Statements.Add( new CodeMethodInvokeExpression(assemblyList, "Add", new CodeMethodInvokeExpression( new CodeMethodReferenceExpression() { MethodName = "Load" }, new CodePrimitiveExpression(reference.FullName) ) ) ); } loadAssembliesMethod.Statements.Add( new CodeMethodInvokeExpression(assemblyList, "Add", new CodeMethodInvokeExpression( new CodeMethodReferenceExpression() { MethodName = "System.Reflection.Assembly.GetExecutingAssembly" } ) ) ); loadAssembliesMethod.Statements.Add(new CodeMethodReturnStatement(assemblyList)); return loadAssembliesMethod; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- XXXOnTypeBuilderInstantiation.cs
- TextInfo.cs
- SharedPersonalizationStateInfo.cs
- ByteStreamMessageEncoderFactory.cs
- XmlSchemaDatatype.cs
- Schema.cs
- RewritingProcessor.cs
- BindingUtils.cs
- WindowsListViewItemStartMenu.cs
- LinqDataSourceEditData.cs
- XmlTypeAttribute.cs
- CuspData.cs
- COM2ExtendedTypeConverter.cs
- UIServiceHelper.cs
- ConnectionPoolRegistry.cs
- RuntimeWrappedException.cs
- SignalGate.cs
- CompilationUtil.cs
- ClientScriptManager.cs
- DeploymentExceptionMapper.cs
- ServiceDescriptions.cs
- WindowsStatusBar.cs
- XmlStreamStore.cs
- WebPartConnectionsEventArgs.cs
- SqlMethodAttribute.cs
- CompositeDispatchFormatter.cs
- BitmapSource.cs
- controlskin.cs
- AgileSafeNativeMemoryHandle.cs
- BaseUriHelper.cs
- ServiceContractGenerationContext.cs
- TextChange.cs
- FormView.cs
- TypeUsage.cs
- WeakReferenceList.cs
- ChooseAction.cs
- CdpEqualityComparer.cs
- EnumBuilder.cs
- XmlBinaryReader.cs
- ValueUnavailableException.cs
- RealProxy.cs
- SaveFileDialog.cs
- Row.cs
- PersonalizableAttribute.cs
- FileChangesMonitor.cs
- SessionPageStatePersister.cs
- DateTimeParse.cs
- ManagementObjectCollection.cs
- RangeValidator.cs
- SchemeSettingElement.cs
- WebBrowserHelper.cs
- FunctionParameter.cs
- CompoundFileStorageReference.cs
- ExpressionPrefixAttribute.cs
- WinFormsSecurity.cs
- ScriptControlDescriptor.cs
- BasicHttpBindingCollectionElement.cs
- HttpListenerPrefixCollection.cs
- BigInt.cs
- UIElement.cs
- QueryPrefixOp.cs
- DoubleLinkList.cs
- SafeRightsManagementSessionHandle.cs
- _ShellExpression.cs
- MailDefinition.cs
- TextBoxAutomationPeer.cs
- OraclePermission.cs
- ImageDesigner.cs
- BaseTemplateCodeDomTreeGenerator.cs
- StandardCommands.cs
- FileDialog_Vista_Interop.cs
- XmlSignatureManifest.cs
- LayoutSettings.cs
- MatrixTransform3D.cs
- webproxy.cs
- OperationPickerDialog.designer.cs
- WindowsGrip.cs
- ConnectionStringSettings.cs
- Translator.cs
- LOSFormatter.cs
- SqlComparer.cs
- StateMachineDesignerPaint.cs
- Geometry.cs
- XmlDigitalSignatureProcessor.cs
- InteropBitmapSource.cs
- AssociatedControlConverter.cs
- MembershipSection.cs
- TextShapeableCharacters.cs
- Style.cs
- Matrix3DStack.cs
- RegexNode.cs
- ChtmlTextBoxAdapter.cs
- HttpCookie.cs
- AsyncDataRequest.cs
- MetricEntry.cs
- HyperLinkDesigner.cs
- TokenBasedSet.cs
- StaticExtensionConverter.cs
- DataGridViewCellToolTipTextNeededEventArgs.cs
- XamlGridLengthSerializer.cs