diff --git a/ICSharpCode.NRefactory/CSharp/Resolver/IResolveVisitorNavigator.cs b/ICSharpCode.NRefactory/CSharp/Resolver/IResolveVisitorNavigator.cs
index 4db0fc1a86..6967f42606 100644
--- a/ICSharpCode.NRefactory/CSharp/Resolver/IResolveVisitorNavigator.cs
+++ b/ICSharpCode.NRefactory/CSharp/Resolver/IResolveVisitorNavigator.cs
@@ -5,11 +5,19 @@ using System;
namespace ICSharpCode.NRefactory.CSharp.Resolver
{
+ ///
+ /// Allows controlling which nodes are resolved by the resolve visitor.
+ ///
+ ///
public interface IResolveVisitorNavigator
{
ResolveVisitorNavigationMode Scan(INode node);
}
+ ///
+ /// Represents the operation mode of the resolve visitor.
+ ///
+ ///
public enum ResolveVisitorNavigationMode
{
///
diff --git a/ICSharpCode.NRefactory/CSharp/Resolver/NodeListResolveVisitorNavigator.cs b/ICSharpCode.NRefactory/CSharp/Resolver/NodeListResolveVisitorNavigator.cs
new file mode 100644
index 0000000000..8cdb3781b8
--- /dev/null
+++ b/ICSharpCode.NRefactory/CSharp/Resolver/NodeListResolveVisitorNavigator.cs
@@ -0,0 +1,42 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
+
+using System;
+using System.Collections.Generic;
+
+namespace ICSharpCode.NRefactory.CSharp.Resolver
+{
+ ///
+ /// implementation that resolves a list of nodes.
+ /// We will skip all nodes which are not the target nodes or ancestors of the target nodes.
+ ///
+ public sealed class NodeListResolveVisitorNavigator : IResolveVisitorNavigator
+ {
+ readonly Dictionary dict = new Dictionary();
+
+ ///
+ /// Creates a new NodeListResolveVisitorNavigator that resolves the specified nodes.
+ ///
+ public NodeListResolveVisitorNavigator(IEnumerable nodes)
+ {
+ if (nodes == null)
+ throw new ArgumentNullException("nodes");
+ foreach (INode node in nodes) {
+ dict[node] = ResolveVisitorNavigationMode.Resolve;
+ for (INode ancestor = node.Parent; ancestor != null && !dict.ContainsKey(ancestor); ancestor = ancestor.Parent) {
+ dict.Add(ancestor, ResolveVisitorNavigationMode.Scan);
+ }
+ }
+ }
+
+ ///
+ public ResolveVisitorNavigationMode Scan(INode node)
+ {
+ ResolveVisitorNavigationMode mode;
+ if (dict.TryGetValue(node, out mode))
+ return mode;
+ else
+ return ResolveVisitorNavigationMode.Skip;
+ }
+ }
+}
diff --git a/ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs b/ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs
index 3b53d268f0..8c26a665e8 100644
--- a/ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs
+++ b/ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs
@@ -3,8 +3,8 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Linq;
-
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
@@ -16,22 +16,51 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
///
/// The ResolveVisitor does two jobs at the same time: it tracks the resolve context (properties on CSharpResolver)
/// and it resolves the expressions visited.
- /// To allow using the context tracking without having to resolve every expression in the file (e.g.
+ /// To allow using the context tracking without having to resolve every expression in the file (e.g. when you want to resolve
+ /// only a single node deep within the DOM), you can use the interface.
+ /// The navigator allows you to switch the between scanning mode and resolving mode.
+ /// In scanning mode, the context is tracked (local variables registered etc.), but nodes are not resolved.
+ /// While scanning, the navigator will get asked about every node that the resolve visitor is about to enter.
+ /// This allows the navigator whether to keep scanning, whether switch to resolving mode, or whether to completely skip the
+ /// subtree rooted at that node.
+ ///
+ /// In resolving mode, the context is tracked and nodes will be resolved.
+ /// The resolve visitor may decide that it needs to resolve other nodes as well in order to resolve the current node.
+ /// In this case, those nodes will be resolved automatically, without asking the navigator interface.
+ /// For child nodes that are not essential to resolving, the resolve visitor will switch back to scanning mode (and thus will
+ /// ask the navigator for further instructions).
+ ///
+ /// Moreover, there is the ResolveAll mode - it works similar to resolving mode, but will not switch back to scanning mode.
+ /// The whole subtree will be resolved without notifying the navigator.
///
public class ResolveVisitor : AbstractDomVisitor