|
|
@ -26,16 +26,13 @@ using ICSharpCode.NRefactory.Utils; |
|
|
|
|
|
|
|
|
|
|
|
namespace ICSharpCode.NRefactory.CSharp.Resolver |
|
|
|
namespace ICSharpCode.NRefactory.CSharp.Resolver |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
public delegate void FoundReferenceCallback(AstNode astNode, ResolveResult result); |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <summary>
|
|
|
|
/// 'Find references' implementation.
|
|
|
|
/// 'Find references' implementation.
|
|
|
|
/// </summary>
|
|
|
|
/// </summary>
|
|
|
|
public class FindReferences |
|
|
|
public class FindReferences |
|
|
|
{ |
|
|
|
{ |
|
|
|
/// <summary>
|
|
|
|
|
|
|
|
/// Callback that is invoked whenever a reference is found.
|
|
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
|
|
public event Action<AstNode, ResolveResult> ReferenceFound; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region Properties
|
|
|
|
#region Properties
|
|
|
|
/// <summary>
|
|
|
|
/// <summary>
|
|
|
|
/// Gets/Sets the cancellation token.
|
|
|
|
/// Gets/Sets the cancellation token.
|
|
|
@ -95,28 +92,32 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver |
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region class SearchScope
|
|
|
|
#region class SearchScope
|
|
|
|
public abstract class SearchScope : IResolveVisitorNavigator |
|
|
|
abstract class SearchScope : IResolveVisitorNavigator, IFindReferenceSearchScope |
|
|
|
{ |
|
|
|
{ |
|
|
|
protected string searchTerm; |
|
|
|
protected string searchTerm; |
|
|
|
internal Accessibility accessibility; |
|
|
|
internal Accessibility accessibility; |
|
|
|
internal ITypeDefinition topLevelTypeDefinition; |
|
|
|
internal ITypeDefinition topLevelTypeDefinition; |
|
|
|
internal FindReferences findReferences; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
FoundReferenceCallback callback; |
|
|
|
/// Gets the search term. Only files that contain this identifier need to be parsed.
|
|
|
|
|
|
|
|
/// Can return null if all files need to be parsed.
|
|
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
|
|
public string SearchTerm { get { return searchTerm; } } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
IResolveVisitorNavigator IFindReferenceSearchScope.GetNavigator(FoundReferenceCallback callback) |
|
|
|
/// Gets the accessibility that defines the search scope.
|
|
|
|
{ |
|
|
|
/// </summary>
|
|
|
|
SearchScope n = (SearchScope)MemberwiseClone(); |
|
|
|
public Accessibility Accessibility { get { return accessibility; } } |
|
|
|
n.callback = callback; |
|
|
|
|
|
|
|
return n; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
string IFindReferenceSearchScope.SearchTerm { |
|
|
|
/// Gets the top-level entity that defines the search scope.
|
|
|
|
get { return searchTerm; } |
|
|
|
/// </summary>
|
|
|
|
} |
|
|
|
public ITypeDefinition TopLevelTypeDefinition { get { return topLevelTypeDefinition; } } |
|
|
|
|
|
|
|
|
|
|
|
Accessibility IFindReferenceSearchScope.Accessibility { |
|
|
|
|
|
|
|
get { return accessibility; } |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ITypeDefinition IFindReferenceSearchScope.TopLevelTypeDefinition { |
|
|
|
|
|
|
|
get { return topLevelTypeDefinition; } |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
internal abstract bool CanMatch(AstNode node); |
|
|
|
internal abstract bool CanMatch(AstNode node); |
|
|
|
internal abstract bool IsMatch(ResolveResult rr); |
|
|
|
internal abstract bool IsMatch(ResolveResult rr); |
|
|
@ -147,15 +148,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver |
|
|
|
|
|
|
|
|
|
|
|
protected void ReportMatch(AstNode node, ResolveResult result) |
|
|
|
protected void ReportMatch(AstNode node, ResolveResult result) |
|
|
|
{ |
|
|
|
{ |
|
|
|
var referenceFound = findReferences.ReferenceFound; |
|
|
|
if (callback != null) |
|
|
|
if (referenceFound != null) |
|
|
|
callback(node, result); |
|
|
|
referenceFound(node, result); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region GetSearchScopes
|
|
|
|
#region GetSearchScopes
|
|
|
|
public IList<SearchScope> GetSearchScopes(IEntity entity) |
|
|
|
public IList<IFindReferenceSearchScope> GetSearchScopes(IEntity entity) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (entity == null) |
|
|
|
if (entity == null) |
|
|
|
throw new ArgumentNullException("entity"); |
|
|
|
throw new ArgumentNullException("entity"); |
|
|
@ -196,19 +196,17 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver |
|
|
|
additionalScope = new FindChainedConstructorReferences(ctor); |
|
|
|
additionalScope = new FindChainedConstructorReferences(ctor); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case EntityType.Destructor: |
|
|
|
case EntityType.Destructor: |
|
|
|
return EmptyList<SearchScope>.Instance; |
|
|
|
return EmptyList<IFindReferenceSearchScope>.Instance; |
|
|
|
default: |
|
|
|
default: |
|
|
|
throw new ArgumentException("Unknown entity type " + entity.EntityType); |
|
|
|
throw new ArgumentException("Unknown entity type " + entity.EntityType); |
|
|
|
} |
|
|
|
} |
|
|
|
if (scope.accessibility == Accessibility.None) |
|
|
|
if (scope.accessibility == Accessibility.None) |
|
|
|
scope.accessibility = effectiveAccessibility; |
|
|
|
scope.accessibility = effectiveAccessibility; |
|
|
|
scope.topLevelTypeDefinition = topLevelTypeDefinition; |
|
|
|
scope.topLevelTypeDefinition = topLevelTypeDefinition; |
|
|
|
scope.findReferences = this; |
|
|
|
|
|
|
|
if (additionalScope != null) { |
|
|
|
if (additionalScope != null) { |
|
|
|
if (additionalScope.accessibility == Accessibility.None) |
|
|
|
if (additionalScope.accessibility == Accessibility.None) |
|
|
|
additionalScope.accessibility = effectiveAccessibility; |
|
|
|
additionalScope.accessibility = effectiveAccessibility; |
|
|
|
additionalScope.topLevelTypeDefinition = topLevelTypeDefinition; |
|
|
|
additionalScope.topLevelTypeDefinition = topLevelTypeDefinition; |
|
|
|
additionalScope.findReferences = this; |
|
|
|
|
|
|
|
return new[] { scope, additionalScope }; |
|
|
|
return new[] { scope, additionalScope }; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
return new[] { scope }; |
|
|
|
return new[] { scope }; |
|
|
@ -220,7 +218,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver |
|
|
|
/// <summary>
|
|
|
|
/// <summary>
|
|
|
|
/// Gets the file names that possibly contain references to the element being searched for.
|
|
|
|
/// Gets the file names that possibly contain references to the element being searched for.
|
|
|
|
/// </summary>
|
|
|
|
/// </summary>
|
|
|
|
public IList<string> GetInterestingFileNames(SearchScope searchScope, IEnumerable<ITypeDefinition> allTypes, ITypeResolveContext context) |
|
|
|
public IList<string> GetInterestingFileNames(IFindReferenceSearchScope searchScope, IEnumerable<ITypeDefinition> allTypes, ITypeResolveContext context) |
|
|
|
{ |
|
|
|
{ |
|
|
|
IEnumerable<ITypeDefinition> interestingTypes; |
|
|
|
IEnumerable<ITypeDefinition> interestingTypes; |
|
|
|
if (searchScope.TopLevelTypeDefinition != null) { |
|
|
|
if (searchScope.TopLevelTypeDefinition != null) { |
|
|
@ -276,11 +274,13 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver |
|
|
|
/// <param name="parsedFile">The type system representation of the file being searched.</param>
|
|
|
|
/// <param name="parsedFile">The type system representation of the file being searched.</param>
|
|
|
|
/// <param name="compilationUnit">The compilation unit of the file being searched.</param>
|
|
|
|
/// <param name="compilationUnit">The compilation unit of the file being searched.</param>
|
|
|
|
/// <param name="context">The type resolve context to use for resolving the file.</param>
|
|
|
|
/// <param name="context">The type resolve context to use for resolving the file.</param>
|
|
|
|
public void FindReferencesInFile(SearchScope searchScope, ParsedFile parsedFile, CompilationUnit compilationUnit, ITypeResolveContext context) |
|
|
|
/// <param name="callback">Callback used to report the references that were found.</param>
|
|
|
|
|
|
|
|
public void FindReferencesInFile(IFindReferenceSearchScope searchScope, ParsedFile parsedFile, CompilationUnit compilationUnit, |
|
|
|
|
|
|
|
ITypeResolveContext context, FoundReferenceCallback callback) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (searchScope == null) |
|
|
|
if (searchScope == null) |
|
|
|
throw new ArgumentNullException("searchScope"); |
|
|
|
throw new ArgumentNullException("searchScope"); |
|
|
|
FindReferencesInFile(new[] { searchScope }, parsedFile, compilationUnit, context); |
|
|
|
FindReferencesInFile(new[] { searchScope }, parsedFile, compilationUnit, context, callback); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <summary>
|
|
|
@ -290,7 +290,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver |
|
|
|
/// <param name="parsedFile">The type system representation of the file being searched.</param>
|
|
|
|
/// <param name="parsedFile">The type system representation of the file being searched.</param>
|
|
|
|
/// <param name="compilationUnit">The compilation unit of the file being searched.</param>
|
|
|
|
/// <param name="compilationUnit">The compilation unit of the file being searched.</param>
|
|
|
|
/// <param name="context">The type resolve context to use for resolving the file.</param>
|
|
|
|
/// <param name="context">The type resolve context to use for resolving the file.</param>
|
|
|
|
public void FindReferencesInFile(IList<SearchScope> searchScopes, ParsedFile parsedFile, CompilationUnit compilationUnit, ITypeResolveContext context) |
|
|
|
/// <param name="callback">Callback used to report the references that were found.</param>
|
|
|
|
|
|
|
|
public void FindReferencesInFile(IList<IFindReferenceSearchScope> searchScopes, ParsedFile parsedFile, CompilationUnit compilationUnit, |
|
|
|
|
|
|
|
ITypeResolveContext context, FoundReferenceCallback callback) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (searchScopes == null) |
|
|
|
if (searchScopes == null) |
|
|
|
throw new ArgumentNullException("searchScopes"); |
|
|
|
throw new ArgumentNullException("searchScopes"); |
|
|
@ -303,16 +305,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver |
|
|
|
this.CancellationToken.ThrowIfCancellationRequested(); |
|
|
|
this.CancellationToken.ThrowIfCancellationRequested(); |
|
|
|
if (searchScopes.Count == 0) |
|
|
|
if (searchScopes.Count == 0) |
|
|
|
return; |
|
|
|
return; |
|
|
|
foreach (SearchScope scope in searchScopes) { |
|
|
|
|
|
|
|
if (scope.findReferences != this) |
|
|
|
|
|
|
|
throw new ArgumentException("Cannot use a search scope that was created by another FindReferences instance"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
using (var ctx = context.Synchronize()) { |
|
|
|
using (var ctx = context.Synchronize()) { |
|
|
|
IResolveVisitorNavigator navigator; |
|
|
|
IResolveVisitorNavigator navigator; |
|
|
|
if (searchScopes.Count == 1) |
|
|
|
if (searchScopes.Count == 1) |
|
|
|
navigator = searchScopes[0]; |
|
|
|
navigator = searchScopes[0].GetNavigator(callback); |
|
|
|
else |
|
|
|
else |
|
|
|
navigator = new CompositeResolveVisitorNavigator(searchScopes.ToArray()); |
|
|
|
navigator = new CompositeResolveVisitorNavigator(searchScopes.Select(s => s.GetNavigator(callback)).ToArray()); |
|
|
|
navigator = new DetectSkippableNodesNavigator(navigator, compilationUnit); |
|
|
|
navigator = new DetectSkippableNodesNavigator(navigator, compilationUnit); |
|
|
|
CSharpResolver resolver = new CSharpResolver(ctx, this.CancellationToken); |
|
|
|
CSharpResolver resolver = new CSharpResolver(ctx, this.CancellationToken); |
|
|
|
ResolveVisitor v = new ResolveVisitor(resolver, parsedFile, navigator); |
|
|
|
ResolveVisitor v = new ResolveVisitor(resolver, parsedFile, navigator); |
|
|
|