Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / XamlBuildTask / Microsoft / Build / Tasks / Xaml / ClassImporter.cs / 1305376 / ClassImporter.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace Microsoft.Build.Tasks.Xaml { using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Xaml; using System.Xaml.Schema; using System.ComponentModel; using System.Runtime; using System.Windows.Markup; class ClassImporter { string DefaultClassVisibility; string DefaultFieldVisibility; IExceptionLogger buildLogger; string xamlFileName; string localAssemblyName; string rootNamespace; NamespaceTable namespaceTable; public ClassImporter(IExceptionLogger buildLogger, string xamlFileName, string localAssemblyName, string rootNamespace) { this.buildLogger = buildLogger; this.xamlFileName = xamlFileName; this.localAssemblyName = localAssemblyName; this.rootNamespace = rootNamespace; this.DefaultClassVisibility = XamlBuildTaskServices.PublicClassModifier; this.DefaultFieldVisibility = XamlBuildTaskServices.InternalClassModifier; this.namespaceTable = new NamespaceTable(localAssemblyName); } // Throws InvalidOperationException at DesignTime: Input XAML contains invalid constructs for generating a class. For example, unexpected content or unknown class or field modifiers. public ClassData ReadFromXaml(XamlNodeList nodes) { if (nodes == null) { throw FxTrace.Exception.ArgumentNull("nodeList"); } StackcurrentTypes = new Stack (); XamlReader reader = nodes.GetReader(); XamlSchemaContext xsc = reader.SchemaContext; XamlNodeList strippedXamlNodes = new XamlNodeList(xsc); XamlWriter strippedXamlNodesWriter = strippedXamlNodes.Writer; ClassData result = new ClassData() { FileName = this.xamlFileName, Visibility = DefaultClassVisibility, RootNamespace = this.rootNamespace }; // We loop through the provided XAML; for each node, we do two things: // 1. If it's a directive that's relevant to x:Class, we extract the data. // 2. Unless it's a directive that's exclusively relevant to x:Class, we write it to strippedXamlNodes. // The result is two outputs: class data, and stripped XAML that can be used to initialize the // an instance of the class. bool readNextNode = false; while (readNextNode || reader.Read()) { bool stripNodeFromXaml = false; readNextNode = false; namespaceTable.ManageNamespace(reader); switch (reader.NodeType) { case XamlNodeType.StartObject: if (result.RootTypeName == null) { result.RootTypeName = reader.Type; } currentTypes.Push(new NamedObject() { TypeName = reader.Type, Visibility = DefaultFieldVisibility, TypeArguments = reader.Type.TypeArguments, }); break; case XamlNodeType.EndObject: currentTypes.Pop(); break; case XamlNodeType.StartMember: XamlMember member = reader.Member; if (member.IsDirective) { bool isRootElement = (currentTypes.Count == 1); stripNodeFromXaml = ProcessDirective(reader, result, currentTypes.Peek(), isRootElement, strippedXamlNodes, out readNextNode); } else { NamedObject currentType = currentTypes.Peek(); XamlType currentXamlType = currentType.TypeName; if (currentXamlType.IsUnknown) { result.RequiresCompilationPass2 = true; } } break; case XamlNodeType.EndMember: break; case XamlNodeType.Value: break; case XamlNodeType.NamespaceDeclaration: break; case XamlNodeType.None: break; case XamlNodeType.GetObject: //Push a dummy NamedObject so that it gets popped when you see the corresponding EndObject currentTypes.Push(new NamedObject()); break; default: Debug.Fail("Unrecognized XamlNodeType value" + reader.NodeType.ToString()); break; } if (!stripNodeFromXaml) { WritestrippedXamlNode(reader, strippedXamlNodesWriter); } } // ClassData.Name should be initialized to a non-null non-empty value if // the file contains x:Class. Throw an error if neither is found. if (result.Name == null) { string xClassDirectiveName = "{" + XamlLanguage.Class.PreferredXamlNamespace + "}" + XamlLanguage.Class.Name; throw FxTrace.Exception.AsError(LogInvalidOperationException(null, SR.TaskCannotProcessFileWithoutType(xClassDirectiveName))); } strippedXamlNodes.Writer.Close(); strippedXamlNodes = RewriteRootNode(strippedXamlNodes, result.Name, result.Namespace); result.StrippedXaml = strippedXamlNodes; return result; } IList UpdateTypeArgs(IList typeArgs, XamlSchemaContext xsc) { if (typeArgs != null) { IList updatedTypeArgs = new List (); foreach (var typeArg in typeArgs) { IList typeArgTypeArgs = UpdateTypeArgs(typeArg.TypeArguments, xsc); string typeArgXmlns = XamlBuildTaskServices.UpdateClrNamespaceUriWithLocalAssembly(typeArg.PreferredXamlNamespace, this.localAssemblyName); updatedTypeArgs.Add(new XamlType(typeArgXmlns, typeArg.Name, typeArgTypeArgs, xsc)); } return updatedTypeArgs; } return typeArgs; } void WritestrippedXamlNode(XamlReader reader, XamlWriter writer) { switch (reader.NodeType) { case XamlNodeType.StartObject: XamlType xamlType = reader.Type; if (xamlType.IsUnknown) { IList typeArgs = UpdateTypeArgs(xamlType.TypeArguments, reader.SchemaContext); string xmlns = XamlBuildTaskServices.UpdateClrNamespaceUriWithLocalAssembly(xamlType.PreferredXamlNamespace, this.localAssemblyName); xamlType = new XamlType(xmlns, xamlType.Name, typeArgs, reader.SchemaContext); } writer.WriteStartObject(xamlType); break; case XamlNodeType.StartMember: XamlMember member = reader.Member; if (member.IsUnknown && !member.IsDirective) { string xmlns = XamlBuildTaskServices.UpdateClrNamespaceUriWithLocalAssembly(member.DeclaringType.PreferredXamlNamespace, this.localAssemblyName); XamlType memberXamlType = new XamlType(xmlns, member.DeclaringType.Name, member.DeclaringType.TypeArguments, reader.SchemaContext); member = new XamlMember(member.Name, memberXamlType, member.IsAttachable); } writer.WriteStartMember(member); break; case XamlNodeType.NamespaceDeclaration: NamespaceDeclaration ns = new NamespaceDeclaration( XamlBuildTaskServices.UpdateClrNamespaceUriWithLocalAssembly(reader.Namespace.Namespace, this.localAssemblyName), reader.Namespace.Prefix); writer.WriteNamespace(ns); break; case XamlNodeType.GetObject: case XamlNodeType.EndObject: case XamlNodeType.EndMember: case XamlNodeType.Value: case XamlNodeType.None: writer.WriteNode(reader); break; default: Debug.Fail("Unrecognized XamlNodeType value" + reader.NodeType.ToString()); break; } } XamlNodeList RewriteRootNode(XamlNodeList strippedXamlNodes, string name, string @namespace) { // Rewrite the root node to have the name of class declared via x:Class (rather than the base class) // Also, for any properties on the root object that are declared in this class, need to rewrite the // namespace to include the root namespace, if there is one. string oldNamespace = null; if (!string.IsNullOrEmpty(this.rootNamespace)) { oldNamespace = @namespace; if (!string.IsNullOrEmpty(@namespace)) { @namespace = this.rootNamespace + "." + @namespace; } else { @namespace = this.rootNamespace; } } string namespaceName = string.Format(CultureInfo.InvariantCulture, "{0}{1};{2}{3}", XamlBuildTaskServices.ClrNamespaceUriNamespacePart, @namespace, XamlBuildTaskServices.ClrNamespaceUriAssemblyPart, this.localAssemblyName); XamlReader reader = strippedXamlNodes.GetReader(); XamlSchemaContext xsc = reader.SchemaContext; XamlNodeList newStrippedXamlNodes = new XamlNodeList(xsc); XamlWriter writer = newStrippedXamlNodes.Writer; int depth = 0; XamlType rootXamlType = null; while (reader.Read()) { switch (reader.NodeType) { case XamlNodeType.StartObject: case XamlNodeType.GetObject: depth++; break; case XamlNodeType.EndObject: depth--; break; } if (reader.NodeType == XamlNodeType.StartObject && depth == 1) { rootXamlType = new XamlType(namespaceName, name, null, xsc); writer.WriteStartObject(rootXamlType); } else if (reader.NodeType == XamlNodeType.StartMember && depth == 1 && reader.Member.IsUnknown && reader.Member.DeclaringType != null && reader.Member.DeclaringType.Name == rootXamlType.Name) { string clrNs; XamlMember member = reader.Member; if (XamlBuildTaskServices.TryExtractClrNs(member.PreferredXamlNamespace, out clrNs) && clrNs == oldNamespace) { // This is a member defined on the document root type, but missing the project root namespace. Fix it. XamlMember newMember = new XamlMember(member.Name, rootXamlType, member.IsAttachable); Fx.Assert(rootXamlType != null, "First StartObject should already have been processed"); writer.WriteStartMember(newMember); } else { writer.WriteNode(reader); } } else { writer.WriteNode(reader); } } writer.Close(); return newStrippedXamlNodes; } bool ProcessDirective(XamlReader reader, ClassData classData, NamedObject currentObject, bool isRootElement, XamlNodeList strippedXamlNodes, out bool readNextNode) { Fx.Assert(reader.NodeType == XamlNodeType.StartMember, "Current node should be a Start Member Node"); XamlMember member = reader.Member; bool directiveRecognized = false; readNextNode = false; switch (member.Name) { case "Name": // Unlike all the other directives that we process, x:Name should be written // to the stripped output. strippedXamlNodes.Writer.WriteStartMember(member); string objectName = ReadAtom(reader, XamlLanguage.Name.Name); if (!objectName.StartsWith(XamlBuildTaskServices.SerializerReferenceNamePrefix, StringComparison.Ordinal)) { currentObject.Name = objectName; classData.NamedObjects.Add(currentObject); } strippedXamlNodes.Writer.WriteValue(objectName); strippedXamlNodes.Writer.WriteEndMember(); directiveRecognized = true; break; case "Class": if (isRootElement) { string fullClassName = ReadAtom(reader, XamlLanguage.Class.Name); SetClassName(fullClassName, classData); directiveRecognized = true; } break; case "ClassModifier": if (isRootElement) { classData.Visibility = ReadAtom(reader, XamlLanguage.ClassModifier.Name); directiveRecognized = true; } break; case "FieldModifier": currentObject.Visibility = ReadAtom(reader, XamlLanguage.FieldModifier.Name); directiveRecognized = true; break; case "Code": string codeSnippet = ReadAtom(reader, XamlLanguage.Code.Name); classData.CodeSnippets.Add(codeSnippet); directiveRecognized = true; break; case "TypeArguments": if (isRootElement) { classData.TypeArguments = currentObject.TypeArguments; SkipOneLess(reader); directiveRecognized = true; } break; case "Members": classData.Members = ReadMembersCollection(reader.ReadSubtree()); if (!classData.RequiresCompilationPass2) { foreach (PropertyDefinition property in classData.Members.Values) { if (property.Type.IsUnknown) { classData.RequiresCompilationPass2 = true; break; } } } directiveRecognized = true; readNextNode = true; break; case "ClassAttributes": classData.Attributes = ReadAttributesCollection(reader.ReadSubtree()); directiveRecognized = true; readNextNode = true; break; } if (directiveRecognized == true && readNextNode == false) { reader.Read(); Fx.Assert(reader.NodeType == XamlNodeType.EndMember, "Current node should be a XamlEndmember"); } return directiveRecognized; } private IList ReadAttributesCollection(XamlReader reader) { IList attributes = new List (); bool nextNodeRead = false; while (nextNodeRead || reader.Read()) { this.namespaceTable.ManageNamespace(reader); nextNodeRead = false; if (reader.NodeType == XamlNodeType.StartObject && reader.Type != null) { AttributeData attribute = null; try { attribute = AttributeData.LoadAttributeData(reader.ReadSubtree(), this.namespaceTable, this.rootNamespace); } catch (InvalidOperationException e) { throw FxTrace.Exception.AsError(LogInvalidOperationException(reader, e.Message)); } nextNodeRead = true; attributes.Add(attribute); } } return attributes; } IDictionary ReadMembersCollection(XamlReader reader) { IDictionary members = new Dictionary (); bool nextNodeRead = false; while (nextNodeRead || reader.Read()) { namespaceTable.ManageNamespace(reader); nextNodeRead = false; if (reader.NodeType == XamlNodeType.StartObject) { if (reader.Type == XamlLanguage.Property) { PropertyDefinition xProperty = LoadProperty(reader.ReadSubtree()); nextNodeRead = true; if (members.ContainsKey(xProperty.Name)) { throw FxTrace.Exception.AsError(LogInvalidOperationException(reader, SR.DuplicatePropertyDefinition(xProperty.Name))); } members.Add(xProperty.Name, xProperty); } } } return members; } PropertyDefinition LoadProperty(XamlReader xamlReader) { if (xamlReader == null) { throw FxTrace.Exception.ArgumentNull("xamlReader"); } PropertyDefinition property = new PropertyDefinition(); while (xamlReader.Read()) { if (xamlReader.NodeType == XamlNodeType.StartMember) { XamlMember member = xamlReader.Member; switch(member.Name) { case "Name": property.Name = ReadValueAsString(xamlReader.ReadSubtree()); break; case "Type": property.Type = ReadPropertyType(xamlReader.ReadSubtree()); break; case "Attributes": ((List )property.Attributes).AddRange(ReadAttributesCollection(xamlReader.ReadSubtree())); break; case "Modifier": property.Modifier = ReadValueAsString(xamlReader.ReadSubtree()); break; default: throw FxTrace.Exception.AsError(LogInvalidOperationException(xamlReader, SR.UnknownPropertyMember(member.Name))); } } } if (string.IsNullOrEmpty(property.Name)) { throw FxTrace.Exception.AsError(LogInvalidOperationException(xamlReader, SR.PropertyNameRequired)); } if (property.Type == null) { throw FxTrace.Exception.AsError(LogInvalidOperationException(xamlReader, SR.PropertyTypeRequired(property.Name))); } return property; } XamlType ReadPropertyType(XamlReader xamlReader) { while (xamlReader.Read()) { if (xamlReader.NodeType == XamlNodeType.Value && xamlReader.Value is string) { return XamlBuildTaskServices.GetXamlTypeFromString((string)xamlReader.Value, this.namespaceTable, xamlReader.SchemaContext); } } return null; } string ReadValueAsString(XamlReader xamlReader) { while (xamlReader.Read()) { if (xamlReader.NodeType == XamlNodeType.Value) { return xamlReader.Value as string; } } return string.Empty; } string ReadAtom(XamlReader reader, string propertyName) { reader.Read(); if (reader.NodeType != XamlNodeType.Value) { throw FxTrace.Exception.AsError(LogInvalidOperationException(reader, SR.TextRepresentationExpected(propertyName))); } return (string)reader.Value; } void SetClassName(string fullClassName, ClassData classData) { int lastIndex = fullClassName.LastIndexOf('.'); if (lastIndex != -1) { string classNamespace = fullClassName.Substring(0, lastIndex); string className = fullClassName.Substring(lastIndex + 1); classData.Name = className; classData.Namespace = classNamespace; } else { classData.Name = fullClassName; classData.Namespace = String.Empty; } if (string.IsNullOrEmpty(classData.Name)) { throw FxTrace.Exception.AsError(LogInvalidOperationException(null, SR.ClassNameMustBeNonEmpty)); } } int SkipOneLess(XamlReader reader) { Fx.Assert(reader != null, "reader parameter should never be null"); int nodeCount = 0; if (reader.NodeType == XamlNodeType.Value) { reader.Read(); nodeCount++; return nodeCount; } int depth = 1; while (depth > 0) { if (reader.IsEof) { throw FxTrace.Exception.AsError(LogInvalidOperationException(null, SR.UnexpectedEndOfXaml)); } reader.Read(); nodeCount++; switch (reader.NodeType) { case XamlNodeType.StartMember: case XamlNodeType.StartObject: depth++; break; case XamlNodeType.EndMember: case XamlNodeType.EndObject: depth--; break; } } return nodeCount; } Exception LogInvalidOperationException(XamlReader reader, string exceptionMessage) { IXamlLineInfo lineInfo = reader == null ? null : reader as IXamlLineInfo; if (lineInfo != null && lineInfo.HasLineInfo) { return this.buildLogger.LogException( new InvalidOperationException(exceptionMessage), this.xamlFileName, lineInfo.LineNumber, lineInfo.LinePosition); } else { return this.buildLogger.LogException( new InvalidOperationException(exceptionMessage), this.xamlFileName); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace Microsoft.Build.Tasks.Xaml { using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Xaml; using System.Xaml.Schema; using System.ComponentModel; using System.Runtime; using System.Windows.Markup; class ClassImporter { string DefaultClassVisibility; string DefaultFieldVisibility; IExceptionLogger buildLogger; string xamlFileName; string localAssemblyName; string rootNamespace; NamespaceTable namespaceTable; public ClassImporter(IExceptionLogger buildLogger, string xamlFileName, string localAssemblyName, string rootNamespace) { this.buildLogger = buildLogger; this.xamlFileName = xamlFileName; this.localAssemblyName = localAssemblyName; this.rootNamespace = rootNamespace; this.DefaultClassVisibility = XamlBuildTaskServices.PublicClassModifier; this.DefaultFieldVisibility = XamlBuildTaskServices.InternalClassModifier; this.namespaceTable = new NamespaceTable(localAssemblyName); } // Throws InvalidOperationException at DesignTime: Input XAML contains invalid constructs for generating a class. For example, unexpected content or unknown class or field modifiers. public ClassData ReadFromXaml(XamlNodeList nodes) { if (nodes == null) { throw FxTrace.Exception.ArgumentNull("nodeList"); } Stack currentTypes = new Stack (); XamlReader reader = nodes.GetReader(); XamlSchemaContext xsc = reader.SchemaContext; XamlNodeList strippedXamlNodes = new XamlNodeList(xsc); XamlWriter strippedXamlNodesWriter = strippedXamlNodes.Writer; ClassData result = new ClassData() { FileName = this.xamlFileName, Visibility = DefaultClassVisibility, RootNamespace = this.rootNamespace }; // We loop through the provided XAML; for each node, we do two things: // 1. If it's a directive that's relevant to x:Class, we extract the data. // 2. Unless it's a directive that's exclusively relevant to x:Class, we write it to strippedXamlNodes. // The result is two outputs: class data, and stripped XAML that can be used to initialize the // an instance of the class. bool readNextNode = false; while (readNextNode || reader.Read()) { bool stripNodeFromXaml = false; readNextNode = false; namespaceTable.ManageNamespace(reader); switch (reader.NodeType) { case XamlNodeType.StartObject: if (result.RootTypeName == null) { result.RootTypeName = reader.Type; } currentTypes.Push(new NamedObject() { TypeName = reader.Type, Visibility = DefaultFieldVisibility, TypeArguments = reader.Type.TypeArguments, }); break; case XamlNodeType.EndObject: currentTypes.Pop(); break; case XamlNodeType.StartMember: XamlMember member = reader.Member; if (member.IsDirective) { bool isRootElement = (currentTypes.Count == 1); stripNodeFromXaml = ProcessDirective(reader, result, currentTypes.Peek(), isRootElement, strippedXamlNodes, out readNextNode); } else { NamedObject currentType = currentTypes.Peek(); XamlType currentXamlType = currentType.TypeName; if (currentXamlType.IsUnknown) { result.RequiresCompilationPass2 = true; } } break; case XamlNodeType.EndMember: break; case XamlNodeType.Value: break; case XamlNodeType.NamespaceDeclaration: break; case XamlNodeType.None: break; case XamlNodeType.GetObject: //Push a dummy NamedObject so that it gets popped when you see the corresponding EndObject currentTypes.Push(new NamedObject()); break; default: Debug.Fail("Unrecognized XamlNodeType value" + reader.NodeType.ToString()); break; } if (!stripNodeFromXaml) { WritestrippedXamlNode(reader, strippedXamlNodesWriter); } } // ClassData.Name should be initialized to a non-null non-empty value if // the file contains x:Class. Throw an error if neither is found. if (result.Name == null) { string xClassDirectiveName = "{" + XamlLanguage.Class.PreferredXamlNamespace + "}" + XamlLanguage.Class.Name; throw FxTrace.Exception.AsError(LogInvalidOperationException(null, SR.TaskCannotProcessFileWithoutType(xClassDirectiveName))); } strippedXamlNodes.Writer.Close(); strippedXamlNodes = RewriteRootNode(strippedXamlNodes, result.Name, result.Namespace); result.StrippedXaml = strippedXamlNodes; return result; } IList UpdateTypeArgs(IList typeArgs, XamlSchemaContext xsc) { if (typeArgs != null) { IList updatedTypeArgs = new List (); foreach (var typeArg in typeArgs) { IList typeArgTypeArgs = UpdateTypeArgs(typeArg.TypeArguments, xsc); string typeArgXmlns = XamlBuildTaskServices.UpdateClrNamespaceUriWithLocalAssembly(typeArg.PreferredXamlNamespace, this.localAssemblyName); updatedTypeArgs.Add(new XamlType(typeArgXmlns, typeArg.Name, typeArgTypeArgs, xsc)); } return updatedTypeArgs; } return typeArgs; } void WritestrippedXamlNode(XamlReader reader, XamlWriter writer) { switch (reader.NodeType) { case XamlNodeType.StartObject: XamlType xamlType = reader.Type; if (xamlType.IsUnknown) { IList typeArgs = UpdateTypeArgs(xamlType.TypeArguments, reader.SchemaContext); string xmlns = XamlBuildTaskServices.UpdateClrNamespaceUriWithLocalAssembly(xamlType.PreferredXamlNamespace, this.localAssemblyName); xamlType = new XamlType(xmlns, xamlType.Name, typeArgs, reader.SchemaContext); } writer.WriteStartObject(xamlType); break; case XamlNodeType.StartMember: XamlMember member = reader.Member; if (member.IsUnknown && !member.IsDirective) { string xmlns = XamlBuildTaskServices.UpdateClrNamespaceUriWithLocalAssembly(member.DeclaringType.PreferredXamlNamespace, this.localAssemblyName); XamlType memberXamlType = new XamlType(xmlns, member.DeclaringType.Name, member.DeclaringType.TypeArguments, reader.SchemaContext); member = new XamlMember(member.Name, memberXamlType, member.IsAttachable); } writer.WriteStartMember(member); break; case XamlNodeType.NamespaceDeclaration: NamespaceDeclaration ns = new NamespaceDeclaration( XamlBuildTaskServices.UpdateClrNamespaceUriWithLocalAssembly(reader.Namespace.Namespace, this.localAssemblyName), reader.Namespace.Prefix); writer.WriteNamespace(ns); break; case XamlNodeType.GetObject: case XamlNodeType.EndObject: case XamlNodeType.EndMember: case XamlNodeType.Value: case XamlNodeType.None: writer.WriteNode(reader); break; default: Debug.Fail("Unrecognized XamlNodeType value" + reader.NodeType.ToString()); break; } } XamlNodeList RewriteRootNode(XamlNodeList strippedXamlNodes, string name, string @namespace) { // Rewrite the root node to have the name of class declared via x:Class (rather than the base class) // Also, for any properties on the root object that are declared in this class, need to rewrite the // namespace to include the root namespace, if there is one. string oldNamespace = null; if (!string.IsNullOrEmpty(this.rootNamespace)) { oldNamespace = @namespace; if (!string.IsNullOrEmpty(@namespace)) { @namespace = this.rootNamespace + "." + @namespace; } else { @namespace = this.rootNamespace; } } string namespaceName = string.Format(CultureInfo.InvariantCulture, "{0}{1};{2}{3}", XamlBuildTaskServices.ClrNamespaceUriNamespacePart, @namespace, XamlBuildTaskServices.ClrNamespaceUriAssemblyPart, this.localAssemblyName); XamlReader reader = strippedXamlNodes.GetReader(); XamlSchemaContext xsc = reader.SchemaContext; XamlNodeList newStrippedXamlNodes = new XamlNodeList(xsc); XamlWriter writer = newStrippedXamlNodes.Writer; int depth = 0; XamlType rootXamlType = null; while (reader.Read()) { switch (reader.NodeType) { case XamlNodeType.StartObject: case XamlNodeType.GetObject: depth++; break; case XamlNodeType.EndObject: depth--; break; } if (reader.NodeType == XamlNodeType.StartObject && depth == 1) { rootXamlType = new XamlType(namespaceName, name, null, xsc); writer.WriteStartObject(rootXamlType); } else if (reader.NodeType == XamlNodeType.StartMember && depth == 1 && reader.Member.IsUnknown && reader.Member.DeclaringType != null && reader.Member.DeclaringType.Name == rootXamlType.Name) { string clrNs; XamlMember member = reader.Member; if (XamlBuildTaskServices.TryExtractClrNs(member.PreferredXamlNamespace, out clrNs) && clrNs == oldNamespace) { // This is a member defined on the document root type, but missing the project root namespace. Fix it. XamlMember newMember = new XamlMember(member.Name, rootXamlType, member.IsAttachable); Fx.Assert(rootXamlType != null, "First StartObject should already have been processed"); writer.WriteStartMember(newMember); } else { writer.WriteNode(reader); } } else { writer.WriteNode(reader); } } writer.Close(); return newStrippedXamlNodes; } bool ProcessDirective(XamlReader reader, ClassData classData, NamedObject currentObject, bool isRootElement, XamlNodeList strippedXamlNodes, out bool readNextNode) { Fx.Assert(reader.NodeType == XamlNodeType.StartMember, "Current node should be a Start Member Node"); XamlMember member = reader.Member; bool directiveRecognized = false; readNextNode = false; switch (member.Name) { case "Name": // Unlike all the other directives that we process, x:Name should be written // to the stripped output. strippedXamlNodes.Writer.WriteStartMember(member); string objectName = ReadAtom(reader, XamlLanguage.Name.Name); if (!objectName.StartsWith(XamlBuildTaskServices.SerializerReferenceNamePrefix, StringComparison.Ordinal)) { currentObject.Name = objectName; classData.NamedObjects.Add(currentObject); } strippedXamlNodes.Writer.WriteValue(objectName); strippedXamlNodes.Writer.WriteEndMember(); directiveRecognized = true; break; case "Class": if (isRootElement) { string fullClassName = ReadAtom(reader, XamlLanguage.Class.Name); SetClassName(fullClassName, classData); directiveRecognized = true; } break; case "ClassModifier": if (isRootElement) { classData.Visibility = ReadAtom(reader, XamlLanguage.ClassModifier.Name); directiveRecognized = true; } break; case "FieldModifier": currentObject.Visibility = ReadAtom(reader, XamlLanguage.FieldModifier.Name); directiveRecognized = true; break; case "Code": string codeSnippet = ReadAtom(reader, XamlLanguage.Code.Name); classData.CodeSnippets.Add(codeSnippet); directiveRecognized = true; break; case "TypeArguments": if (isRootElement) { classData.TypeArguments = currentObject.TypeArguments; SkipOneLess(reader); directiveRecognized = true; } break; case "Members": classData.Members = ReadMembersCollection(reader.ReadSubtree()); if (!classData.RequiresCompilationPass2) { foreach (PropertyDefinition property in classData.Members.Values) { if (property.Type.IsUnknown) { classData.RequiresCompilationPass2 = true; break; } } } directiveRecognized = true; readNextNode = true; break; case "ClassAttributes": classData.Attributes = ReadAttributesCollection(reader.ReadSubtree()); directiveRecognized = true; readNextNode = true; break; } if (directiveRecognized == true && readNextNode == false) { reader.Read(); Fx.Assert(reader.NodeType == XamlNodeType.EndMember, "Current node should be a XamlEndmember"); } return directiveRecognized; } private IList ReadAttributesCollection(XamlReader reader) { IList attributes = new List (); bool nextNodeRead = false; while (nextNodeRead || reader.Read()) { this.namespaceTable.ManageNamespace(reader); nextNodeRead = false; if (reader.NodeType == XamlNodeType.StartObject && reader.Type != null) { AttributeData attribute = null; try { attribute = AttributeData.LoadAttributeData(reader.ReadSubtree(), this.namespaceTable, this.rootNamespace); } catch (InvalidOperationException e) { throw FxTrace.Exception.AsError(LogInvalidOperationException(reader, e.Message)); } nextNodeRead = true; attributes.Add(attribute); } } return attributes; } IDictionary ReadMembersCollection(XamlReader reader) { IDictionary members = new Dictionary (); bool nextNodeRead = false; while (nextNodeRead || reader.Read()) { namespaceTable.ManageNamespace(reader); nextNodeRead = false; if (reader.NodeType == XamlNodeType.StartObject) { if (reader.Type == XamlLanguage.Property) { PropertyDefinition xProperty = LoadProperty(reader.ReadSubtree()); nextNodeRead = true; if (members.ContainsKey(xProperty.Name)) { throw FxTrace.Exception.AsError(LogInvalidOperationException(reader, SR.DuplicatePropertyDefinition(xProperty.Name))); } members.Add(xProperty.Name, xProperty); } } } return members; } PropertyDefinition LoadProperty(XamlReader xamlReader) { if (xamlReader == null) { throw FxTrace.Exception.ArgumentNull("xamlReader"); } PropertyDefinition property = new PropertyDefinition(); while (xamlReader.Read()) { if (xamlReader.NodeType == XamlNodeType.StartMember) { XamlMember member = xamlReader.Member; switch(member.Name) { case "Name": property.Name = ReadValueAsString(xamlReader.ReadSubtree()); break; case "Type": property.Type = ReadPropertyType(xamlReader.ReadSubtree()); break; case "Attributes": ((List )property.Attributes).AddRange(ReadAttributesCollection(xamlReader.ReadSubtree())); break; case "Modifier": property.Modifier = ReadValueAsString(xamlReader.ReadSubtree()); break; default: throw FxTrace.Exception.AsError(LogInvalidOperationException(xamlReader, SR.UnknownPropertyMember(member.Name))); } } } if (string.IsNullOrEmpty(property.Name)) { throw FxTrace.Exception.AsError(LogInvalidOperationException(xamlReader, SR.PropertyNameRequired)); } if (property.Type == null) { throw FxTrace.Exception.AsError(LogInvalidOperationException(xamlReader, SR.PropertyTypeRequired(property.Name))); } return property; } XamlType ReadPropertyType(XamlReader xamlReader) { while (xamlReader.Read()) { if (xamlReader.NodeType == XamlNodeType.Value && xamlReader.Value is string) { return XamlBuildTaskServices.GetXamlTypeFromString((string)xamlReader.Value, this.namespaceTable, xamlReader.SchemaContext); } } return null; } string ReadValueAsString(XamlReader xamlReader) { while (xamlReader.Read()) { if (xamlReader.NodeType == XamlNodeType.Value) { return xamlReader.Value as string; } } return string.Empty; } string ReadAtom(XamlReader reader, string propertyName) { reader.Read(); if (reader.NodeType != XamlNodeType.Value) { throw FxTrace.Exception.AsError(LogInvalidOperationException(reader, SR.TextRepresentationExpected(propertyName))); } return (string)reader.Value; } void SetClassName(string fullClassName, ClassData classData) { int lastIndex = fullClassName.LastIndexOf('.'); if (lastIndex != -1) { string classNamespace = fullClassName.Substring(0, lastIndex); string className = fullClassName.Substring(lastIndex + 1); classData.Name = className; classData.Namespace = classNamespace; } else { classData.Name = fullClassName; classData.Namespace = String.Empty; } if (string.IsNullOrEmpty(classData.Name)) { throw FxTrace.Exception.AsError(LogInvalidOperationException(null, SR.ClassNameMustBeNonEmpty)); } } int SkipOneLess(XamlReader reader) { Fx.Assert(reader != null, "reader parameter should never be null"); int nodeCount = 0; if (reader.NodeType == XamlNodeType.Value) { reader.Read(); nodeCount++; return nodeCount; } int depth = 1; while (depth > 0) { if (reader.IsEof) { throw FxTrace.Exception.AsError(LogInvalidOperationException(null, SR.UnexpectedEndOfXaml)); } reader.Read(); nodeCount++; switch (reader.NodeType) { case XamlNodeType.StartMember: case XamlNodeType.StartObject: depth++; break; case XamlNodeType.EndMember: case XamlNodeType.EndObject: depth--; break; } } return nodeCount; } Exception LogInvalidOperationException(XamlReader reader, string exceptionMessage) { IXamlLineInfo lineInfo = reader == null ? null : reader as IXamlLineInfo; if (lineInfo != null && lineInfo.HasLineInfo) { return this.buildLogger.LogException( new InvalidOperationException(exceptionMessage), this.xamlFileName, lineInfo.LineNumber, lineInfo.LinePosition); } else { return this.buildLogger.LogException( new InvalidOperationException(exceptionMessage), this.xamlFileName); } } } } // 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
- TabletCollection.cs
- HwndSource.cs
- HttpRuntimeSection.cs
- SharedPerformanceCounter.cs
- AttachedPropertyDescriptor.cs
- IISMapPath.cs
- ScrollBar.cs
- MemoryStream.cs
- AndCondition.cs
- OneToOneMappingSerializer.cs
- EmptyEnumerable.cs
- DataGridViewCellValidatingEventArgs.cs
- ProxyFragment.cs
- BoundingRectTracker.cs
- Message.cs
- RootBuilder.cs
- WebPartEventArgs.cs
- TraceSource.cs
- SafeFileHandle.cs
- TemplateControlCodeDomTreeGenerator.cs
- PathSegmentCollection.cs
- StateChangeEvent.cs
- ColorConvertedBitmapExtension.cs
- StorageMappingItemCollection.cs
- XmlChildNodes.cs
- DiscoveryOperationContextExtension.cs
- ExpandoClass.cs
- XmlQueryContext.cs
- RayHitTestParameters.cs
- HitTestWithPointDrawingContextWalker.cs
- TransformationRules.cs
- RegexMatchCollection.cs
- LifetimeServices.cs
- Pair.cs
- BindingEntityInfo.cs
- HttpCookie.cs
- XmlSchemaAny.cs
- InstancePersistence.cs
- SafeReversePInvokeHandle.cs
- CheckBoxAutomationPeer.cs
- ExceptionRoutedEventArgs.cs
- XmlIlVisitor.cs
- BrowserTree.cs
- CryptoConfig.cs
- TypeConvertions.cs
- SimpleApplicationHost.cs
- Color.cs
- SoundPlayerAction.cs
- BindingGroup.cs
- WhitespaceRuleLookup.cs
- ImageListUtils.cs
- Int64AnimationUsingKeyFrames.cs
- _Events.cs
- metadatamappinghashervisitor.hashsourcebuilder.cs
- ListViewInsertedEventArgs.cs
- Object.cs
- AuthorizationRuleCollection.cs
- TypeReference.cs
- TemplateControl.cs
- SecurityTokenException.cs
- TreeViewHitTestInfo.cs
- LinqDataSourceDeleteEventArgs.cs
- OledbConnectionStringbuilder.cs
- MarkupCompilePass2.cs
- CompositeCollection.cs
- CultureInfoConverter.cs
- CapabilitiesPattern.cs
- RegistryKey.cs
- BindingEntityInfo.cs
- TriState.cs
- RegionData.cs
- UserControl.cs
- CertificateManager.cs
- LoginUtil.cs
- IncrementalCompileAnalyzer.cs
- ElementMarkupObject.cs
- base64Transforms.cs
- CheckedPointers.cs
- RelatedPropertyManager.cs
- HttpModuleAction.cs
- BuildResultCache.cs
- SqlDelegatedTransaction.cs
- ObjectHandle.cs
- DataTableNewRowEvent.cs
- CodeIterationStatement.cs
- CatalogZone.cs
- UserControlBuildProvider.cs
- MemoryStream.cs
- String.cs
- MarkupProperty.cs
- BulletedListEventArgs.cs
- EditorZone.cs
- InstanceKeyNotReadyException.cs
- BevelBitmapEffect.cs
- DragStartedEventArgs.cs
- TimerElapsedEvenArgs.cs
- WorkflowDefinitionContext.cs
- MiniModule.cs
- ServiceEndpoint.cs
- CssClassPropertyAttribute.cs