public SourceLocationFoundEventArgs(object target, SourceLocation sourceLocation) { UnitTestUtility.Assert(target != null, "Target cannot be null and is ensured by caller"); UnitTestUtility.Assert(sourceLocation != null, "Target cannot be null and is ensured by caller"); this.target = target; this.sourceLocation = sourceLocation; }
internal DocumentLocation FindCharacterStrictlyAfter(char c, DocumentLocation afterLocation) { var locationList = this.GetLocationList(c); UnitTestUtility.Assert(locationList != null, "We should always find character for special characters only"); // Note that this 'nextLocation' may not represent a real document location (we could hit an end line character here so that there is no next line // position. This is merely used for the search algorithm below: var nextLocation = new DocumentLocation(afterLocation.LineNumber, new OneBasedCounter(afterLocation.LinePosition.Value + 1)); var result = locationList.MyBinarySearch(nextLocation); if (result.IsFound) { // It is possible that the next location is a quote itself, or return(nextLocation); } else if (result.IsNextIndexAvailable) { // Some other later position is the quote, or return(locationList[result.NextIndex]); } else { // in the worst case no quote can be found. return(null); } }
public override void SetValue(object instance, object propertyValue) { UnitTestUtility.Assert(propertyValue is int, "The value for this attachable property should be an integer and is ensured by the emitter."); int value = (int)propertyValue; switch (this.sourceLocationMember) { case SourceLocationMemberType.StartLine: this.sourceLocationCollector.OnStartLineFound(instance, value); break; case SourceLocationMemberType.StartColumn: this.sourceLocationCollector.OnStartColumnFound(instance, value); break; case SourceLocationMemberType.EndLine: this.sourceLocationCollector.OnEndLineFound(instance, value); break; case SourceLocationMemberType.EndColumn: this.sourceLocationCollector.OnEndColumnFound(instance, value); break; default: UnitTestUtility.Assert(false, "All possible SourceLocationMember are exhausted."); break; } }
internal DocumentLocation(OneBasedCounter lineNumber, OneBasedCounter linePosition) { UnitTestUtility.Assert(lineNumber != null, "lineNumber should not be null."); UnitTestUtility.Assert(linePosition != null, "linePosition should not be null."); this.lineNumber = lineNumber; this.linePosition = linePosition; }
internal DocumentRange(DocumentLocation start, DocumentLocation end) { UnitTestUtility.Assert(start != null, "DocumentRange.Start cannot be null"); UnitTestUtility.Assert(end != null, "DocumentRange.End cannot be null"); UnitTestUtility.Assert((start.LineNumber.Value < end.LineNumber.Value) || ((start.LineNumber.Value == end.LineNumber.Value) && (start.LinePosition.Value <= end.LinePosition.Value)), "Start cannot before go after End."); this.start = start; this.end = end; }
private DocumentRange FindEmptyElementRange(DocumentLocation elementLocation) { DocumentLocation startBracket = this.FindStartElementBracket(elementLocation); DocumentLocation endBracket = this.FindEndElementBracket(elementLocation); UnitTestUtility.Assert(startBracket != null, "XmlReader should guarantee there must be a start angle bracket."); UnitTestUtility.Assert(endBracket != null, "XmlReader should guarantee there must be an end angle bracket."); DocumentRange emptyElementRange = new DocumentRange(startBracket, endBracket); return(emptyElementRange); }
private DocumentRange FindAttributeValueLocation(DocumentLocation memberLocation) { UnitTestUtility.Assert(this.characterSpottingTextReader != null, "Ensured by constructor."); DocumentLocation attributeStart = this.characterSpottingTextReader.FindCharacterStrictlyAfter(this.QuoteChar, memberLocation); UnitTestUtility.Assert(attributeStart != null, "Read should ensure the two quote characters exists"); DocumentLocation attributeEnd = this.characterSpottingTextReader.FindCharacterStrictlyAfter(this.QuoteChar, attributeStart); UnitTestUtility.Assert(attributeEnd != null, "Read should ensure the two quote characters exists"); return(new DocumentRange(attributeStart, attributeEnd)); }
public XmlReaderWithSourceLocation(TextReader underlyingTextReader) { UnitTestUtility.Assert(underlyingTextReader != null, "CharacterSpottingTextReader cannot be null and should be ensured by caller."); CharacterSpottingTextReader characterSpottingTextReader = new CharacterSpottingTextReader(underlyingTextReader); this.BaseReader = XmlReader.Create(characterSpottingTextReader); UnitTestUtility.Assert(this.BaseReaderAsLineInfo != null, "The XmlReader created by XmlReader.Create should ensure this."); UnitTestUtility.Assert(this.BaseReaderAsLineInfo.HasLineInfo(), "The XmlReader created by XmlReader.Create should ensure this."); this.characterSpottingTextReader = characterSpottingTextReader; this.contentStartLocationStack = new Stack <DocumentLocation>(); }
public CharacterSpottingTextReader(TextReader underlyingReader) { UnitTestUtility.Assert(underlyingReader != null, "underlyingReader should not be null and should be ensured by caller."); this.underlyingReader = underlyingReader; this.currentLine = 1; this.currentPosition = 1; this.startAngleBrackets = new List <DocumentLocation>(); this.endAngleBrackets = new List <DocumentLocation>(); this.singleQuotes = new List <DocumentLocation>(); this.doubleQuotes = new List <DocumentLocation>(); this.endLines = new List <DocumentLocation>(); }
internal void OnEndColumnFound(object instance, int value) { UnitTestUtility.Assert(instance == this.currentObject, "This should be ensured by the XamlSourceLocationObjectReader to emit attachable property in proper order"); this.endColumn = value; // Notify value first to keep the order from "inner to outer". this.NotifyValueIfNeeded(instance); // XamlDebuggerXmlReader has no idea what the filename is (it only knew a stream of data) // So we set FileName = null. this.parent.NotifySourceLocationFound(instance, new SourceLocation(/* FileName = */ null, startLine, startColumn, endLine, endColumn), isValueNode: false); this.currentObject = null; }
internal static XamlMember ReplaceXamlMemberInvoker(this XamlMember originalXamlMember, XamlSchemaContext schemaContext, XamlMemberInvoker newInvoker) { if (originalXamlMember.IsEvent) { if (originalXamlMember.IsAttachable) { UnitTestUtility.Assert(originalXamlMember.UnderlyingMember is MethodInfo, "Guaranteed by XamlMember."); return(new XamlMember(originalXamlMember.Name, originalXamlMember.UnderlyingMember as MethodInfo, schemaContext, newInvoker)); } else { UnitTestUtility.Assert(originalXamlMember.UnderlyingMember is EventInfo, "Guaranteed by XamlMember."); return(new XamlMember(originalXamlMember.UnderlyingMember as EventInfo, schemaContext, newInvoker)); } } else if (originalXamlMember.IsDirective) { return(originalXamlMember); } else if (originalXamlMember.IsUnknown) { return(originalXamlMember); } else { if (originalXamlMember.IsAttachable) { MethodInfo attachablePropertyMethod = originalXamlMember.UnderlyingMember as MethodInfo; if (attachablePropertyMethod.ReturnType == typeof(void)) { return(new XamlMember(originalXamlMember.Name, null, originalXamlMember.UnderlyingMember as MethodInfo, schemaContext, newInvoker)); } else { return(new XamlMember(originalXamlMember.Name, originalXamlMember.UnderlyingMember as MethodInfo, null, schemaContext, newInvoker)); } } else { PropertyInfo propertyInfo = originalXamlMember.UnderlyingMember as PropertyInfo; if (propertyInfo != null) { return(new XamlMember(propertyInfo, schemaContext, newInvoker)); } else { return(originalXamlMember); } } } }
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; }
internal DocumentLocation FindCharacterStrictlyBefore(char c, DocumentLocation documentLocation) { var locationList = this.GetLocationList(c); UnitTestUtility.Assert(locationList != null, "We should always find character for special characters only"); var result = locationList.MyBinarySearch(documentLocation); if (result.IsFound) { if (result.FoundIndex > 0) { return(locationList[result.FoundIndex - 1]); } else { return(null); } } else if (result.IsNextIndexAvailable) { if (result.NextIndex > 0) { return(locationList[result.NextIndex - 1]); } else { return(null); } } else if (locationList.Count > 0) { return(locationList[locationList.Count - 1]); } else { return(null); } }
public override object GetValue(object instance) { UnitTestUtility.Assert(false, "This method should not be called within framework code."); return(null); }
internal void OnEndLineFound(object instance, int value) { UnitTestUtility.Assert(instance == this.currentObject, "This should be ensured by the XamlSourceLocationObjectReader to emit attachable property in proper order"); this.endLine = value; }
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); }
public override bool Read() { bool result = base.Read(); if (this.NodeType == System.Xml.XmlNodeType.Element) { DocumentLocation elementLocation = this.CurrentLocation; if (this.IsEmptyElement) { DocumentRange emptyElementRange = this.FindEmptyElementRange(elementLocation); this.EmptyElementRanges.Add(elementLocation, emptyElementRange); } else { DocumentLocation startElementBracket = this.FindStartElementBracket(elementLocation); this.StartElementLocations.Add(elementLocation, startElementBracket); // Push a null as a place holder. In XmlNodeType.Text part, we replace this // null with real data. Why not pushing real data only without this place holder? // Because in XmlNodeType.EndElement, we need to know whether there is Text. Think // about situation like <a>Text1<b><c>Text2</c></b>Text3</a> // So, each time an Element starts, we push a place holder in the stack so that Start // and End don't mis-match. this.contentStartLocationStack.Push(null); } int attributeCount = this.AttributeCount; if (attributeCount > 0) { for (int i = 0; i < attributeCount; i++) { this.MoveToAttribute(i); DocumentLocation memberLocation = this.CurrentLocation; DocumentRange attributeValueRange = this.FindAttributeValueLocation(memberLocation); this.AttributeValueRanges.Add(memberLocation, attributeValueRange); } this.MoveToElement(); } } else if (this.NodeType == System.Xml.XmlNodeType.EndElement) { DocumentLocation endElementLocation = this.CurrentLocation; DocumentLocation endElementBracket = this.FindEndElementBracket(endElementLocation); this.EndElementLocations.Add(endElementLocation, endElementBracket); UnitTestUtility.Assert( this.contentStartLocationStack.Count > 0, "The stack should contain at least a null we pushed in StartElement."); DocumentLocation contentStartLocation = this.contentStartLocationStack.Pop(); if (contentStartLocation != null) { DocumentLocation contentEnd = this.FindContentEndBefore(endElementLocation); this.ContentValueRanges.Add(endElementLocation, new DocumentRange(contentStartLocation, contentEnd)); } } else if (this.NodeType == System.Xml.XmlNodeType.Text) { UnitTestUtility.Assert(this.contentStartLocationStack.Count > 0, "Adding Text with out StartElement?"); if (this.contentStartLocationStack.Peek() == null) { // no text was added since the last StartElement. // This is the start of the content of this Element. // <a>ABCDE</a> // Sometimes, xml reader gives the text by ABC and DE in // two times. this.contentStartLocationStack.Pop(); this.contentStartLocationStack.Push(this.CurrentLocation); } } return(result); }