// We get here when we are inside x:ClassAttributes or x:Property.Attributes. We expect the first element to be the Attribute SO. internal static AttributeData LoadAttributeData(XamlReader reader, NamespaceTable namespaceTable, string rootNamespace) { AttributeData attributeData = null; reader.Read(); if (reader.NodeType == XamlNodeType.StartObject) { attributeData = new AttributeData { Type = reader.Type }; bool readNext = false; while (readNext || reader.Read()) { namespaceTable.ManageNamespace(reader); readNext = false; if (reader.NodeType == XamlNodeType.StartMember) { if (reader.Member == XamlLanguage.Arguments) { foreach (AttributeParameterData parameterData in ReadParameters(reader.ReadSubtree(), namespaceTable, rootNamespace)) { attributeData.Parameters.Add(parameterData); } readNext = true; } else if (!reader.Member.IsDirective) { KeyValuePair<string, AttributeParameterData> propertyInfo = ReadAttributeProperty(reader.ReadSubtree(), namespaceTable, rootNamespace); attributeData.Properties.Add(propertyInfo.Key, propertyInfo.Value); readNext = true; } } } } return attributeData; }
// We get here when we are inside x:ClassAttributes or x:Property.Attributes. We expect the first element to be the Attribute SO. internal static AttributeData LoadAttributeData(XamlReader reader, NamespaceTable namespaceTable, string rootNamespace) { AttributeData attributeData = null; reader.Read(); if (reader.NodeType == XamlNodeType.StartObject) { attributeData = new AttributeData { Type = reader.Type }; bool readNext = false; while (readNext || reader.Read()) { namespaceTable.ManageNamespace(reader); readNext = false; if (reader.NodeType == XamlNodeType.StartMember) { if (reader.Member == XamlLanguage.Arguments) { foreach (AttributeParameterData parameterData in ReadParameters(reader.ReadSubtree(), namespaceTable, rootNamespace)) { attributeData.Parameters.Add(parameterData); } readNext = true; } else if (!reader.Member.IsDirective) { KeyValuePair <string, AttributeParameterData> propertyInfo = ReadAttributeProperty(reader.ReadSubtree(), namespaceTable, rootNamespace); attributeData.Properties.Add(propertyInfo.Key, propertyInfo.Value); readNext = true; } } } } return(attributeData); }
// 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 <NamedObject> currentTypes = new Stack <NamedObject>(); XamlReader reader = nodes.GetReader(); XamlSchemaContext xsc = reader.SchemaContext; XamlNodeList strippedXamlNodes = new XamlNodeList(xsc); XamlWriter strippedXamlNodesWriter = strippedXamlNodes.Writer; ClassData result = new ClassData() { FileName = this.xamlFileName, IsPublic = this.DefaultClassIsPublic, 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.BaseType == null) { result.BaseType = reader.Type; } currentTypes.Push(new NamedObject() { Type = reader.Type, Visibility = DefaultFieldVisibility, }); 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.Type; 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.EmbeddedResourceXaml = strippedXamlNodes; return(result); }