From deb6bcd37746d9569e53f3ea1c4a7d1f4536edef Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Tue, 27 Mar 2012 20:49:22 +0200 Subject: [PATCH 1/3] Add CancellationToken to AXmlParser. --- ICSharpCode.NRefactory.Xml/AXmlParser.cs | 36 ++++++++++++------- .../TagMatchingHeuristics.cs | 9 +++-- ICSharpCode.NRefactory.Xml/TagReader.cs | 8 +++-- 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/ICSharpCode.NRefactory.Xml/AXmlParser.cs b/ICSharpCode.NRefactory.Xml/AXmlParser.cs index dfee11174d..d2c327ef30 100644 --- a/ICSharpCode.NRefactory.Xml/AXmlParser.cs +++ b/ICSharpCode.NRefactory.Xml/AXmlParser.cs @@ -20,6 +20,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using System.Threading; using System.Xml.Linq; using ICSharpCode.NRefactory.Editor; using ICSharpCode.NRefactory.Utils; @@ -51,12 +52,13 @@ namespace ICSharpCode.NRefactory.Xml /// Parses a document into a flat list of tags. /// /// Parsed tag soup. - public IList ParseTagSoup(ITextSource textSource) + public IList ParseTagSoup(ITextSource textSource, + CancellationToken cancellationToken = default(CancellationToken)) { if (textSource == null) throw new ArgumentNullException("textSource"); var reader = new TagReader(this, textSource, false); - var internalObjects = reader.ReadAllObjects(); + var internalObjects = reader.ReadAllObjects(cancellationToken); return CreatePublic(internalObjects); } @@ -66,16 +68,21 @@ namespace ICSharpCode.NRefactory.Xml /// The parser state from a previous call to ParseIncremental(). Use null for the first call. /// The text source for the new document version. /// Out: the new parser state, pass this to the next ParseIncremental() call. + /// Optional: cancellation token. /// Parsed tag soup. - public IList ParseTagSoupIncremental(IncrementalParserState oldParserState, ITextSource newTextSource, out IncrementalParserState newParserState) + public IList ParseTagSoupIncremental( + IncrementalParserState oldParserState, ITextSource newTextSource, out IncrementalParserState newParserState, + CancellationToken cancellationToken = default(CancellationToken)) { if (newTextSource == null) throw new ArgumentNullException("newTextSource"); - var internalObjects = InternalParseIncremental(oldParserState, newTextSource, out newParserState, false); + var internalObjects = InternalParseIncremental(oldParserState, newTextSource, out newParserState, false, cancellationToken); return CreatePublic(internalObjects); } - List InternalParseIncremental(IncrementalParserState oldParserState, ITextSource newTextSource, out IncrementalParserState newParserState, bool collapseProperlyNestedElements) + List InternalParseIncremental( + IncrementalParserState oldParserState, ITextSource newTextSource, out IncrementalParserState newParserState, + bool collapseProperlyNestedElements, CancellationToken cancellationToken) { var reader = new TagReader(this, newTextSource, collapseProperlyNestedElements); ITextSourceVersion newVersion = newTextSource.Version; @@ -83,9 +90,9 @@ namespace ICSharpCode.NRefactory.Xml List internalObjects; if (reuseMap != null) - internalObjects = reader.ReadAllObjectsIncremental(oldParserState.Objects, reuseMap); + internalObjects = reader.ReadAllObjectsIncremental(oldParserState.Objects, reuseMap, cancellationToken); else - internalObjects = reader.ReadAllObjects(); + internalObjects = reader.ReadAllObjects(cancellationToken); if (newVersion != null) newParserState = new IncrementalParserState(newTextSource.TextLength, newVersion, internalObjects.ToArray()); @@ -98,14 +105,14 @@ namespace ICSharpCode.NRefactory.Xml /// /// Parses a document. /// - public AXmlDocument Parse(ITextSource textSource) + public AXmlDocument Parse(ITextSource textSource, CancellationToken cancellationToken = default(CancellationToken)) { if (textSource == null) throw new ArgumentNullException("textSource"); var reader = new TagReader(this, textSource, true); - var internalObjects = reader.ReadAllObjects(); + var internalObjects = reader.ReadAllObjects(cancellationToken); var heuristic = new TagMatchingHeuristics(textSource); - return new AXmlDocument(null, 0, heuristic.CreateDocument(internalObjects)); + return new AXmlDocument(null, 0, heuristic.CreateDocument(internalObjects, cancellationToken)); } /// @@ -114,14 +121,17 @@ namespace ICSharpCode.NRefactory.Xml /// The parser state from a previous call to ParseIncremental(). Use null for the first call. /// The text source for the new document version. /// Out: the new parser state, pass this to the next ParseIncremental() call. + /// Optional: cancellation token. /// Parsed tag soup. - 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) 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); - return new AXmlDocument(null, 0, heuristic.CreateDocument(internalObjects)); + return new AXmlDocument(null, 0, heuristic.CreateDocument(internalObjects, cancellationToken)); } } } diff --git a/ICSharpCode.NRefactory.Xml/TagMatchingHeuristics.cs b/ICSharpCode.NRefactory.Xml/TagMatchingHeuristics.cs index 2772f44b35..dc997d9907 100644 --- a/ICSharpCode.NRefactory.Xml/TagMatchingHeuristics.cs +++ b/ICSharpCode.NRefactory.Xml/TagMatchingHeuristics.cs @@ -20,6 +20,7 @@ using System; using System.Linq; using System.Collections.Generic; using System.Diagnostics; +using System.Threading; using ICSharpCode.NRefactory.Editor; using ICSharpCode.NRefactory.Utils; @@ -28,6 +29,7 @@ namespace ICSharpCode.NRefactory.Xml class TagMatchingHeuristics { readonly ITextSource textSource; + const int MaxConfigurationCount = 30; public TagMatchingHeuristics(ITextSource textSource) @@ -35,9 +37,9 @@ namespace ICSharpCode.NRefactory.Xml this.textSource = textSource; } - public InternalDocument CreateDocument(List tagSoup) + public InternalDocument CreateDocument(List tagSoup, CancellationToken cancellationToken) { - var stack = InsertPlaceholderTags(tagSoup); + var stack = InsertPlaceholderTags(tagSoup, cancellationToken); InternalDocument doc = new InternalDocument(); var docElements = CreateElements(ref stack); docElements.Reverse(); // reverse due to stack @@ -201,7 +203,7 @@ namespace ICSharpCode.NRefactory.Xml return indentation; } - ImmutableStack InsertPlaceholderTags(List objects) + ImmutableStack InsertPlaceholderTags(List objects, CancellationToken cancellationToken) { // Calculate indentation levels in front of the tags: int[] indentationBeforeTags = new int[objects.Count]; @@ -218,6 +220,7 @@ namespace ICSharpCode.NRefactory.Xml listA.Add(new Configuration(new OpenTagStack(), ImmutableStack.Empty, 0)); for (int i = 0; i < indentationBeforeTags.Length; i++) { + cancellationToken.ThrowIfCancellationRequested(); ProcessObject(objects[i], indentationBeforeTags[i], listA, ref listB); Swap(ref listA, ref listB); } diff --git a/ICSharpCode.NRefactory.Xml/TagReader.cs b/ICSharpCode.NRefactory.Xml/TagReader.cs index e6178de37d..ef6e424c1e 100644 --- a/ICSharpCode.NRefactory.Xml/TagReader.cs +++ b/ICSharpCode.NRefactory.Xml/TagReader.cs @@ -22,6 +22,7 @@ using System.Diagnostics; using System.Globalization; using System.Linq; using System.Text; +using System.Threading; using ICSharpCode.NRefactory.Editor; namespace ICSharpCode.NRefactory.Xml @@ -38,21 +39,23 @@ namespace ICSharpCode.NRefactory.Xml elementNameStack = new Stack(); } - public List ReadAllObjects() + public List ReadAllObjects(CancellationToken cancellationToken) { while (HasMoreData()) { + cancellationToken.ThrowIfCancellationRequested(); ReadObject(); } return objects; } - public List ReadAllObjectsIncremental(InternalObject[] oldObjects, List reuseMap) + public List ReadAllObjectsIncremental(InternalObject[] oldObjects, List reuseMap, CancellationToken cancellationToken) { ObjectIterator oldObjectIterator = new ObjectIterator(oldObjects); int reuseMapIndex = 0; while (reuseMapIndex < reuseMap.Count) { var reuseEntry = reuseMap[reuseMapIndex]; while (this.CurrentLocation < reuseEntry.NewOffset) { + cancellationToken.ThrowIfCancellationRequested(); ReadObject(); } if (this.CurrentLocation >= reuseEntry.NewOffset + reuseEntry.Length) { @@ -80,6 +83,7 @@ namespace ICSharpCode.NRefactory.Xml } } while (HasMoreData()) { + cancellationToken.ThrowIfCancellationRequested(); ReadObject(); } return objects; From 4f471705358c034d10ea88d46f4ee0f0ca02d27b Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Thu, 29 Mar 2012 21:47:59 +0200 Subject: [PATCH 2/3] Fixed type inference bug introduced in 2e40a34 - array covariance was ignored. --- .../Resolver/TypeInference.cs | 27 ++++++++++++++++--- .../CSharp/Resolver/ExtensionMethodTests.cs | 17 ++++++++++++ .../CSharp/Resolver/TypeInferenceTests.cs | 22 +++++++++++++++ 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/TypeInference.cs b/ICSharpCode.NRefactory.CSharp/Resolver/TypeInference.cs index 5a7118ec55..d176e9b7c6 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/TypeInference.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/TypeInference.cs @@ -629,12 +629,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver // Handle array types: ArrayType arrU = U as ArrayType; ArrayType arrV = V as ArrayType; + ParameterizedType pV = V as ParameterizedType; if (arrU != null && arrV != null && arrU.Dimensions == arrV.Dimensions) { MakeLowerBoundInference(arrU.ElementType, arrV.ElementType); return; + } else if (arrU != null && IsGenericInterfaceImplementedByArray(pV) && arrU.Dimensions == 1) { + MakeLowerBoundInference(arrU.ElementType, pV.GetTypeArgument(0)); + return; } // Handle parameterized types: - ParameterizedType pV = V as ParameterizedType; if (pV != null) { ParameterizedType uniqueBaseType = null; foreach (IType baseU in U.GetAllBaseTypes()) { @@ -674,6 +677,21 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver 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 #region MakeUpperBoundInference (§7.5.2.10) @@ -696,12 +714,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver // Handle array types: ArrayType arrU = U as ArrayType; ArrayType arrV = V as ArrayType; + ParameterizedType pU = U as ParameterizedType; if (arrV != null && arrU != null && arrU.Dimensions == arrV.Dimensions) { MakeUpperBoundInference(arrU.ElementType, arrV.ElementType); return; - } + } else if (arrV != null && IsGenericInterfaceImplementedByArray(pU) && arrV.Dimensions == 1) { + MakeUpperBoundInference(pU.GetTypeArgument(0), arrV.ElementType); + return; + } // Handle parameterized types: - ParameterizedType pU = U as ParameterizedType; if (pU != null) { ParameterizedType uniqueBaseType = null; foreach (IType baseV in V.GetAllBaseTypes()) { diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ExtensionMethodTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ExtensionMethodTests.cs index aca87a4fce..098deaa421 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ExtensionMethodTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ExtensionMethodTests.cs @@ -101,5 +101,22 @@ public static class XC { Assert.AreEqual("XC.Filter", mrr.Member.FullName); 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(this IEnumerable source) {}$ +} +"; + var mrr = Resolve(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); + } } } diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/TypeInferenceTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/TypeInferenceTests.cs index 81481006c5..287cfc9bd5 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/TypeInferenceTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/TypeInferenceTests.cs @@ -126,6 +126,28 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver out 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(IList 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 #region Inference with Method Groups From 444fe4ebf727dbc4e49b9d1279257392f4303886 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Thu, 29 Mar 2012 22:34:11 +0200 Subject: [PATCH 3/3] Make IParsedFile.LastWriteTime nullable. Replace IAXmlVisitor interface with AXmlVisitor abstract base class. --- .../Refactoring/CodeIssue.cs | 13 +++-- .../Refactoring/DocumentScript.cs | 1 + .../TypeSystem/CSharpParsedFile.cs | 4 +- ICSharpCode.NRefactory.Xml/AXmlAttribute.cs | 2 +- ICSharpCode.NRefactory.Xml/AXmlDocument.cs | 7 ++- ICSharpCode.NRefactory.Xml/AXmlElement.cs | 2 +- ICSharpCode.NRefactory.Xml/AXmlObject.cs | 2 +- ICSharpCode.NRefactory.Xml/AXmlTag.cs | 2 +- ICSharpCode.NRefactory.Xml/AXmlText.cs | 2 +- .../{IAXmlVisitor.cs => AXmlVisitor.cs} | 47 +++++++++++++------ .../ICSharpCode.NRefactory.Xml.csproj | 2 +- .../TypeSystem/IParsedFile.cs | 2 +- 12 files changed, 57 insertions(+), 29 deletions(-) rename ICSharpCode.NRefactory.Xml/{IAXmlVisitor.cs => AXmlVisitor.cs} (55%) diff --git a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssue.cs b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssue.cs index 435ed304f6..3676e3df65 100644 --- a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssue.cs +++ b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssue.cs @@ -1,6 +1,6 @@ -// +// // InspectionIssue.cs -// +// // Author: // Mike Krüger // @@ -46,17 +46,20 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring private set; } - public IEnumerable Actions { + public IList Actions { get; private set; } - public CodeIssue(string description, TextLocation start, TextLocation end, IEnumerable action = null) + public CodeIssue(string description, TextLocation start, TextLocation end, IEnumerable actions = null) { Desription = description; Start = start; End = end; - Actions = action ?? Enumerable.Empty (); + if (actions != null) + Actions = actions.ToArray(); + else + Actions = EmptyList.Instance; } public CodeIssue(string description, TextLocation start, TextLocation end, CodeAction action) : this (description, start, end, action != null ? new [] { action } : null) diff --git a/ICSharpCode.NRefactory.CSharp/Refactoring/DocumentScript.cs b/ICSharpCode.NRefactory.CSharp/Refactoring/DocumentScript.cs index 510bd8e229..99fcc6ebe9 100644 --- a/ICSharpCode.NRefactory.CSharp/Refactoring/DocumentScript.cs +++ b/ICSharpCode.NRefactory.CSharp/Refactoring/DocumentScript.cs @@ -46,6 +46,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring this.originalDocument = document.CreateDocumentSnapshot(); this.currentDocument = document; this.options = options; + this.eolMarker = options.EolMarker; Debug.Assert(currentDocument.Version.CompareAge(originalDocument.Version) == 0); this.undoGroup = document.OpenUndoGroup(); } diff --git a/ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpParsedFile.cs b/ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpParsedFile.cs index b2b73947c7..889fde118a 100644 --- a/ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpParsedFile.cs +++ b/ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpParsedFile.cs @@ -73,9 +73,9 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem get { return fileName; } } - DateTime lastWriteTime = DateTime.UtcNow; + DateTime? lastWriteTime; - public DateTime LastWriteTime { + public DateTime? LastWriteTime { get { return lastWriteTime; } set { FreezableHelper.ThrowIfFrozen(this); diff --git a/ICSharpCode.NRefactory.Xml/AXmlAttribute.cs b/ICSharpCode.NRefactory.Xml/AXmlAttribute.cs index f792434be0..999f019569 100644 --- a/ICSharpCode.NRefactory.Xml/AXmlAttribute.cs +++ b/ICSharpCode.NRefactory.Xml/AXmlAttribute.cs @@ -104,7 +104,7 @@ namespace ICSharpCode.NRefactory.Xml } /// - public override void AcceptVisitor(IAXmlVisitor visitor) + public override void AcceptVisitor(AXmlVisitor visitor) { visitor.VisitAttribute(this); } diff --git a/ICSharpCode.NRefactory.Xml/AXmlDocument.cs b/ICSharpCode.NRefactory.Xml/AXmlDocument.cs index 64ec7b0498..b525c9ae4d 100644 --- a/ICSharpCode.NRefactory.Xml/AXmlDocument.cs +++ b/ICSharpCode.NRefactory.Xml/AXmlDocument.cs @@ -45,7 +45,7 @@ namespace ICSharpCode.NRefactory.Xml } /// - public override void AcceptVisitor(IAXmlVisitor visitor) + public override void AcceptVisitor(AXmlVisitor visitor) { visitor.VisitDocument(this); } @@ -55,5 +55,10 @@ namespace ICSharpCode.NRefactory.Xml { return string.Format(CultureInfo.InvariantCulture, "[{0} Chld:{1}]", base.ToString(), this.Children.Count); } + + /// + /// Represents an empty document. + /// + public readonly static AXmlDocument Empty = new AXmlDocument(null, 0, new InternalDocument()); } } diff --git a/ICSharpCode.NRefactory.Xml/AXmlElement.cs b/ICSharpCode.NRefactory.Xml/AXmlElement.cs index 4495422585..a71c95b54a 100644 --- a/ICSharpCode.NRefactory.Xml/AXmlElement.cs +++ b/ICSharpCode.NRefactory.Xml/AXmlElement.cs @@ -164,7 +164,7 @@ namespace ICSharpCode.NRefactory.Xml } /// - public override void AcceptVisitor(IAXmlVisitor visitor) + public override void AcceptVisitor(AXmlVisitor visitor) { visitor.VisitElement(this); } diff --git a/ICSharpCode.NRefactory.Xml/AXmlObject.cs b/ICSharpCode.NRefactory.Xml/AXmlObject.cs index ac1258a39d..5ad0dde396 100644 --- a/ICSharpCode.NRefactory.Xml/AXmlObject.cs +++ b/ICSharpCode.NRefactory.Xml/AXmlObject.cs @@ -179,7 +179,7 @@ namespace ICSharpCode.NRefactory.Xml #endregion /// Call appropriate visit method on the given visitor - public abstract void AcceptVisitor(IAXmlVisitor visitor); + public abstract void AcceptVisitor(AXmlVisitor visitor); /// /// Gets the start offset of the segment. diff --git a/ICSharpCode.NRefactory.Xml/AXmlTag.cs b/ICSharpCode.NRefactory.Xml/AXmlTag.cs index c8e211a504..16a528f636 100644 --- a/ICSharpCode.NRefactory.Xml/AXmlTag.cs +++ b/ICSharpCode.NRefactory.Xml/AXmlTag.cs @@ -84,7 +84,7 @@ namespace ICSharpCode.NRefactory.Xml public bool IsUnknownBang { get { return internalObject.IsUnknownBang; } } /// - public override void AcceptVisitor(IAXmlVisitor visitor) + public override void AcceptVisitor(AXmlVisitor visitor) { visitor.VisitTag(this); } diff --git a/ICSharpCode.NRefactory.Xml/AXmlText.cs b/ICSharpCode.NRefactory.Xml/AXmlText.cs index f07895a5b6..d291dbe1a6 100644 --- a/ICSharpCode.NRefactory.Xml/AXmlText.cs +++ b/ICSharpCode.NRefactory.Xml/AXmlText.cs @@ -49,7 +49,7 @@ namespace ICSharpCode.NRefactory.Xml } /// - public override void AcceptVisitor(IAXmlVisitor visitor) + public override void AcceptVisitor(AXmlVisitor visitor) { visitor.VisitText(this); } diff --git a/ICSharpCode.NRefactory.Xml/IAXmlVisitor.cs b/ICSharpCode.NRefactory.Xml/AXmlVisitor.cs similarity index 55% rename from ICSharpCode.NRefactory.Xml/IAXmlVisitor.cs rename to ICSharpCode.NRefactory.Xml/AXmlVisitor.cs index bd0eeaf74d..9180ff58ce 100644 --- a/ICSharpCode.NRefactory.Xml/IAXmlVisitor.cs +++ b/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 // software and associated documentation files (the "Software"), to deal in the Software @@ -17,27 +17,46 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.Text; namespace ICSharpCode.NRefactory.Xml { /// - /// Visitor for the XML tree + /// Derive from this class to create visitor for the XML tree /// - public interface IAXmlVisitor + public abstract class AXmlVisitor { - /// Visit document - void VisitDocument(AXmlDocument document); + /// Visit AXmlDocument + public virtual void VisitDocument(AXmlDocument document) + { + foreach (AXmlObject child in document.Children) + child.AcceptVisitor(this); + } - /// Visit tag - void VisitTag(AXmlTag tag); + /// Visit AXmlElement + public virtual void VisitElement(AXmlElement element) + { + foreach (AXmlObject child in element.Children) + child.AcceptVisitor(this); + } - /// Visit attribute - void VisitAttribute(AXmlAttribute attribute); + /// Visit AXmlTag + public virtual void VisitTag(AXmlTag tag) + { + foreach (AXmlObject child in tag.Children) + child.AcceptVisitor(this); + } - /// Visit text - void VisitText(AXmlText text); + /// Visit AXmlAttribute + public virtual void VisitAttribute(AXmlAttribute attribute) + { + + } - /// Visit element - void VisitElement(AXmlElement element); + /// Visit AXmlText + public virtual void VisitText(AXmlText text) + { + + } } -} +} \ No newline at end of file diff --git a/ICSharpCode.NRefactory.Xml/ICSharpCode.NRefactory.Xml.csproj b/ICSharpCode.NRefactory.Xml/ICSharpCode.NRefactory.Xml.csproj index d59380abda..e98d2e0a8d 100644 --- a/ICSharpCode.NRefactory.Xml/ICSharpCode.NRefactory.Xml.csproj +++ b/ICSharpCode.NRefactory.Xml/ICSharpCode.NRefactory.Xml.csproj @@ -68,8 +68,8 @@ + - diff --git a/ICSharpCode.NRefactory/TypeSystem/IParsedFile.cs b/ICSharpCode.NRefactory/TypeSystem/IParsedFile.cs index 07863c799f..0a9a04f83e 100644 --- a/ICSharpCode.NRefactory/TypeSystem/IParsedFile.cs +++ b/ICSharpCode.NRefactory/TypeSystem/IParsedFile.cs @@ -34,7 +34,7 @@ namespace ICSharpCode.NRefactory.TypeSystem /// /// Gets the time when the file was last written. /// - DateTime LastWriteTime { get; } + DateTime? LastWriteTime { get; set; } /// /// Gets all top-level type definitions.