Browse Source

Merge branch 'master' of github.com:icsharpcode/NRefactory

newNRvisualizers
Mike Krüger 14 years ago
parent
commit
769ea3e023
  1. 13
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssue.cs
  2. 1
      ICSharpCode.NRefactory.CSharp/Refactoring/DocumentScript.cs
  3. 27
      ICSharpCode.NRefactory.CSharp/Resolver/TypeInference.cs
  4. 4
      ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpParsedFile.cs
  5. 17
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/ExtensionMethodTests.cs
  6. 22
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/TypeInferenceTests.cs
  7. 2
      ICSharpCode.NRefactory.Xml/AXmlAttribute.cs
  8. 7
      ICSharpCode.NRefactory.Xml/AXmlDocument.cs
  9. 2
      ICSharpCode.NRefactory.Xml/AXmlElement.cs
  10. 2
      ICSharpCode.NRefactory.Xml/AXmlObject.cs
  11. 36
      ICSharpCode.NRefactory.Xml/AXmlParser.cs
  12. 2
      ICSharpCode.NRefactory.Xml/AXmlTag.cs
  13. 2
      ICSharpCode.NRefactory.Xml/AXmlText.cs
  14. 47
      ICSharpCode.NRefactory.Xml/AXmlVisitor.cs
  15. 2
      ICSharpCode.NRefactory.Xml/ICSharpCode.NRefactory.Xml.csproj
  16. 9
      ICSharpCode.NRefactory.Xml/TagMatchingHeuristics.cs
  17. 8
      ICSharpCode.NRefactory.Xml/TagReader.cs
  18. 2
      ICSharpCode.NRefactory/TypeSystem/IParsedFile.cs

13
ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssue.cs

@ -1,6 +1,6 @@
// //
// InspectionIssue.cs // InspectionIssue.cs
// //
// Author: // Author:
// Mike Krüger <mkrueger@xamarin.com> // Mike Krüger <mkrueger@xamarin.com>
// //
@ -46,17 +46,20 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
private set; private set;
} }
public IEnumerable<CodeAction> Actions { public IList<CodeAction> Actions {
get; get;
private set; private set;
} }
public CodeIssue(string description, TextLocation start, TextLocation end, IEnumerable<CodeAction> action = null) public CodeIssue(string description, TextLocation start, TextLocation end, IEnumerable<CodeAction> actions = null)
{ {
Desription = description; Desription = description;
Start = start; Start = start;
End = end; End = end;
Actions = action ?? Enumerable.Empty<CodeAction> (); if (actions != null)
Actions = actions.ToArray();
else
Actions = EmptyList<CodeAction>.Instance;
} }
public CodeIssue(string description, TextLocation start, TextLocation end, CodeAction action) : this (description, start, end, action != null ? new [] { action } : null) public CodeIssue(string description, TextLocation start, TextLocation end, CodeAction action) : this (description, start, end, action != null ? new [] { action } : null)

1
ICSharpCode.NRefactory.CSharp/Refactoring/DocumentScript.cs

@ -46,6 +46,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
this.originalDocument = document.CreateDocumentSnapshot(); this.originalDocument = document.CreateDocumentSnapshot();
this.currentDocument = document; this.currentDocument = document;
this.options = options; this.options = options;
this.eolMarker = options.EolMarker;
Debug.Assert(currentDocument.Version.CompareAge(originalDocument.Version) == 0); Debug.Assert(currentDocument.Version.CompareAge(originalDocument.Version) == 0);
this.undoGroup = document.OpenUndoGroup(); this.undoGroup = document.OpenUndoGroup();
} }

27
ICSharpCode.NRefactory.CSharp/Resolver/TypeInference.cs

