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
- CompilerErrorCollection.cs
- BitVector32.cs
- Type.cs
- DesignerActionMethodItem.cs
- PathFigureCollection.cs
- QuaternionValueSerializer.cs
- XmlNodeReader.cs
- TrackingProfile.cs
- SynchronizedInputProviderWrapper.cs
- StringValueSerializer.cs
- UncommonField.cs
- FontFamily.cs
- TemplateControlParser.cs
- BaseProcessor.cs
- ListSortDescriptionCollection.cs
- FontConverter.cs
- ToolBar.cs
- _LocalDataStore.cs
- CodeComment.cs
- DesignerSerializerAttribute.cs
- StorageEntityTypeMapping.cs
- CodePrimitiveExpression.cs
- TextSelection.cs
- FormViewRow.cs
- TextBox.cs
- StringCollection.cs
- RowsCopiedEventArgs.cs
- CellConstantDomain.cs
- TemplateControlBuildProvider.cs
- ListBindingHelper.cs
- Vector.cs
- ScrollBarRenderer.cs
- NavigationPropertyEmitter.cs
- DataGridViewTextBoxColumn.cs
- AbsoluteQuery.cs
- CompilationSection.cs
- CmsUtils.cs
- HttpCapabilitiesEvaluator.cs
- Propagator.JoinPropagator.cs
- UrlEncodedParameterWriter.cs
- SapiRecoContext.cs
- ExtendedPropertyInfo.cs
- SelectionProviderWrapper.cs
- DesignerActionVerbList.cs
- ArithmeticLiteral.cs
- BinaryFormatter.cs
- FunctionDescription.cs
- BinaryReader.cs
- CacheChildrenQuery.cs
- SafeNativeMethods.cs
- SamlAssertion.cs
- CodeSubDirectory.cs
- CustomWebEventKey.cs
- TrailingSpaceComparer.cs
- WebServicesInteroperability.cs
- AsyncPostBackTrigger.cs
- RSAPKCS1KeyExchangeFormatter.cs
- RegistryDataKey.cs
- listviewsubitemcollectioneditor.cs
- DependencyPropertyKind.cs
- Point3DCollectionValueSerializer.cs
- IdentifierCollection.cs
- DefaultExpressionVisitor.cs
- XmlRootAttribute.cs
- Stack.cs
- CommonDialog.cs
- WebPageTraceListener.cs
- SqlXml.cs
- GestureRecognizer.cs
- RefExpr.cs
- AsyncPostBackErrorEventArgs.cs
- PresentationAppDomainManager.cs
- IntegerValidatorAttribute.cs
- TaskHelper.cs
- HTTPNotFoundHandler.cs
- SQLMoneyStorage.cs
- IncrementalReadDecoders.cs
- DataGridViewAdvancedBorderStyle.cs
- ResourceCategoryAttribute.cs
- unsafenativemethodstextservices.cs
- TextBoxLine.cs
- UdpChannelFactory.cs
- SQlBooleanStorage.cs
- HostingEnvironmentSection.cs
- WindowsAltTab.cs
- TextHidden.cs
- webbrowsersite.cs
- OdbcDataReader.cs
- XmlCodeExporter.cs
- TableAutomationPeer.cs
- MaskedTextBox.cs
- TriggerActionCollection.cs
- PasswordPropertyTextAttribute.cs
- BoundingRectTracker.cs
- BookmarkTable.cs
- PrintPreviewControl.cs
- GlobalProxySelection.cs
- GetParentChain.cs
- Fault.cs
- DataGridViewRowConverter.cs