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;
 }
예제 #2
0
        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);
            }
        }
예제 #3
0
            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;
                }
            }
예제 #4
0
 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;
 }
예제 #5
0
 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>();
        }
예제 #9
0
 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>();
 }
예제 #10
0
            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;
            }
예제 #11
0
 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);
             }
         }
     }
 }
예제 #12
0
 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;
 }
예제 #13
0
        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);
            }
        }
예제 #14
0
 public override object GetValue(object instance)
 {
     UnitTestUtility.Assert(false, "This method should not be called within framework code.");
     return(null);
 }
예제 #15
0
 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;
 }
예제 #16
0
        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);
        }