private static XamlNode CreateCurrentNode(XamlReader xamlReader, IXamlLineInfo xamlLineInfo) { XamlNode currentNode = new XamlNode { Namespace = xamlReader.Namespace, NodeType = xamlReader.NodeType, Type = xamlReader.Type, Member = xamlReader.Member, Value = xamlReader.Value, LineNumber = xamlLineInfo.LineNumber, LinePosition = xamlLineInfo.LinePosition, }; return(currentNode); }
private void InjectLineInfoXamlNodesToBuffer() { XamlNode startNode = this.objectDeclarationRecords.Pop(); if (!this.SuppressingMarkupExtension() && (startNode.Type != null && !startNode.Type.IsUnknown && !startNode.Type.IsMarkupExtension)) { DocumentLocation myStartBracket = null; DocumentLocation myEndBracket = null; DocumentRange myRange; DocumentLocation myStartLocation = new DocumentLocation(startNode.LineNumber, startNode.LinePosition); if (this.xmlReaderWithSourceLocation.EmptyElementRanges.TryGetValue(myStartLocation, out myRange)) { myStartBracket = myRange.Start; myEndBracket = myRange.End; } else { DocumentLocation myEndLocation = new DocumentLocation(this.Current.LineNumber, this.Current.LinePosition); this.xmlReaderWithSourceLocation.StartElementLocations.TryGetValue(myStartLocation, out myStartBracket); this.xmlReaderWithSourceLocation.EndElementLocations.TryGetValue(myEndLocation, out myEndBracket); } // To enhance visual selection DocumentLocation myRealEndBracket = new DocumentLocation(myEndBracket.LineNumber.Value, myEndBracket.LinePosition.Value + 1); this.bufferedXamlNodes.Clear(); this.InjectLineInfoMembersToBuffer(myStartBracket, myRealEndBracket); DocumentRange valueRange; if (this.initializationValueRanges.TryGetValue(startNode, out valueRange)) { DocumentRange realValueRange = new DocumentRange(valueRange.Start, new DocumentLocation(valueRange.End.LineNumber.Value, valueRange.End.LinePosition.Value + 1)); this.SourceLocationCollector.AddValueRange(new DocumentRange(myStartBracket, myRealEndBracket), realValueRange); } } if (IsMarkupExtension(startNode)) { // Pop a level Fx.Assert(this.suppressMarkupExtensionLevel > 0, "this.suppressMarkupExtensionLevel > 0"); --this.suppressMarkupExtensionLevel; } // We need to make sure we also buffer the current node so that this is not missed when the buffer exhausts. this.bufferedXamlNodes.Enqueue(this.Current); }
internal XamlDebuggerXmlReader(TextReader underlyingTextReader, XamlSchemaContext schemaContext, Assembly localAssembly) { UnitTestUtility.Assert(underlyingTextReader != null, "underlyingTextReader should not be null and is ensured by caller."); this.xmlReaderWithSourceLocation = new XmlReaderWithSourceLocation(underlyingTextReader); this.underlyingReader = new XamlXmlReader(this.xmlReaderWithSourceLocation, schemaContext, new XamlXmlReaderSettings { ProvideLineInfo = true, LocalAssembly = localAssembly }); this.xamlLineInfo = (IXamlLineInfo)this.underlyingReader; UnitTestUtility.Assert(this.xamlLineInfo.HasLineInfo, "underlyingReader is constructed with the ProvideLineInfo option above."); this.schemaContext = schemaContext; this.objectDeclarationRecords = new Stack <XamlNode>(); this.initializationValueRanges = new Dictionary <XamlNode, DocumentRange>(); this.bufferedXamlNodes = new Queue <XamlNode>(); this.current = this.CreateCurrentNode(); this.SourceLocationFound += XamlDebuggerXmlReader.SetSourceLocation; }
public XamlDebuggerXmlReader(XamlReader underlyingReader, IXamlLineInfo xamlLineInfo, TextReader textReader) { this.underlyingReader = underlyingReader; this.xamlLineInfo = xamlLineInfo; this.xmlReaderWithSourceLocation = new XmlReaderWithSourceLocation(textReader); this.initializationValueRanges = new Dictionary <XamlNode, DocumentRange>(); // Parse the XML at once to get all the locations we wanted. while (this.xmlReaderWithSourceLocation.Read()) { } this.schemaContext = underlyingReader.SchemaContext; this.objectDeclarationRecords = new Stack <XamlNode>(); this.bufferedXamlNodes = new Queue <XamlNode>(); this.current = this.CreateCurrentNode(); this.SourceLocationFound += XamlDebuggerXmlReader.SetSourceLocation; }
private static bool IsMarkupExtension(XamlNode node) { Fx.Assert(node != null, "node != null"); return(node.Type != null && node.Type.IsMarkupExtension); }
public override bool Read() { bool readSucceed; if (this.bufferedXamlNodes.Count > 0) { this.Current = this.bufferedXamlNodes.Dequeue(); readSucceed = this.Current != null; } else { readSucceed = this.underlyingReader.Read(); if (readSucceed) { this.Current = CreateCurrentNode(this.underlyingReader, this.xamlLineInfo); this.PushObjectDeclarationNodeIfApplicable(); switch (this.Current.NodeType) { case XamlNodeType.StartMember: // When we reach a StartMember node, the next node to come might be a Value. // To correctly pass SourceLocation information, we need to rewrite this node to use ValueNodeXamlMemberInvoker. // But we don't know if the next node is a Value node yet, so we are buffering here and look ahead for a single node. UnitTestUtility.Assert(this.bufferedXamlNodes.Count == 0, "this.bufferedXamlNodes should be empty when we reach this code path."); this.bufferedXamlNodes.Enqueue(this.Current); // This directive represents the XAML node or XAML information set // representation of initialization text, where a string within an // object element supplies the type construction information for // the surrounding object element. bool isInitializationValue = this.Current.Member == XamlLanguage.Initialization; bool moreNode = this.underlyingReader.Read(); UnitTestUtility.Assert(moreNode, "Start Member must followed by some other nodes."); this.Current = this.CreateCurrentNode(); this.bufferedXamlNodes.Enqueue(this.Current); // It is possible that the next node after StartMember is a StartObject/GetObject. // We need to push the object declaration node to the Stack this.PushObjectDeclarationNodeIfApplicable(); if (!this.SuppressingMarkupExtension() && this.Current.NodeType == XamlNodeType.Value) { DocumentRange valueRange; DocumentLocation currentLocation = new DocumentLocation(this.Current.LineNumber, this.Current.LinePosition); bool isInAttribute = this.xmlReaderWithSourceLocation.AttributeValueRanges.TryGetValue(currentLocation, out valueRange); bool isInContent = isInAttribute ? false : this.xmlReaderWithSourceLocation.ContentValueRanges.TryGetValue(currentLocation, out valueRange); if (isInAttribute || (isInContent && !isInitializationValue)) { // For Value Node with known line info, we want to route the value setting process through this Reader. // Therefore we need to go back to the member node and replace the XamlMemberInvoker. XamlNode startMemberNodeForValue = this.bufferedXamlNodes.Peek(); XamlMember xamlMemberForValue = startMemberNodeForValue.Member; XamlMemberInvoker newXamlMemberInvoker = new ValueNodeXamlMemberInvoker(this, xamlMemberForValue.Invoker, valueRange); startMemberNodeForValue.Member = xamlMemberForValue.ReplaceXamlMemberInvoker(this.schemaContext, newXamlMemberInvoker); } else if (isInContent && isInitializationValue) { XamlNode currentStartObject = this.objectDeclarationRecords.Peek(); if (!this.initializationValueRanges.ContainsKey(currentStartObject)) { this.initializationValueRanges.Add(currentStartObject, valueRange); } else { UnitTestUtility.Assert(false, "I assume it is impossible for an object to have more than one initialization member"); } } } this.StartAccessingBuffer(); break; case XamlNodeType.EndObject: this.InjectLineInfoXamlNodesToBuffer(); this.StartAccessingBuffer(); break; case XamlNodeType.Value: break; default: break; } } } return(readSucceed); }