@ -629,12 +629,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
// Handle array types: // Handle array types:
ArrayType arrU = U as ArrayType; ArrayType arrU = U as ArrayType;
ArrayType arrV = V as ArrayType; ArrayType arrV = V as ArrayType;
ParameterizedType pV = V as ParameterizedType;
if (arrU != null && arrV != null && arrU.Dimensions == arrV.Dimensions) { if (arrU != null && arrV != null && arrU.Dimensions == arrV.Dimensions) {
MakeLowerBoundInference(arrU.ElementType, arrV.ElementType); MakeLowerBoundInference(arrU.ElementType, arrV.ElementType);
return; return;
} else if (arrU != null && IsGenericInterfaceImplementedByArray(pV) && arrU.Dimensions == 1) {
MakeLowerBoundInference(arrU.ElementType, pV.GetTypeArgument(0));
return;
} }
// Handle parameterized types: // Handle parameterized types:
ParameterizedType pV = V as ParameterizedType;
if (pV != null) { if (pV != null) {
ParameterizedType uniqueBaseType = null; ParameterizedType uniqueBaseType = null;
foreach (IType baseU in U.GetAllBaseTypes()) { foreach (IType baseU in U.GetAllBaseTypes()) {
@ -674,6 +677,21 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
Log.Unindent(); Log.Unindent();
} }
} }
static bool IsGenericInterfaceImplementedByArray(ParameterizedType rt)
{
if (rt == null || rt.TypeParameterCount != 1)
return false;
switch (rt.GetDefinition().FullName) {
case "System.Collections.Generic.IEnumerable":
case "System.Collections.Generic.ICollection":
case "System.Collections.Generic.IList":
case "System.Collections.Generic.IReadOnlyList":
return true;
default:
return false;
}
}
#endregion #endregion
#region MakeUpperBoundInference (§7.5.2.10) #region MakeUpperBoundInference (§7.5.2.10)
@ -696,12 +714,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
// Handle array types: // Handle array types:
ArrayType arrU = U as ArrayType; ArrayType arrU = U as ArrayType;
ArrayType arrV = V as ArrayType; ArrayType arrV = V as ArrayType;
ParameterizedType pU = U as ParameterizedType;
if (arrV != null && arrU != null && arrU.Dimensions == arrV.Dimensions) { if (arrV != null && arrU != null && arrU.Dimensions == arrV.Dimensions) {
MakeUpperBoundInference(arrU.ElementType, arrV.ElementType); MakeUpperBoundInference(arrU.ElementType, arrV.ElementType);
return; return;
} } else if (arrV != null && IsGenericInterfaceImplementedByArray(pU) && arrV.Dimensions == 1) {
MakeUpperBoundInference(pU.GetTypeArgument(0), arrV.ElementType);
return;
}
// Handle parameterized types: // Handle parameterized types:
ParameterizedType pU = U as ParameterizedType;
if (pU != null) { if (pU != null) {
ParameterizedType uniqueBaseType = null; ParameterizedType uniqueBaseType = null;
foreach (IType baseV in V.GetAllBaseTypes()) { foreach (IType baseV in V.GetAllBaseTypes()) {

4
ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpParsedFile.cs

@ -73,9 +73,9 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
get { return fileName; } get { return fileName; }
} }
DateTime lastWriteTime = DateTime.UtcNow; DateTime? lastWriteTime;
public DateTime LastWriteTime { public DateTime? LastWriteTime {
get { return lastWriteTime; } get { return lastWriteTime; }
set { set {
FreezableHelper.ThrowIfFrozen(this); FreezableHelper.ThrowIfFrozen(this);

17
ICSharpCode.NRefactory.Tests/CSharp/Resolver/ExtensionMethodTests.cs

@ -101,5 +101,22 @@ public static class XC {
Assert.AreEqual("XC.Filter", mrr.Member.FullName); Assert.AreEqual("XC.Filter", mrr.Member.FullName);
Assert.AreEqual("System.Collections.Generic.IEnumerable`1[[System.String]]", mrr.Type.ReflectionName); Assert.AreEqual("System.Collections.Generic.IEnumerable`1[[System.String]]", mrr.Type.ReflectionName);
} }
[Test]
public void FirstIsEligibleExtensionMethod()
{
string program = @"using System; using System.Collections.Generic;
public static class XC {
$public static TSource First<TSource>(this IEnumerable<TSource> source) {}$
}
";
var mrr = Resolve<MemberResolveResult>(program);
var targetType = compilation.FindType(typeof(string[]));
IType[] inferredTypes;
bool isEligible = CSharpResolver.IsEligibleExtensionMethod(targetType, (IMethod)mrr.Member, true, out inferredTypes);
Assert.IsTrue(isEligible);
Assert.AreEqual(1, inferredTypes.Length);
Assert.AreEqual("System.String", inferredTypes[0].ReflectionName);
}
} }
} }

22
ICSharpCode.NRefactory.Tests/CSharp/Resolver/TypeInferenceTests.cs

@ -126,6 +126,28 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
out success)); out success));
Assert.IsTrue(success); Assert.IsTrue(success);
} }
[Test]
public void ArrayToListWithArrayCovariance()
{
ITypeParameter tp = new DefaultTypeParameter(compilation, EntityType.Method, 0, "T");
IType objectType = compilation.FindType(KnownTypeCode.Object);
IType stringType = compilation.FindType(KnownTypeCode.String);
ITypeDefinition listType = compilation.FindType(KnownTypeCode.IListOfT).GetDefinition();
// void M<T>(IList<T> a, T b);
// M(new string[0], new object());
bool success;
Assert.AreEqual(
new [] { objectType },
ti.InferTypeArguments(
new [] { tp },
new [] { new ResolveResult(new ArrayType(compilation, stringType)), new ResolveResult(objectType) },
new [] { new ParameterizedType(listType, new [] { tp }), (IType)tp },
out success));
Assert.IsTrue(success);
}
#endregion #endregion
#region Inference with Method Groups #region Inference with Method Groups

