Browse Source

Add CancellationToken to AXmlParser.

newNRvisualizers
Daniel Grunwald 14 years ago
parent
commit
deb6bcd377
  1. 36
      ICSharpCode.NRefactory.Xml/AXmlParser.cs
  2. 9
      ICSharpCode.NRefactory.Xml/TagMatchingHeuristics.cs
  3. 8
      ICSharpCode.NRefactory.Xml/TagReader.cs

36
ICSharpCode.NRefactory.Xml/AXmlParser.cs

@ -20,6 +20,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading;
using System.Xml.Linq; using System.Xml.Linq;
using ICSharpCode.NRefactory.Editor; using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.Utils; using ICSharpCode.NRefactory.Utils;
@ -51,12 +52,13 @@ namespace ICSharpCode.NRefactory.Xml
/// Parses a document into a flat list of tags. /// Parses a document into a flat list of tags.
/// </summary> /// </summary>
/// <returns>Parsed tag soup.</returns> /// <returns>Parsed tag soup.</returns>
public IList<AXmlObject> ParseTagSoup(ITextSource textSource) public IList<AXmlObject> ParseTagSoup(ITextSource textSource,
CancellationToken cancellationToken = default(CancellationToken))
{ {
if (textSource == null) if (textSource == null)
throw new ArgumentNullException("textSource"); throw new ArgumentNullException("textSource");
var reader = new TagReader(this, textSource, false); var reader = new TagReader(this, textSource, false);
var internalObjects = reader.ReadAllObjects(); var internalObjects = reader.ReadAllObjects(cancellationToken);
return CreatePublic(internalObjects); return CreatePublic(internalObjects);
} }
@ -66,16 +68,21 @@ namespace ICSharpCode.NRefactory.Xml
/// <param name="oldParserState">The parser state from a previous call to ParseIncremental(). Use null for the first call.</param> /// <param name="oldParserState">The parser state from a previous call to ParseIncremental(). Use null for the first call.</param>
/// <param name="newTextSource">The text source for the new document version.</param> /// <param name="newTextSource">The text source for the new document version.</param>
/// <param name="newParserState">Out: the new parser state, pass this to the next ParseIncremental() call.</param> /// <param name="newParserState">Out: the new parser state, pass this to the next ParseIncremental() call.</param>
/// <param name="cancellationToken">Optional: cancellation token.</param>
/// <returns>Parsed tag soup.</returns> /// <returns>Parsed tag soup.</returns>
public IList<AXmlObject> ParseTagSoupIncremental(IncrementalParserState oldParserState, ITextSource newTextSource, out IncrementalParserState newParserState) public IList<AXmlObject> ParseTagSoupIncremental(
IncrementalParserState oldParserState, ITextSource newTextSource, out IncrementalParserState newParserState,
CancellationToken cancellationToken = default(CancellationToken))
{ {
if (newTextSource == null) if (newTextSource == null)
throw new ArgumentNullException("newTextSource"); throw new ArgumentNullException("newTextSource");
var internalObjects = InternalParseIncremental(oldParserState, newTextSource, out newParserState, false); var internalObjects = InternalParseIncremental(oldParserState, newTextSource, out newParserState, false, cancellationToken);
return CreatePublic(internalObjects); return CreatePublic(internalObjects);
} }
List<InternalObject> InternalParseIncremental(IncrementalParserState oldParserState, ITextSource newTextSource, out IncrementalParserState newParserState, bool collapseProperlyNestedElements) List<InternalObject> InternalParseIncremental(
IncrementalParserState oldParserState, ITextSource newTextSource, out IncrementalParserState newParserState,
bool collapseProperlyNestedElements, CancellationToken cancellationToken)
{ {
var reader = new TagReader(this, newTextSource, collapseProperlyNestedElements); var reader = new TagReader(this, newTextSource, collapseProperlyNestedElements);
ITextSourceVersion newVersion = newTextSource.Version; ITextSourceVersion newVersion = newTextSource.Version;
@ -83,9 +90,9 @@ namespace ICSharpCode.NRefactory.Xml
List<InternalObject> internalObjects; List<InternalObject> internalObjects;
if (reuseMap != null) if (reuseMap != null)
internalObjects = reader.ReadAllObjectsIncremental(oldParserState.Objects, reuseMap); internalObjects = reader.ReadAllObjectsIncremental(oldParserState.Objects, reuseMap, cancellationToken);
else else
internalObjects = reader.ReadAllObjects(); internalObjects = reader.ReadAllObjects(cancellationToken);
if (newVersion != null) if (newVersion != null)
newParserState = new IncrementalParserState(newTextSource.TextLength, newVersion, internalObjects.ToArray()); newParserState = new IncrementalParserState(newTextSource.TextLength, newVersion, internalObjects.ToArray());
@ -98,14 +105,14 @@ namespace ICSharpCode.NRefactory.Xml
/// <summary> /// <summary>
/// Parses a document. /// Parses a document.
/// </summary> /// </summary>
public AXmlDocument Parse(ITextSource textSource) public AXmlDocument Parse(ITextSource textSource, CancellationToken cancellationToken = default(CancellationToken))
{ {
if (textSource == null) if (textSource == null)
throw new ArgumentNullException("textSource"); throw new ArgumentNullException("textSource");
var reader = new TagReader(this, textSource, true); var reader = new TagReader(this, textSource, true);
var internalObjects = reader.ReadAllObjects(); var internalObjects = reader.ReadAllObjects(cancellationToken);
var heuristic = new TagMatchingHeuristics(textSource); var heuristic = new TagMatchingHeuristics(textSource);
return new AXmlDocument(null, 0, heuristic.CreateDocument(internalObjects)); return new AXmlDocument(null, 0, heuristic.CreateDocument(internalObjects, cancellationToken));
} }
/// <summary> /// <summary>
@ -114,14 +121,17 @@ namespace ICSharpCode.NRefactory.Xml
/// <param name="oldParserState">The parser state from a previous call to ParseIncremental(). Use null for the first call.</param> /// <param name="oldParserState">The parser state from a previous call to ParseIncremental(). Use null for the first call.</param>
/// <param name="newTextSource">The text source for the new document version.</param> /// <param name="newTextSource">The text source for the new document version.</param>
/// <param name="newParserState">Out: the new parser state, pass this to the next ParseIncremental() call.</param> /// <param name="newParserState">Out: the new parser state, pass this to the next ParseIncremental() call.</param>
/// <param name="cancellationToken">Optional: cancellation token.</param>
/// <returns>Parsed tag soup.</returns> /// <returns>Parsed tag soup.</returns>
public AXmlDocument ParseIncremental(IncrementalParserState oldParserState, ITextSource newTextSource, out IncrementalParserState newParserState) public AXmlDocument ParseIncremental(
IncrementalParserState oldParserState, ITextSource newTextSource, out IncrementalParserState newParserState,
CancellationToken cancellationToken = default(CancellationToken))
{ {
if (newTextSource == null) if (newTextSource == null)
throw new ArgumentNullException("newTextSource"); throw new ArgumentNullException("newTextSource");
var internalObjects = InternalParseIncremental(oldParserState, newTextSource, out newParserState, true); var internalObjects = InternalParseIncremental(oldParserState, newTextSource, out newParserState, true, cancellationToken);
var heuristic = new TagMatchingHeuristics(newTextSource); var heuristic = new TagMatchingHeuristics(newTextSource);
return new AXmlDocument(null, 0, heuristic.CreateDocument(internalObjects)); return new AXmlDocument(null, 0, heuristic.CreateDocument(internalObjects, cancellationToken));
} }
} }
} }

