Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/xamarin/NRefactory.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Grunwald <daniel@danielgrunwald.de>2012-02-22 22:37:39 +0400
committerDaniel Grunwald <daniel@danielgrunwald.de>2012-02-23 18:39:42 +0400
commitdef994306351ce70f5e15dc04ca73cc8d6f6ecad (patch)
tree6dbed5faf981be1c11177235c79842f48dcc643a /ICSharpCode.NRefactory.Xml
parent2c7c1c7ee7f0e4bbde8ee319f189538489014955 (diff)
Add AXmlObject.CreateReader() method.
Diffstat (limited to 'ICSharpCode.NRefactory.Xml')
-rw-r--r--ICSharpCode.NRefactory.Xml/AXmlDocument.cs13
-rw-r--r--ICSharpCode.NRefactory.Xml/AXmlElement.cs8
-rw-r--r--ICSharpCode.NRefactory.Xml/AXmlObject.cs38
-rw-r--r--ICSharpCode.NRefactory.Xml/AXmlReader.cs339
-rw-r--r--ICSharpCode.NRefactory.Xml/ICSharpCode.NRefactory.Xml.csproj1
-rw-r--r--ICSharpCode.NRefactory.Xml/InternalDocument.cs18
-rw-r--r--ICSharpCode.NRefactory.Xml/ObjectIterator.cs26
-rw-r--r--ICSharpCode.NRefactory.Xml/TagMatchingHeuristics.cs2
-rw-r--r--ICSharpCode.NRefactory.Xml/TagReader.cs162
9 files changed, 494 insertions, 113 deletions
diff --git a/ICSharpCode.NRefactory.Xml/AXmlDocument.cs b/ICSharpCode.NRefactory.Xml/AXmlDocument.cs
index 90b54714..64ec7b04 100644
--- a/ICSharpCode.NRefactory.Xml/AXmlDocument.cs
+++ b/ICSharpCode.NRefactory.Xml/AXmlDocument.cs
@@ -18,6 +18,7 @@
using System;
using System.Globalization;
+using System.Xml;
namespace ICSharpCode.NRefactory.Xml
{
@@ -32,6 +33,18 @@ namespace ICSharpCode.NRefactory.Xml
}
/// <inheritdoc/>
+ public override XmlReader CreateReader()
+ {
+ return new AXmlReader(internalObject.NestedObjects);
+ }
+
+ /// <inheritdoc/>
+ public override XmlReader CreateReader(Func<int, TextLocation> offsetToTextLocation)
+ {
+ return new AXmlReader(internalObject.NestedObjects, startOffset, offsetToTextLocation);
+ }
+
+ /// <inheritdoc/>
public override void AcceptVisitor(IAXmlVisitor visitor)
{
visitor.VisitDocument(this);
diff --git a/ICSharpCode.NRefactory.Xml/AXmlElement.cs b/ICSharpCode.NRefactory.Xml/AXmlElement.cs
index 9a8dfb19..44954225 100644
--- a/ICSharpCode.NRefactory.Xml/AXmlElement.cs
+++ b/ICSharpCode.NRefactory.Xml/AXmlElement.cs
@@ -90,17 +90,13 @@ namespace ICSharpCode.NRefactory.Xml
/// <summary> The part of name before ":" </summary>
/// <returns> Empty string if not found </returns>
public string Prefix {
- get {
- return GetNamespacePrefix(this.Name);
- }
+ get { return ((InternalElement)internalObject).Prefix; }
}
/// <summary> The part of name after ":" </summary>
/// <returns> Empty string if not found </returns>
public string LocalName {
- get {
- return GetLocalName(this.Name);
- }
+ get { return ((InternalElement)internalObject).LocalName; }
}
/// <summary> Resolved namespace of the name </summary>
diff --git a/ICSharpCode.NRefactory.Xml/AXmlObject.cs b/ICSharpCode.NRefactory.Xml/AXmlObject.cs
index 49e99273..94cc605e 100644
--- a/ICSharpCode.NRefactory.Xml/AXmlObject.cs
+++ b/ICSharpCode.NRefactory.Xml/AXmlObject.cs
@@ -19,6 +19,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Xml;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.Utils;
@@ -51,6 +52,22 @@ namespace ICSharpCode.NRefactory.Xml
}
/// <summary>
+ /// Creates an XML reader that reads from this document.
+ /// </summary>
+ public virtual XmlReader CreateReader()
+ {
+ return new AXmlReader(new[] { internalObject });
+ }
+
+ /// <summary>
+ /// Creates an XML reader that reads from this document.
+ /// </summary>
+ public virtual XmlReader CreateReader(Func<int, TextLocation> offsetToTextLocation)
+ {
+ return new AXmlReader(new[] { internalObject }, startOffset, offsetToTextLocation);
+ }
+
+ /// <summary>
/// Gets the parent node.
/// </summary>
public AXmlObject Parent {
@@ -82,6 +99,23 @@ namespace ICSharpCode.NRefactory.Xml
}
/// <summary>
+ /// Gets a child fully containg the given offset.
+ /// Goes recursively down the tree.
+ /// Specail case if at the end of attribute or text
+ /// </summary>
+ public AXmlObject GetChildAtOffset(int offset)
+ {
+ foreach(AXmlObject child in this.Children) {
+ if (offset == child.EndOffset && (child is AXmlAttribute || child is AXmlText))
+ return child;
+ if (child.StartOffset < offset && offset < child.EndOffset) {
+ return child.GetChildAtOffset(offset);
+ }
+ }
+ return this; // No childs at offset
+ }
+
+ /// <summary>
/// The error that occured in the context of this node (excluding nested nodes)
/// </summary>
public IEnumerable<SyntaxError> MySyntaxErrors {
@@ -119,7 +153,7 @@ namespace ICSharpCode.NRefactory.Xml
/// <summary> The part of name before ":" </summary>
/// <returns> Empty string if not found </returns>
- protected static string GetNamespacePrefix(string name)
+ internal static string GetNamespacePrefix(string name)
{
if (string.IsNullOrEmpty(name)) return string.Empty;
int colonIndex = name.IndexOf(':');
@@ -132,7 +166,7 @@ namespace ICSharpCode.NRefactory.Xml
/// <summary> The part of name after ":" </summary>
/// <returns> Whole name if ":" not found </returns>
- protected static string GetLocalName(string name)
+ internal static string GetLocalName(string name)
{
if (string.IsNullOrEmpty(name)) return string.Empty;
int colonIndex = name.IndexOf(':');
diff --git a/ICSharpCode.NRefactory.Xml/AXmlReader.cs b/ICSharpCode.NRefactory.Xml/AXmlReader.cs
new file mode 100644
index 00000000..af4bf406
--- /dev/null
+++ b/ICSharpCode.NRefactory.Xml/AXmlReader.cs
@@ -0,0 +1,339 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this
+// software and associated documentation files (the "Software"), to deal in the Software
+// without restriction, including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
+// to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or
+// substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Xml;
+
+namespace ICSharpCode.NRefactory.Xml
+{
+ /// <summary>
+ /// XmlReader implementation that reads from an <see cref="AXmlDocument"/>.
+ /// </summary>
+ sealed class AXmlReader : XmlReader, IXmlLineInfo
+ {
+ readonly ObjectIterator objectIterator;
+ readonly Func<int, TextLocation> offsetToTextLocation;
+ readonly XmlNameTable nameTable = new NameTable();
+ ReadState readState = ReadState.Initial;
+ XmlNodeType elementNodeType = XmlNodeType.None;
+ IList<InternalAttribute> attributes;
+ int attributeIndex = -1;
+ bool inAttributeValue;
+
+ internal AXmlReader(InternalObject[] objects, int startPosition = 0, Func<int, TextLocation> offsetToTextLocation = null)
+ {
+ this.offsetToTextLocation = offsetToTextLocation;
+ objectIterator = new ObjectIterator(objects, startPosition);
+ objectIterator.StopAtElementEnd = true;
+ }
+
+ public override void ResolveEntity()
+ {
+ throw new NotSupportedException();
+ }
+
+ public override ReadState ReadState {
+ get { return readState; }
+ }
+
+ public override bool ReadAttributeValue()
+ {
+ if (attributeIndex >= 0 && !inAttributeValue) {
+ inAttributeValue = true;
+ return true;
+ }
+ return false;
+ }
+
+ public override bool Read()
+ {
+ switch (readState) {
+ case ReadState.Initial:
+ readState = ReadState.Interactive;
+ return ReadCurrentPosition();
+ case ReadState.Interactive:
+ objectIterator.MoveInto();
+ return ReadCurrentPosition();
+ default:
+ return false;
+ }
+ }
+
+ bool ReadCurrentPosition()
+ {
+ attributes = null;
+ attributeIndex = -1;
+ inAttributeValue = false;
+ while (true) {
+ var obj = objectIterator.CurrentObject;
+ if (obj == null) {
+ readState = ReadState.EndOfFile;
+ elementNodeType = XmlNodeType.None;
+ return false;
+ } else if (objectIterator.IsAtElementEnd) {
+ elementNodeType = XmlNodeType.EndElement;
+ return true;
+ } else if (obj is InternalElement) {
+ // element start
+ elementNodeType = XmlNodeType.Element;
+ InternalTag startTag = ((InternalTag)obj.NestedObjects[0]);
+ if (startTag.NestedObjects != null)
+ attributes = startTag.NestedObjects.OfType<InternalAttribute>().ToList();
+ return true;
+ } else if (obj is InternalText) {
+ InternalText text = (InternalText)obj;
+ if (text.ContainsOnlyWhitespace) {
+ elementNodeType = XmlNodeType.Whitespace;
+ } else {
+ elementNodeType = XmlNodeType.Text;
+ }
+ return true;
+ } else if (obj is InternalTag) {
+ // start/end tags can be skipped as the parent InternalElement already handles them,
+ // TODO all other tags (xml decl, comments, ...)
+ } else {
+ throw new NotSupportedException();
+ }
+ objectIterator.MoveInto();
+ }
+ }
+
+ public override void Skip()
+ {
+ if (readState == ReadState.Interactive) {
+ MoveToElement();
+ objectIterator.MoveNext();
+ ReadCurrentPosition();
+ }
+ }
+
+ public override string Prefix {
+ get {
+ if (readState != ReadState.Interactive)
+ return string.Empty;
+ if (attributeIndex >= 0) {
+ if (inAttributeValue)
+ return string.Empty;
+ return nameTable.Add(AXmlObject.GetNamespacePrefix(attributes[attributeIndex].Name));
+ }
+ InternalElement element = objectIterator.CurrentObject as InternalElement;
+ return element != null ? nameTable.Add(element.Prefix) : string.Empty;
+ }
+ }
+
+ public override string NamespaceURI {
+ get {
+ if (readState != ReadState.Interactive)
+ return string.Empty;
+ return LookupNamespace(this.Prefix);
+ }
+ }
+
+ public override string LocalName {
+ get {
+ if (readState != ReadState.Interactive)
+ return string.Empty;
+ if (attributeIndex >= 0) {
+ if (inAttributeValue)
+ return string.Empty;
+ return nameTable.Add(AXmlObject.GetLocalName(attributes[attributeIndex].Name));
+ }
+ InternalElement element = objectIterator.CurrentObject as InternalElement;
+ return element != null ? nameTable.Add(element.LocalName) : string.Empty;
+ }
+ }
+
+ public override bool IsEmptyElement {
+ get {
+ if (readState != ReadState.Interactive)
+ return false;
+ InternalElement element = objectIterator.CurrentObject as InternalElement;
+ return element != null && element.NestedObjects.Length == 1;
+ }
+ }
+
+ public override string Value {
+ get {
+ if (readState != ReadState.Interactive)
+ return string.Empty;
+ if (attributeIndex >= 0)
+ return attributes[attributeIndex].Value;
+ InternalText text = objectIterator.CurrentObject as InternalText;
+ return text != null ? text.Value : string.Empty;
+ }
+ }
+
+ public override XmlNodeType NodeType {
+ get {
+ if (attributeIndex >= 0)
+ return inAttributeValue ? XmlNodeType.Text : XmlNodeType.Attribute;
+ else
+ return elementNodeType;
+ }
+ }
+
+ public override XmlNameTable NameTable {
+ get { return nameTable; }
+ }
+
+ public override bool MoveToFirstAttribute()
+ {
+ return DoMoveToAttribute(0);
+ }
+
+ public override bool MoveToNextAttribute()
+ {
+ return DoMoveToAttribute(attributeIndex + 1);
+ }
+
+ public override void MoveToAttribute(int i)
+ {
+ if (!DoMoveToAttribute(i))
+ throw new ArgumentOutOfRangeException("i");
+ }
+
+ bool DoMoveToAttribute(int i)
+ {
+ if (i >= 0 && i < this.AttributeCount) {
+ attributeIndex = i;
+ inAttributeValue = false;
+ return true;
+ }
+ return false;
+ }
+
+ public override bool MoveToElement()
+ {
+ if (attributeIndex >= 0) {
+ attributeIndex = -1;
+ inAttributeValue = false;
+ return true;
+ }
+ return false;
+ }
+
+ int GetAttributeIndex(string name)
+ {
+ if (attributes == null)
+ return -1;
+ for (int i = 0; i < attributes.Count; i++) {
+ if (attributes[i].Name == name)
+ return i;
+ }
+ return -1;
+ }
+
+ int GetAttributeIndex(string name, string ns)
+ {
+ if (attributes == null)
+ return -1;
+ for (int i = 0; i < attributes.Count; i++) {
+ if (AXmlObject.GetLocalName(attributes[i].Name) == name && LookupNamespace(AXmlObject.GetNamespacePrefix(attributes[i].Name)) == ns)
+ return i;
+ }
+ return -1;
+ }
+
+ public override bool MoveToAttribute(string name, string ns)
+ {
+ return DoMoveToAttribute(GetAttributeIndex(name, ns));
+ }
+
+ public override bool MoveToAttribute(string name)
+ {
+ return DoMoveToAttribute(GetAttributeIndex(name));
+ }
+
+ public override string LookupNamespace(string prefix)
+ {
+ return string.Empty; // TODO implement namespace lookup
+ }
+
+ public override string GetAttribute(int i)
+ {
+ if (attributes == null || i < 0 || i >= attributes.Count)
+ return null;
+ return attributes[i].Value;
+ }
+
+ public override string GetAttribute(string name, string namespaceURI)
+ {
+ return GetAttribute(GetAttributeIndex(name, namespaceURI));
+ }
+
+ public override string GetAttribute(string name)
+ {
+ return GetAttribute(GetAttributeIndex(name));
+ }
+
+ public override bool EOF {
+ get { return readState == ReadState.EndOfFile; }
+ }
+
+ public override int Depth {
+ get { return objectIterator.Depth; }
+ }
+
+ public override void Close()
+ {
+ readState = ReadState.Closed;
+ }
+
+ public override string BaseURI {
+ get { return string.Empty; }
+ }
+
+ public override int AttributeCount {
+ get { return attributes != null ? attributes.Count : 0; }
+ }
+
+ int CurrentPosition {
+ get {
+ if (attributeIndex < 0)
+ return objectIterator.CurrentPosition;
+ else
+ return objectIterator.CurrentPosition + attributes[attributeIndex].StartRelativeToParent;
+ }
+ }
+
+ public int LineNumber {
+ get {
+ if (offsetToTextLocation != null)
+ return offsetToTextLocation(CurrentPosition).Line;
+ else
+ return 0;
+ }
+ }
+
+ public int LinePosition {
+ get {
+ if (offsetToTextLocation != null)
+ return offsetToTextLocation(CurrentPosition).Column - 1;
+ else
+ return 0;
+ }
+ }
+
+ bool IXmlLineInfo.HasLineInfo()
+ {
+ return offsetToTextLocation != null;
+ }
+ }
+}
diff --git a/ICSharpCode.NRefactory.Xml/ICSharpCode.NRefactory.Xml.csproj b/ICSharpCode.NRefactory.Xml/ICSharpCode.NRefactory.Xml.csproj
index aa8be493..acd79c7d 100644
--- a/ICSharpCode.NRefactory.Xml/ICSharpCode.NRefactory.Xml.csproj
+++ b/ICSharpCode.NRefactory.Xml/ICSharpCode.NRefactory.Xml.csproj
@@ -57,6 +57,7 @@
<Compile Include="AXmlDocument.cs" />
<Compile Include="AXmlElement.cs" />
<Compile Include="AXmlObject.cs" />
+ <Compile Include="AXmlReader.cs" />
<Compile Include="AXmlTag.cs" />
<Compile Include="AXmlText.cs" />
<Compile Include="IAXmlVisitor.cs" />
diff --git a/ICSharpCode.NRefactory.Xml/InternalDocument.cs b/ICSharpCode.NRefactory.Xml/InternalDocument.cs
index 6ff535c4..adfd9cb6 100644
--- a/ICSharpCode.NRefactory.Xml/InternalDocument.cs
+++ b/ICSharpCode.NRefactory.Xml/InternalDocument.cs
@@ -126,7 +126,7 @@ namespace ICSharpCode.NRefactory.Xml
}
}
- class InternalAttribute : InternalObject
+ sealed class InternalAttribute : InternalObject
{
public string Name;
public int EqualsSignLength; // length of equals sign including the surrounding whitespace
@@ -143,10 +143,24 @@ namespace ICSharpCode.NRefactory.Xml
}
}
- class InternalElement : InternalObject
+ sealed class InternalElement : InternalObject
{
public bool HasEndTag;
public bool IsPropertyNested;
+ public readonly string Name;
+
+ public InternalElement(InternalTag tag)
+ {
+ this.Name = tag.Name;
+ }
+
+ public string Prefix {
+ get { return AXmlObject.GetNamespacePrefix(Name); }
+ }
+
+ public string LocalName {
+ get { return AXmlObject.GetLocalName(Name); }
+ }
public override AXmlObject CreatePublicObject(AXmlObject parent, int parentStartOffset)
{
diff --git a/ICSharpCode.NRefactory.Xml/ObjectIterator.cs b/ICSharpCode.NRefactory.Xml/ObjectIterator.cs
index 1d83f3e2..ad4ad841 100644
--- a/ICSharpCode.NRefactory.Xml/ObjectIterator.cs
+++ b/ICSharpCode.NRefactory.Xml/ObjectIterator.cs
@@ -24,7 +24,7 @@ namespace ICSharpCode.NRefactory.Xml
/// <summary>
/// Iterates through an internal object tree.
/// </summary>
- class ObjectIterator
+ sealed class ObjectIterator
{
Stack<InternalObject[]> listStack = new Stack<InternalObject[]>();
Stack<int> indexStack = new Stack<int>();
@@ -33,9 +33,12 @@ namespace ICSharpCode.NRefactory.Xml
int currentIndex;
InternalObject currentObject;
int currentPosition;
+ internal bool StopAtElementEnd;
+ bool isAtElementEnd;
- public ObjectIterator(InternalObject[] objects)
+ public ObjectIterator(InternalObject[] objects, int startPosition = 0)
{
+ this.currentPosition = startPosition;
this.objects = objects;
if (objects.Length > 0)
this.currentObject = objects[0];
@@ -49,22 +52,37 @@ namespace ICSharpCode.NRefactory.Xml
get { return currentPosition; }
}
+ public bool IsAtElementEnd {
+ get { return isAtElementEnd; }
+ }
+
+ public int Depth {
+ get { return listStack.Count; }
+ }
+
public void MoveNext()
{
if (currentObject == null)
return;
currentIndex++;
currentPosition += currentObject.Length;
+ isAtElementEnd = false;
while (currentIndex >= objects.Length && listStack.Count > 0) {
objects = listStack.Pop();
- currentIndex = indexStack.Pop() + 1;
+ currentIndex = indexStack.Pop();
+ if (this.StopAtElementEnd) {
+ isAtElementEnd = true;
+ break;
+ } else {
+ currentIndex++;
+ }
}
currentObject = (currentIndex < objects.Length ? objects[currentIndex] : null);
}
public void MoveInto()
{
- if (!(currentObject is InternalElement)) {
+ if (isAtElementEnd || !(currentObject is InternalElement)) {
MoveNext();
} else {
listStack.Push(objects);
diff --git a/ICSharpCode.NRefactory.Xml/TagMatchingHeuristics.cs b/ICSharpCode.NRefactory.Xml/TagMatchingHeuristics.cs
index e5896eaf..2772f44b 100644
--- a/ICSharpCode.NRefactory.Xml/TagMatchingHeuristics.cs
+++ b/ICSharpCode.NRefactory.Xml/TagMatchingHeuristics.cs
@@ -324,7 +324,7 @@ namespace ICSharpCode.NRefactory.Xml
childElements.Add(tag);
}
}
- InternalElement e = new InternalElement();
+ InternalElement e = new InternalElement(startTag);
e.HasEndTag = (tag != EndTagPlaceholder);
e.NestedObjects = new InternalObject[childElements.Count];
int pos = 0;
diff --git a/ICSharpCode.NRefactory.Xml/TagReader.cs b/ICSharpCode.NRefactory.Xml/TagReader.cs
index 60527dea..e6178de3 100644
--- a/ICSharpCode.NRefactory.Xml/TagReader.cs
+++ b/ICSharpCode.NRefactory.Xml/TagReader.cs
@@ -97,7 +97,7 @@ namespace ICSharpCode.NRefactory.Xml
return;
if (tag.IsEmptyTag) {
// the tag is its own element
- objects[objects.Count - 1] = new InternalElement() {
+ objects[objects.Count - 1] = new InternalElement(tag) {
Length = tag.Length,
LengthTouched = tag.LengthTouched,
IsPropertyNested = true,
@@ -138,7 +138,7 @@ namespace ICSharpCode.NRefactory.Xml
}
objects.RemoveRange(startIndex, nestedObjects.Length);
objects.Add(
- new InternalElement {
+ new InternalElement((InternalTag)nestedObjects[0]) {
HasEndTag = true,
IsPropertyNested = true,
Length = pos,
@@ -601,108 +601,79 @@ namespace ICSharpCode.NRefactory.Xml
#region Text
/// <summary>
- /// Reads text and optionaly separates it into fragments.
- /// It can also return empty set for no appropriate text input.
- /// Make sure you enumerate it only once
+ /// Reads text.
/// </summary>
void ReadText(TextType type)
{
- const int maxTextFragmentSize = 128;
- bool finished;
- do {
- var text = new InternalText();
- var frame = BeginInternalObject(text);
- text.Type = type;
-
- // Limit the reading to just a few characters
- // (the first character not to be read)
- int fragmentEnd = Math.Min(this.CurrentLocation + maxTextFragmentSize, this.InputLength);
-
- int start = this.CurrentLocation;
-
- // Whitespace would be skipped anyway by any operation
+ var text = new InternalText();
+ var frame = BeginInternalObject(text);
+ text.Type = type;
+
+ int start = this.CurrentLocation;
+ int fragmentEnd = inputLength;
+
+ // Whitespace would be skipped anyway by any operation
+ TryMoveToNonWhiteSpace(fragmentEnd);
+ int wsEnd = this.CurrentLocation;
+
+ // Try move to the terminator given by the context
+ if (type == TextType.WhiteSpace) {
TryMoveToNonWhiteSpace(fragmentEnd);
- int wsEnd = this.CurrentLocation;
-
- // Try move to the terminator given by the context
- if (type == TextType.WhiteSpace) {
- TryMoveToNonWhiteSpace(fragmentEnd);
- } else if (type == TextType.CharacterData) {
- while(true) {
- if (!TryMoveToAnyOf(new char[] {'<', ']'}, fragmentEnd)) break; // End of fragment
- if (TryPeek('<')) break;
- if (TryPeek(']')) {
- if (TryPeek("]]>")) {
- OnSyntaxError(this.CurrentLocation, this.CurrentLocation + 3, "']]>' is not allowed in text");
- }
- TryMoveNext();
- continue;
- }
- throw new InternalException("Infinite loop");
- }
- } else if (type == TextType.Comment) {
- // Do not report too many errors
- bool errorReported = false;
- while(true) {
- if (!TryMoveTo('-', fragmentEnd)) break; // End of fragment
- if (TryPeek("-->")) break;
- if (TryPeek("--") && !errorReported) {
- OnSyntaxError(this.CurrentLocation, this.CurrentLocation + 2, "'--' is not allowed in comment");
- errorReported = true;
+ } else if (type == TextType.CharacterData) {
+ while(true) {
+ if (!TryMoveToAnyOf(new char[] {'<', ']'}, fragmentEnd)) break; // End of fragment
+ if (TryPeek('<')) break;
+ if (TryPeek(']')) {
+ if (TryPeek("]]>")) {
+ OnSyntaxError(this.CurrentLocation, this.CurrentLocation + 3, "']]>' is not allowed in text");
}
TryMoveNext();
+ continue;
}
- } else if (type == TextType.CData) {
- while(true) {
- // We can not use use TryMoveTo("]]>", fragmentEnd) because it may incorectly accept "]" at the end of fragment
- if (!TryMoveTo(']', fragmentEnd)) break; // End of fragment
- if (TryPeek("]]>")) break;
- TryMoveNext();
- }
- } else if (type == TextType.ProcessingInstruction) {
- while(true) {
- if (!TryMoveTo('?', fragmentEnd)) break; // End of fragment
- if (TryPeek("?>")) break;
- TryMoveNext();
- }
- } else if (type == TextType.UnknownBang) {
- TryMoveToAnyOf(new char[] {'<', '>'}, fragmentEnd);
- } else {
- throw new InternalException("Uknown type " + type);
+ throw new InternalException("Infinite loop");
}
-
- text.ContainsOnlyWhitespace = (wsEnd == this.CurrentLocation);
-
- // Terminal found or real end was reached;
- finished = this.CurrentLocation < fragmentEnd || IsEndOfFile();
-
- if (!finished) {
- // We have to continue reading more text fragments
-
- // If there is entity reference, make sure the next segment starts with it to prevent framentation
- int entitySearchStart = Math.Max(start + 1 /* data for us */, this.CurrentLocation - maxEntityLength);
- int entitySearchLength = this.CurrentLocation - entitySearchStart;
- if (entitySearchLength > 0) {
- // Note that LastIndexOf works backward
- int entityIndex = input.LastIndexOf('&', this.CurrentLocation - entitySearchLength, entitySearchLength);
- if (entityIndex != -1) {
- GoBack(entityIndex);
- }
+ } else if (type == TextType.Comment) {
+ // Do not report too many errors
+ bool errorReported = false;
+ while(true) {
+ if (!TryMoveTo('-', fragmentEnd)) break; // End of fragment
+ if (TryPeek("-->")) break;
+ if (TryPeek("--") && !errorReported) {
+ OnSyntaxError(this.CurrentLocation, this.CurrentLocation + 2, "'--' is not allowed in comment");
+ errorReported = true;
}
+ TryMoveNext();
}
-
- string escapedValue = GetText(start, this.CurrentLocation);
- if (type == TextType.CharacterData) {
- // Normalize end of line first
- text.Value = Dereference(NormalizeEndOfLine(escapedValue), start);
- } else {
- text.Value = escapedValue;
+ } else if (type == TextType.CData) {
+ while(true) {
+ // We can not use use TryMoveTo("]]>", fragmentEnd) because it may incorectly accept "]" at the end of fragment
+ if (!TryMoveTo(']', fragmentEnd)) break; // End of fragment
+ if (TryPeek("]]>")) break;
+ TryMoveNext();
}
- text.Value = GetCachedString(text.Value);
-
- EndInternalObject(frame, storeNewObject: this.CurrentLocation > start);
-
- } while (!finished);
+ } else if (type == TextType.ProcessingInstruction) {
+ while(true) {
+ if (!TryMoveTo('?', fragmentEnd)) break; // End of fragment
+ if (TryPeek("?>")) break;
+ TryMoveNext();
+ }
+ } else if (type == TextType.UnknownBang) {
+ TryMoveToAnyOf(new char[] {'<', '>'}, fragmentEnd);
+ } else {
+ throw new InternalException("Unknown type " + type);
+ }
+
+ text.ContainsOnlyWhitespace = (wsEnd == this.CurrentLocation);
+
+ string escapedValue = GetText(start, this.CurrentLocation);
+ if (type == TextType.CharacterData) {
+ text.Value = Dereference(escapedValue, start);
+ } else {
+ text.Value = escapedValue;
+ }
+ text.Value = GetCachedString(text.Value);
+
+ EndInternalObject(frame, storeNewObject: this.CurrentLocation > start);
}
#endregion
@@ -856,11 +827,6 @@ namespace ICSharpCode.NRefactory.Xml
return false;
}
}
-
- static string NormalizeEndOfLine(string text)
- {
- return text.Replace("\r\n", "\n").Replace('\r', '\n');
- }
#endregion
}
}