2
ICSharpCode.NRefactory.Xml/AXmlAttribute.cs

@ -104,7 +104,7 @@ namespace ICSharpCode.NRefactory.Xml
} }
/// <inheritdoc/> /// <inheritdoc/>
public override void AcceptVisitor(IAXmlVisitor visitor) public override void AcceptVisitor(AXmlVisitor visitor)
{ {
visitor.VisitAttribute(this); visitor.VisitAttribute(this);
} }

7
ICSharpCode.NRefactory.Xml/AXmlDocument.cs

@ -45,7 +45,7 @@ namespace ICSharpCode.NRefactory.Xml
} }
/// <inheritdoc/> /// <inheritdoc/>
public override void AcceptVisitor(IAXmlVisitor visitor) public override void AcceptVisitor(AXmlVisitor visitor)
{ {
visitor.VisitDocument(this); visitor.VisitDocument(this);
} }
@ -55,5 +55,10 @@ namespace ICSharpCode.NRefactory.Xml
{ {
return string.Format(CultureInfo.InvariantCulture, "[{0} Chld:{1}]", base.ToString(), this.Children.Count); return string.Format(CultureInfo.InvariantCulture, "[{0} Chld:{1}]", base.ToString(), this.Children.Count);
} }
/// <summary>
/// Represents an empty document.
/// </summary>
public readonly static AXmlDocument Empty = new AXmlDocument(null, 0, new InternalDocument());
} }
} }

2
ICSharpCode.NRefactory.Xml/AXmlElement.cs

@ -164,7 +164,7 @@ namespace ICSharpCode.NRefactory.Xml
} }
/// <inheritdoc/> /// <inheritdoc/>
public override void AcceptVisitor(IAXmlVisitor visitor) public override void AcceptVisitor(AXmlVisitor visitor)
{ {
visitor.VisitElement(this); visitor.VisitElement(this);
} }

2
ICSharpCode.NRefactory.Xml/AXmlObject.cs

@ -179,7 +179,7 @@ namespace ICSharpCode.NRefactory.Xml
#endregion #endregion
/// <summary> Call appropriate visit method on the given visitor </summary> /// <summary> Call appropriate visit method on the given visitor </summary>
public abstract void AcceptVisitor(IAXmlVisitor visitor); public abstract void AcceptVisitor(AXmlVisitor visitor);
/// <summary> /// <summary>
/// Gets the start offset of the segment. /// Gets the start offset of the segment.

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));
} }
} }
} }

2
ICSharpCode.NRefactory.Xml/AXmlTag.cs