9
ICSharpCode.NRefactory.Xml/TagMatchingHeuristics.cs

@ -20,6 +20,7 @@ using System;
using System.Linq; using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Threading;
using ICSharpCode.NRefactory.Editor; using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.Utils; using ICSharpCode.NRefactory.Utils;
@ -28,6 +29,7 @@ namespace ICSharpCode.NRefactory.Xml
class TagMatchingHeuristics class TagMatchingHeuristics
{ {
readonly ITextSource textSource; readonly ITextSource textSource;
const int MaxConfigurationCount = 30; const int MaxConfigurationCount = 30;
public TagMatchingHeuristics(ITextSource textSource) public TagMatchingHeuristics(ITextSource textSource)
@ -35,9 +37,9 @@ namespace ICSharpCode.NRefactory.Xml
this.textSource = textSource; this.textSource = textSource;
} }
public InternalDocument CreateDocument(List<InternalObject> tagSoup) public InternalDocument CreateDocument(List<InternalObject> tagSoup, CancellationToken cancellationToken)
{ {
var stack = InsertPlaceholderTags(tagSoup); var stack = InsertPlaceholderTags(tagSoup, cancellationToken);
InternalDocument doc = new InternalDocument(); InternalDocument doc = new InternalDocument();
var docElements = CreateElements(ref stack); var docElements = CreateElements(ref stack);
docElements.Reverse(); // reverse due to stack docElements.Reverse(); // reverse due to stack
@ -201,7 +203,7 @@ namespace ICSharpCode.NRefactory.Xml
return indentation; return indentation;
} }
ImmutableStack<InternalObject> InsertPlaceholderTags(List<InternalObject> objects) ImmutableStack<InternalObject> InsertPlaceholderTags(List<InternalObject> objects, CancellationToken cancellationToken)
{ {
// Calculate indentation levels in front of the tags: // Calculate indentation levels in front of the tags:
int[] indentationBeforeTags = new int[objects.Count]; int[] indentationBeforeTags = new int[objects.Count];
@ -218,6 +220,7 @@ namespace ICSharpCode.NRefactory.Xml
listA.Add(new Configuration(new OpenTagStack(), ImmutableStack<InternalObject>.Empty, 0)); listA.Add(new Configuration(new OpenTagStack(), ImmutableStack<InternalObject>.Empty, 0));
for (int i = 0; i < indentationBeforeTags.Length; i++) { for (int i = 0; i < indentationBeforeTags.Length; i++) {
cancellationToken.ThrowIfCancellationRequested();
ProcessObject(objects[i], indentationBeforeTags[i], listA, ref listB); ProcessObject(objects[i], indentationBeforeTags[i], listA, ref listB);
Swap(ref listA, ref listB); Swap(ref listA, ref listB);
} }

8
ICSharpCode.NRefactory.Xml/TagReader.cs

@ -22,6 +22,7 @@ using System.Diagnostics;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading;
using ICSharpCode.NRefactory.Editor; using ICSharpCode.NRefactory.Editor;
namespace ICSharpCode.NRefactory.Xml namespace ICSharpCode.NRefactory.Xml
@ -38,21 +39,23 @@ namespace ICSharpCode.NRefactory.Xml
elementNameStack = new Stack<string>(); elementNameStack = new Stack<string>();
} }
public List<InternalObject> ReadAllObjects() public List<InternalObject> ReadAllObjects(CancellationToken cancellationToken)
{ {
while (HasMoreData()) { while (HasMoreData()) {
cancellationToken.ThrowIfCancellationRequested();
ReadObject(); ReadObject();
} }
return objects; return objects;
} }
public List<InternalObject> ReadAllObjectsIncremental(InternalObject[] oldObjects, List<UnchangedSegment> reuseMap) public List<InternalObject> ReadAllObjectsIncremental(InternalObject[] oldObjects, List<UnchangedSegment> reuseMap, CancellationToken cancellationToken)
{ {
ObjectIterator oldObjectIterator = new ObjectIterator(oldObjects); ObjectIterator oldObjectIterator = new ObjectIterator(oldObjects);
int reuseMapIndex = 0; int reuseMapIndex = 0;
while (reuseMapIndex < reuseMap.Count) { while (reuseMapIndex < reuseMap.Count) {
var reuseEntry = reuseMap[reuseMapIndex]; var reuseEntry = reuseMap[reuseMapIndex];
while (this.CurrentLocation < reuseEntry.NewOffset) { while (this.CurrentLocation < reuseEntry.NewOffset) {
cancellationToken.ThrowIfCancellationRequested();
ReadObject(); ReadObject();
} }
if (this.CurrentLocation >= reuseEntry.NewOffset + reuseEntry.Length) { if (this.CurrentLocation >= reuseEntry.NewOffset + reuseEntry.Length) {
@ -80,6 +83,7 @@ namespace ICSharpCode.NRefactory.Xml
} }
} }
while (HasMoreData()) { while (HasMoreData()) {
cancellationToken.ThrowIfCancellationRequested();
ReadObject(); ReadObject();
} }
return objects; return objects;

Loading…
Cancel
Save