@ -84,7 +84,7 @@ namespace ICSharpCode.NRefactory.Xml
public bool IsUnknownBang { get { return internalObject.IsUnknownBang; } } public bool IsUnknownBang { get { return internalObject.IsUnknownBang; } }
/// <inheritdoc/> /// <inheritdoc/>
public override void AcceptVisitor(IAXmlVisitor visitor) public override void AcceptVisitor(AXmlVisitor visitor)
{ {
visitor.VisitTag(this); visitor.VisitTag(this);
} }

2
ICSharpCode.NRefactory.Xml/AXmlText.cs

@ -49,7 +49,7 @@ namespace ICSharpCode.NRefactory.Xml
} }
/// <inheritdoc/> /// <inheritdoc/>
public override void AcceptVisitor(IAXmlVisitor visitor) public override void AcceptVisitor(AXmlVisitor visitor)
{ {
visitor.VisitText(this); visitor.VisitText(this);
} }

47
ICSharpCode.NRefactory.Xml/IAXmlVisitor.cs → ICSharpCode.NRefactory.Xml/AXmlVisitor.cs

@ -1,4 +1,4 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team // Copyright (c) AlphaSierraPapa for the SharpDevelop Team
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy of this // 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 // software and associated documentation files (the "Software"), to deal in the Software
@ -17,27 +17,46 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System; using System;
using System.Text;
namespace ICSharpCode.NRefactory.Xml namespace ICSharpCode.NRefactory.Xml
{ {
/// <summary> /// <summary>
/// Visitor for the XML tree /// Derive from this class to create visitor for the XML tree
/// </summary> /// </summary>
public interface IAXmlVisitor public abstract class AXmlVisitor
{ {
/// <summary> Visit document </summary> /// <summary> Visit AXmlDocument </summary>
void VisitDocument(AXmlDocument document); public virtual void VisitDocument(AXmlDocument document)
{
foreach (AXmlObject child in document.Children)
child.AcceptVisitor(this);
}
/// <summary> Visit tag </summary> /// <summary> Visit AXmlElement </summary>
void VisitTag(AXmlTag tag); public virtual void VisitElement(AXmlElement element)
{
foreach (AXmlObject child in element.Children)
child.AcceptVisitor(this);
}
/// <summary> Visit attribute </summary> /// <summary> Visit AXmlTag </summary>
void VisitAttribute(AXmlAttribute attribute); public virtual void VisitTag(AXmlTag tag)
{
foreach (AXmlObject child in tag.Children)
child.AcceptVisitor(this);
}
/// <summary> Visit text </summary> /// <summary> Visit AXmlAttribute </summary>
void VisitText(AXmlText text); public virtual void VisitAttribute(AXmlAttribute attribute)
{
}
/// <summary> Visit element </summary> /// <summary> Visit AXmlText </summary>
void VisitElement(AXmlElement element); public virtual void VisitText(AXmlText text)
{
}
} }
} }

2
ICSharpCode.NRefactory.Xml/ICSharpCode.NRefactory.Xml.csproj

@ -68,8 +68,8 @@
<Compile Include="AXmlReader.cs" /> <Compile Include="AXmlReader.cs" />
<Compile Include="AXmlTag.cs" /> <Compile Include="AXmlTag.cs" />
<Compile Include="AXmlText.cs" /> <Compile Include="AXmlText.cs" />
<Compile Include="AXmlVisitor.cs" />
<Compile Include="DocumentationElement.cs" /> <Compile Include="DocumentationElement.cs" />
<Compile Include="IAXmlVisitor.cs" />
<Compile Include="IncrementalParserState.cs" /> <Compile Include="IncrementalParserState.cs" />
<Compile Include="InternalDocument.cs" /> <Compile Include="InternalDocument.cs" />
<Compile Include="ObjectIterator.cs" /> <Compile Include="ObjectIterator.cs" />

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;

2
ICSharpCode.NRefactory/TypeSystem/IParsedFile.cs

@ -34,7 +34,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// <summary> /// <summary>
/// Gets the time when the file was last written. /// Gets the time when the file was last written.
/// </summary> /// </summary>
DateTime LastWriteTime { get; } DateTime? LastWriteTime { get; set; }
/// <summary> /// <summary>
/// Gets all top-level type definitions. /// Gets all top-level type definitions.

Loading…
Cancel
Save