diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/FindReferenceSearchScope.cs b/ICSharpCode.NRefactory.CSharp/Resolver/FindReferenceSearchScope.cs
index 3629035320..6bf4e04740 100644
--- a/ICSharpCode.NRefactory.CSharp/Resolver/FindReferenceSearchScope.cs
+++ b/ICSharpCode.NRefactory.CSharp/Resolver/FindReferenceSearchScope.cs
@@ -27,7 +27,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
public interface IFindReferenceSearchScope
{
///
- /// Gets the parent compilation for this search scope.
+ /// Gets the compilation in which the entity being search for was defined.
+ /// This is not necessarily the same compilation as is being searched in.
///
ICompilation Compilation { get; }
@@ -51,6 +52,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// Creates a navigator that can find references to this entity and reports
/// them to the specified callback.
///
- IResolveVisitorNavigator GetNavigator(FoundReferenceCallback callback);
+ IResolveVisitorNavigator GetNavigator(ICompilation compilation, FoundReferenceCallback callback);
}
}
diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/FindReferences.cs b/ICSharpCode.NRefactory.CSharp/Resolver/FindReferences.cs
index 15e10ba29d..331d8ec8c8 100644
--- a/ICSharpCode.NRefactory.CSharp/Resolver/FindReferences.cs
+++ b/ICSharpCode.NRefactory.CSharp/Resolver/FindReferences.cs
@@ -20,6 +20,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
+using ICSharpCode.NRefactory.CSharp.Refactoring;
using ICSharpCode.NRefactory.CSharp.TypeSystem;
using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.NRefactory.TypeSystem;
@@ -93,24 +94,39 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#endregion
#region class SearchScope
- abstract class SearchScope : IResolveVisitorNavigator, IFindReferenceSearchScope
+ sealed class SearchScope : IFindReferenceSearchScope
{
- protected string searchTerm;
- internal ICompilation compilation;
- internal Accessibility accessibility;
- internal ITypeDefinition topLevelTypeDefinition;
+ readonly Func factory;
- FoundReferenceCallback callback;
+ public SearchScope(Func factory)
+ {
+ this.factory = factory;
+ }
- ICompilation IFindReferenceSearchScope.Compilation {
- get { return compilation; }
+ public SearchScope(string searchTerm, Func factory)
+ {
+ this.searchTerm = searchTerm;
+ this.factory = factory;
}
- IResolveVisitorNavigator IFindReferenceSearchScope.GetNavigator(FoundReferenceCallback callback)
+ internal string searchTerm;
+ internal ICompilation declarationCompilation;
+ internal Accessibility accessibility;
+ internal ITypeDefinition topLevelTypeDefinition;
+
+ IResolveVisitorNavigator IFindReferenceSearchScope.GetNavigator(ICompilation compilation, FoundReferenceCallback callback)
{
- SearchScope n = (SearchScope)MemberwiseClone();
- n.callback = callback;
- return n;
+ FindReferenceNavigator n = factory(compilation);
+ if (n != null) {
+ n.callback = callback;
+ return n;
+ } else {
+ return new ConstantModeResolveVisitorNavigator(ResolveVisitorNavigationMode.Skip, null);
+ }
+ }
+
+ ICompilation IFindReferenceSearchScope.Compilation {
+ get { return declarationCompilation; }
}
string IFindReferenceSearchScope.SearchTerm {
@@ -124,6 +140,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ITypeDefinition IFindReferenceSearchScope.TopLevelTypeDefinition {
get { return topLevelTypeDefinition; }
}
+ }
+
+ abstract class FindReferenceNavigator : IResolveVisitorNavigator
+ {
+ internal FoundReferenceCallback callback;
internal abstract bool CanMatch(AstNode node);
internal abstract bool IsMatch(ResolveResult rr);
@@ -143,12 +164,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
}
- void IResolveVisitorNavigator.ProcessConversion(Expression expression, ResolveResult result, Conversion conversion, IType targetType)
- {
- ProcessConversion(expression, result, conversion, targetType);
- }
-
- internal virtual void ProcessConversion(Expression expression, ResolveResult result, Conversion conversion, IType targetType)
+ public virtual void ProcessConversion(Expression expression, ResolveResult result, Conversion conversion, IType targetType)
{
}
@@ -173,33 +189,33 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
SearchScope additionalScope = null;
switch (entity.EntityType) {
case EntityType.TypeDefinition:
- scope = new FindTypeDefinitionReferences((ITypeDefinition)entity, this.FindTypeReferencesEvenIfAliased);
+ scope = FindTypeDefinitionReferences((ITypeDefinition)entity, this.FindTypeReferencesEvenIfAliased);
break;
case EntityType.Field:
if (entity.DeclaringTypeDefinition != null && entity.DeclaringTypeDefinition.Kind == TypeKind.Enum)
- scope = new FindEnumMemberReferences((IField)entity);
+ scope = FindMemberReferences(entity, m => new FindEnumMemberReferences((IField)m));
else
- scope = new FindFieldReferences((IField)entity);
+ scope = FindMemberReferences(entity, m => new FindFieldReferences((IField)m));
break;
case EntityType.Property:
- scope = new FindPropertyReferences((IProperty)entity);
+ scope = FindMemberReferences(entity, m => new FindPropertyReferences((IProperty)m));
break;
case EntityType.Event:
- scope = new FindEventReferences((IEvent)entity);
+ scope = FindMemberReferences(entity, m => new FindEventReferences((IEvent)m));
break;
case EntityType.Method:
scope = GetSearchScopeForMethod((IMethod)entity);
break;
case EntityType.Indexer:
- scope = new FindIndexerReferences((IProperty)entity);
+ scope = FindIndexerReferences((IProperty)entity);
break;
case EntityType.Operator:
scope = GetSearchScopeForOperator((IMethod)entity);
break;
case EntityType.Constructor:
- IMethod ctor = (IMethod)entity;
- scope = new FindObjectCreateReferences(ctor);
- additionalScope = new FindChainedConstructorReferences(ctor);
+ IMethod ctor = (IMethod)((IMethod)entity).MemberDefinition;
+ scope = FindObjectCreateReferences(ctor);
+ additionalScope = FindChainedConstructorReferences(ctor);
break;
case EntityType.Destructor:
return EmptyList.Instance;
@@ -208,12 +224,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
if (scope.accessibility == Accessibility.None)
scope.accessibility = effectiveAccessibility;
- scope.compilation = entity.Compilation;
+ scope.declarationCompilation = entity.Compilation;
scope.topLevelTypeDefinition = topLevelTypeDefinition;
if (additionalScope != null) {
if (additionalScope.accessibility == Accessibility.None)
additionalScope.accessibility = effectiveAccessibility;
- additionalScope.compilation = entity.Compilation;
+ additionalScope.declarationCompilation = entity.Compilation;
additionalScope.topLevelTypeDefinition = topLevelTypeDefinition;
return new[] { scope, additionalScope };
} else {
@@ -284,11 +300,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// The type resolve context to use for resolving the file.
/// Callback used to report the references that were found.
public void FindReferencesInFile(IFindReferenceSearchScope searchScope, CSharpParsedFile parsedFile, CompilationUnit compilationUnit,
- FoundReferenceCallback callback, CancellationToken cancellationToken)
+ ICompilation compilation, FoundReferenceCallback callback, CancellationToken cancellationToken)
{
if (searchScope == null)
throw new ArgumentNullException("searchScope");
- FindReferencesInFile(new[] { searchScope }, parsedFile, compilationUnit, callback, cancellationToken);
+ FindReferencesInFile(new[] { searchScope }, parsedFile, compilationUnit, compilation, callback, cancellationToken);
}
///
@@ -300,7 +316,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// Callback used to report the references that were found.
/// Cancellation token.
public void FindReferencesInFile(IList searchScopes, CSharpParsedFile parsedFile, CompilationUnit compilationUnit,
- FoundReferenceCallback callback, CancellationToken cancellationToken)
+ ICompilation compilation, FoundReferenceCallback callback, CancellationToken cancellationToken)
{
if (searchScopes == null)
throw new ArgumentNullException("searchScopes");
@@ -308,41 +324,61 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
throw new ArgumentNullException("parsedFile");
if (compilationUnit == null)
throw new ArgumentNullException("compilationUnit");
+ if (compilation == null)
+ throw new ArgumentNullException("compilation");
+ if (callback == null)
+ throw new ArgumentNullException("callback");
if (searchScopes.Count == 0)
return;
- ICompilation compilation = searchScopes[0].Compilation;
IResolveVisitorNavigator navigator;
if (searchScopes.Count == 1) {
- navigator = searchScopes[0].GetNavigator(callback);
+ navigator = searchScopes[0].GetNavigator(compilation, callback);
} else {
IResolveVisitorNavigator[] navigators = new IResolveVisitorNavigator[searchScopes.Count];
for (int i = 0; i < navigators.Length; i++) {
- if (searchScopes[i].Compilation != compilation)
- throw new InvalidOperationException("All search scopes must belong to the same compilation");
- navigators[i] = searchScopes[i].GetNavigator(callback);
+ navigators[i] = searchScopes[i].GetNavigator(compilation, callback);
}
navigator = new CompositeResolveVisitorNavigator(navigators);
}
+ cancellationToken.ThrowIfCancellationRequested();
navigator = new DetectSkippableNodesNavigator(navigator, compilationUnit);
+ cancellationToken.ThrowIfCancellationRequested();
CSharpAstResolver resolver = new CSharpAstResolver(compilation, compilationUnit, parsedFile);
- resolver.ApplyNavigator(navigator);
+ resolver.ApplyNavigator(navigator, cancellationToken);
}
#endregion
#region Find TypeDefinition References
- sealed class FindTypeDefinitionReferences : SearchScope
+ SearchScope FindTypeDefinitionReferences(ITypeDefinition typeDefinition, bool findTypeReferencesEvenIfAliased)
+ {
+ string searchTerm = null;
+ if (!findTypeReferencesEvenIfAliased && ReflectionHelper.GetTypeCode(typeDefinition) == TypeCode.Empty) {
+ // not a built-in type
+ searchTerm = typeDefinition.Name;
+ }
+
+ return new SearchScope(
+ searchTerm,
+ delegate (ICompilation compilation) {
+ ITypeDefinition imported = compilation.Import(typeDefinition);
+ if (imported != null)
+ return new FindTypeDefinitionReferencesNavigator(imported, searchTerm);
+ else
+ return null;
+ });
+ }
+
+ sealed class FindTypeDefinitionReferencesNavigator : FindReferenceNavigator
{
- ITypeDefinition typeDefinition;
+ readonly ITypeDefinition typeDefinition;
+ readonly string searchTerm;
- public FindTypeDefinitionReferences(ITypeDefinition typeDefinition, bool findTypeReferencesEvenIfAliased)
+ public FindTypeDefinitionReferencesNavigator(ITypeDefinition typeDefinition, string searchTerm)
{
this.typeDefinition = typeDefinition;
- if (!findTypeReferencesEvenIfAliased && ReflectionHelper.GetTypeCode(typeDefinition) == TypeCode.Empty) {
- // not a built-in type
- this.searchTerm = typeDefinition.Name;
- }
+ this.searchTerm = searchTerm;
}
internal override bool CanMatch(AstNode node)
@@ -378,11 +414,24 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#endregion
#region Find Member References
- class FindMemberReferences : SearchScope
+ SearchScope FindMemberReferences(IEntity member, Func factory)
+ {
+ string searchTerm = member.Name;
+ IMember memberDefinition = ((IMember)member).MemberDefinition;
+ return new SearchScope(
+ searchTerm,
+ delegate(ICompilation compilation) {
+ IMember imported = compilation.Import(memberDefinition);
+ return imported != null ? factory(imported) : null;
+ });
+ }
+
+ class FindMemberReferencesNavigator : FindReferenceNavigator
{
readonly IMember member;
+ readonly string searchTerm;
- public FindMemberReferences(IMember member)
+ public FindMemberReferencesNavigator(IMember member)
{
this.member = member.MemberDefinition;
this.searchTerm = member.Name;
@@ -416,7 +465,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
}
- sealed class FindFieldReferences : FindMemberReferences
+ sealed class FindFieldReferences : FindMemberReferencesNavigator
{
public FindFieldReferences(IField field) : base(field)
{
@@ -431,7 +480,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
}
- sealed class FindEnumMemberReferences : FindMemberReferences
+ sealed class FindEnumMemberReferences : FindMemberReferencesNavigator
{
public FindEnumMemberReferences(IField field) : base(field)
{
@@ -443,7 +492,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
}
- sealed class FindPropertyReferences : FindMemberReferences
+ sealed class FindPropertyReferences : FindMemberReferencesNavigator
{
public FindPropertyReferences(IProperty property) : base(property)
{
@@ -455,7 +504,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
}
- sealed class FindEventReferences : FindMemberReferences
+ sealed class FindEventReferences : FindMemberReferencesNavigator
{
public FindEventReferences(IEvent ev) : base(ev)
{
@@ -474,46 +523,67 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#region Find Method References
SearchScope GetSearchScopeForMethod(IMethod method)
{
+ method = (IMethod)method.MemberDefinition;
+
+ Type specialNodeType;
switch (method.Name) {
case "Add":
- return new FindMethodReferences(method, typeof(ArrayInitializerExpression));
+ specialNodeType = typeof(ArrayInitializerExpression);
+ break;
case "Where":
- return new FindMethodReferences(method, typeof(QueryWhereClause));
+ specialNodeType = typeof(QueryWhereClause);
+ break;
case "Select":
- return new FindMethodReferences(method, typeof(QuerySelectClause));
+ specialNodeType = typeof(QuerySelectClause);
+ break;
case "SelectMany":
- return new FindMethodReferences(method, typeof(QueryFromClause));
+ specialNodeType = typeof(QueryFromClause);
+ break;
case "Join":
case "GroupJoin":
- return new FindMethodReferences(method, typeof(QueryJoinClause));
+ specialNodeType = typeof(QueryJoinClause);
+ break;
case "OrderBy":
case "OrderByDescending":
case "ThenBy":
case "ThenByDescending":
- return new FindMethodReferences(method, typeof(QueryOrdering));
+ specialNodeType = typeof(QueryOrdering);
+ break;
case "GroupBy":
- return new FindMethodReferences(method, typeof(QueryGroupClause));
+ specialNodeType = typeof(QueryGroupClause);
+ break;
case "Invoke":
if (method.DeclaringTypeDefinition != null && method.DeclaringTypeDefinition.Kind == TypeKind.Delegate)
- return new FindMethodReferences(method, typeof(InvocationExpression));
+ specialNodeType = typeof(InvocationExpression);
else
- return new FindMethodReferences(method);
+ specialNodeType = null;
+ break;
default:
- return new FindMethodReferences(method);
+ specialNodeType = null;
+ break;
}
+ // Use searchTerm only if specialNodeType==null
+ string searchTerm = (specialNodeType == null) ? method.Name : null;
+ return new SearchScope(
+ searchTerm,
+ delegate (ICompilation compilation) {
+ IMethod imported = compilation.Import(method);
+ if (imported != null)
+ return new FindMethodReferences(imported, specialNodeType);
+ else
+ return null;
+ });
}
- sealed class FindMethodReferences : SearchScope
+ sealed class FindMethodReferences : FindReferenceNavigator
{
readonly IMethod method;
readonly Type specialNodeType;
- public FindMethodReferences(IMethod method, Type specialNodeType = null)
+ public FindMethodReferences(IMethod method, Type specialNodeType)
{
- this.method = (IMethod)method.MemberDefinition;
+ this.method = method;
this.specialNodeType = specialNodeType;
- if (specialNodeType == null)
- this.searchTerm = method.Name;
}
internal override bool CanMatch(AstNode node)
@@ -549,13 +619,26 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#endregion
#region Find Indexer References
- sealed class FindIndexerReferences : SearchScope
+ SearchScope FindIndexerReferences(IProperty indexer)
+ {
+ indexer = (IProperty)indexer.MemberDefinition;
+ return new SearchScope(
+ delegate (ICompilation compilation) {
+ IProperty imported = compilation.Import(indexer);
+ if (imported != null)
+ return new FindIndexerReferencesNavigator(imported);
+ else
+ return null;
+ });
+ }
+
+ sealed class FindIndexerReferencesNavigator : FindReferenceNavigator
{
readonly IProperty indexer;
- public FindIndexerReferences(IProperty indexer)
+ public FindIndexerReferencesNavigator(IProperty indexer)
{
- this.indexer = (IProperty)indexer.MemberDefinition;
+ this.indexer = indexer;
}
internal override bool CanMatch(AstNode node)
@@ -576,73 +659,88 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
{
OperatorType? opType = OperatorDeclaration.GetOperatorType(op.Name);
if (opType == null)
- return new FindMethodReferences(op);
+ return GetSearchScopeForMethod(op);
switch (opType.Value) {
case OperatorType.LogicalNot:
- return new FindUnaryOperator(op, UnaryOperatorType.Not);
+ return FindUnaryOperator(op, UnaryOperatorType.Not);
case OperatorType.OnesComplement:
- return new FindUnaryOperator(op, UnaryOperatorType.BitNot);
+ return FindUnaryOperator(op, UnaryOperatorType.BitNot);
case OperatorType.UnaryPlus:
- return new FindUnaryOperator(op, UnaryOperatorType.Plus);
+ return FindUnaryOperator(op, UnaryOperatorType.Plus);
case OperatorType.UnaryNegation:
- return new FindUnaryOperator(op, UnaryOperatorType.Minus);
+ return FindUnaryOperator(op, UnaryOperatorType.Minus);
case OperatorType.Increment:
- return new FindUnaryOperator(op, UnaryOperatorType.Increment);
+ return FindUnaryOperator(op, UnaryOperatorType.Increment);
case OperatorType.Decrement:
- return new FindUnaryOperator(op, UnaryOperatorType.Decrement);
+ return FindUnaryOperator(op, UnaryOperatorType.Decrement);
case OperatorType.True:
case OperatorType.False:
// TODO: implement search for op_True/op_False correctly
- return new FindMethodReferences(op);
+ return GetSearchScopeForMethod(op);
case OperatorType.Addition:
- return new FindBinaryOperator(op, BinaryOperatorType.Add);
+ return FindBinaryOperator(op, BinaryOperatorType.Add);
case OperatorType.Subtraction:
- return new FindBinaryOperator(op, BinaryOperatorType.Subtract);
+ return FindBinaryOperator(op, BinaryOperatorType.Subtract);
case OperatorType.Multiply:
- return new FindBinaryOperator(op, BinaryOperatorType.Multiply);
+ return FindBinaryOperator(op, BinaryOperatorType.Multiply);
case OperatorType.Division:
- return new FindBinaryOperator(op, BinaryOperatorType.Divide);
+ return FindBinaryOperator(op, BinaryOperatorType.Divide);
case OperatorType.Modulus:
- return new FindBinaryOperator(op, BinaryOperatorType.Modulus);
+ return FindBinaryOperator(op, BinaryOperatorType.Modulus);
case OperatorType.BitwiseAnd:
// TODO: an overloaded bitwise operator can also be called using the corresponding logical operator
// (if op_True/op_False is defined)
- return new FindBinaryOperator(op, BinaryOperatorType.BitwiseAnd);
+ return FindBinaryOperator(op, BinaryOperatorType.BitwiseAnd);
case OperatorType.BitwiseOr:
- return new FindBinaryOperator(op, BinaryOperatorType.BitwiseOr);
+ return FindBinaryOperator(op, BinaryOperatorType.BitwiseOr);
case OperatorType.ExclusiveOr:
- return new FindBinaryOperator(op, BinaryOperatorType.ExclusiveOr);
+ return FindBinaryOperator(op, BinaryOperatorType.ExclusiveOr);
case OperatorType.LeftShift:
- return new FindBinaryOperator(op, BinaryOperatorType.ShiftLeft);
+ return FindBinaryOperator(op, BinaryOperatorType.ShiftLeft);
case OperatorType.RightShift:
- return new FindBinaryOperator(op, BinaryOperatorType.ShiftRight);
+ return FindBinaryOperator(op, BinaryOperatorType.ShiftRight);
case OperatorType.Equality:
- return new FindBinaryOperator(op, BinaryOperatorType.Equality);
+ return FindBinaryOperator(op, BinaryOperatorType.Equality);
case OperatorType.Inequality:
- return new FindBinaryOperator(op, BinaryOperatorType.InEquality);
+ return FindBinaryOperator(op, BinaryOperatorType.InEquality);
case OperatorType.GreaterThan:
- return new FindBinaryOperator(op, BinaryOperatorType.GreaterThan);
+ return FindBinaryOperator(op, BinaryOperatorType.GreaterThan);
case OperatorType.LessThan:
- return new FindBinaryOperator(op, BinaryOperatorType.LessThan);
+ return FindBinaryOperator(op, BinaryOperatorType.LessThan);
case OperatorType.GreaterThanOrEqual:
- return new FindBinaryOperator(op, BinaryOperatorType.GreaterThanOrEqual);
+ return FindBinaryOperator(op, BinaryOperatorType.GreaterThanOrEqual);
case OperatorType.LessThanOrEqual:
- return new FindBinaryOperator(op, BinaryOperatorType.LessThanOrEqual);
+ return FindBinaryOperator(op, BinaryOperatorType.LessThanOrEqual);
case OperatorType.Implicit:
- return new FindImplicitOperator(op);
+ return FindOperator(op, m => new FindImplicitOperatorNavigator(m));
case OperatorType.Explicit:
- return new FindExplicitOperator(op);
+ return FindOperator(op, m => new FindExplicitOperatorNavigator(m));
default:
throw new InvalidOperationException("Invalid value for OperatorType");
}
}
- sealed class FindUnaryOperator : SearchScope
+ SearchScope FindOperator(IMethod op, Func factory)
+ {
+ op = (IMethod)op.MemberDefinition;
+ return new SearchScope(
+ delegate (ICompilation compilation) {
+ IMethod imported = compilation.Import(op);
+ return imported != null ? factory(imported) : null;
+ });
+ }
+
+ SearchScope FindUnaryOperator(IMethod op, UnaryOperatorType operatorType)
+ {
+ return FindOperator(op, m => new FindUnaryOperatorNavigator(m, operatorType));
+ }
+
+ sealed class FindUnaryOperatorNavigator : FindReferenceNavigator
{
readonly IMethod op;
readonly UnaryOperatorType operatorType;
- public FindUnaryOperator(IMethod op, UnaryOperatorType operatorType)
+ public FindUnaryOperatorNavigator(IMethod op, UnaryOperatorType operatorType)
{
this.op = op;
this.operatorType = operatorType;
@@ -669,12 +767,17 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
}
- sealed class FindBinaryOperator : SearchScope
+ SearchScope FindBinaryOperator(IMethod op, BinaryOperatorType operatorType)
+ {
+ return FindOperator(op, m => new FindBinaryOperatorNavigator(m, operatorType));
+ }
+
+ sealed class FindBinaryOperatorNavigator : FindReferenceNavigator
{
readonly IMethod op;
readonly BinaryOperatorType operatorType;
- public FindBinaryOperator(IMethod op, BinaryOperatorType operatorType)
+ public FindBinaryOperatorNavigator(IMethod op, BinaryOperatorType operatorType)
{
this.op = op;
this.operatorType = operatorType;
@@ -696,11 +799,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
}
- sealed class FindImplicitOperator : SearchScope
+ sealed class FindImplicitOperatorNavigator : FindReferenceNavigator
{
readonly IMethod op;
- public FindImplicitOperator(IMethod op)
+ public FindImplicitOperatorNavigator(IMethod op)
{
this.op = op;
}
@@ -716,7 +819,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return mrr != null && op == mrr.Member.MemberDefinition;
}
- internal override void ProcessConversion(Expression expression, ResolveResult result, Conversion conversion, IType targetType)
+ public override void ProcessConversion(Expression expression, ResolveResult result, Conversion conversion, IType targetType)
{
if (conversion.IsUserDefined && conversion.Method.MemberDefinition == op) {
ReportMatch(expression, result);
@@ -724,11 +827,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
}
- sealed class FindExplicitOperator : SearchScope
+ sealed class FindExplicitOperatorNavigator : FindReferenceNavigator
{
readonly IMethod op;
- public FindExplicitOperator(IMethod op)
+ public FindExplicitOperatorNavigator(IMethod op)
{
this.op = op;
}
@@ -747,17 +850,32 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#endregion
#region Find Constructor References
- sealed class FindObjectCreateReferences : SearchScope
+ SearchScope FindObjectCreateReferences(IMethod ctor)
+ {
+ ctor = (IMethod)ctor.MemberDefinition;
+ string searchTerm = null;
+ if (ReflectionHelper.GetTypeCode(ctor.DeclaringTypeDefinition) == TypeCode.Empty) {
+ // not a built-in type
+ searchTerm = ctor.DeclaringTypeDefinition.Name;
+ }
+ return new SearchScope(
+ searchTerm,
+ delegate (ICompilation compilation) {
+ IMethod imported = compilation.Import(ctor);
+ if (imported != null)
+ return new FindObjectCreateReferencesNavigator(ctor);
+ else
+ return null;
+ });
+ }
+
+ sealed class FindObjectCreateReferencesNavigator : FindReferenceNavigator
{
readonly IMethod ctor;
- public FindObjectCreateReferences(IMethod ctor)
+ public FindObjectCreateReferencesNavigator(IMethod ctor)
{
- this.ctor = (IMethod)ctor.MemberDefinition;
- if (ReflectionHelper.GetTypeCode(ctor.DeclaringTypeDefinition) == TypeCode.Empty) {
- // not a built-in type
- this.searchTerm = ctor.DeclaringTypeDefinition.Name;
- }
+ this.ctor = ctor;
}
internal override bool CanMatch(AstNode node)
@@ -772,18 +890,32 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
}
- sealed class FindChainedConstructorReferences : SearchScope
+ SearchScope FindChainedConstructorReferences(IMethod ctor)
+ {
+ ctor = (IMethod)ctor.MemberDefinition;
+ SearchScope searchScope = new SearchScope(
+ delegate (ICompilation compilation) {
+ IMethod imported = compilation.Import(ctor);
+ if (imported != null)
+ return new FindChainedConstructorReferencesNavigator(imported);
+ else
+ return null;
+ });
+ if (ctor.DeclaringTypeDefinition.IsSealed)
+ searchScope.accessibility = Accessibility.Private;
+ else
+ searchScope.accessibility = Accessibility.Protected;
+ searchScope.accessibility = MergeAccessibility(GetEffectiveAccessibility(ctor), searchScope.accessibility);
+ return searchScope;
+ }
+
+ sealed class FindChainedConstructorReferencesNavigator : FindReferenceNavigator
{
readonly IMethod ctor;
- public FindChainedConstructorReferences(IMethod ctor)
+ public FindChainedConstructorReferencesNavigator(IMethod ctor)
{
- this.ctor = (IMethod)ctor.MemberDefinition;
- if (ctor.DeclaringTypeDefinition.IsSealed)
- this.accessibility = Accessibility.Private;
- else
- this.accessibility = Accessibility.Protected;
- this.accessibility = MergeAccessibility(GetEffectiveAccessibility(ctor), this.accessibility);
+ this.ctor = ctor;
}
internal override bool CanMatch(AstNode node)
@@ -814,12 +946,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
{
if (variable == null)
throw new ArgumentNullException("variable");
- var navigator = new FindLocalReferencesNavigator(variable);
- navigator.compilation = compilation;
- FindReferencesInFile(navigator, parsedFile, compilationUnit, callback, cancellationToken);
+ var searchScope = new SearchScope(c => new FindLocalReferencesNavigator(variable));
+ searchScope.declarationCompilation = compilation;
+ FindReferencesInFile(searchScope, parsedFile, compilationUnit, compilation, callback, cancellationToken);
}
- class FindLocalReferencesNavigator : SearchScope
+ class FindLocalReferencesNavigator : FindReferenceNavigator
{
readonly IVariable variable;
diff --git a/ICSharpCode.NRefactory.CSharp/TypeSystem/ConstantValues.cs b/ICSharpCode.NRefactory.CSharp/TypeSystem/ConstantValues.cs
index d9a2c8158e..cf203adca8 100644
--- a/ICSharpCode.NRefactory.CSharp/TypeSystem/ConstantValues.cs
+++ b/ICSharpCode.NRefactory.CSharp/TypeSystem/ConstantValues.cs
@@ -62,7 +62,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues
nestedContext = nestedContext.WithUsingScope(context.CurrentUsingScope.UnresolvedUsingScope.Resolve(nestedCompilation));
}
if (context.CurrentTypeDefinition != null) {
- nestedContext = nestedContext.WithCurrentTypeDefinition(context.CurrentTypeDefinition.ToTypeReference().Resolve(nestedContext).GetDefinition());
+ nestedContext = nestedContext.WithCurrentTypeDefinition(nestedCompilation.Import(context.CurrentTypeDefinition));
}
return nestedContext;
}
diff --git a/ICSharpCode.NRefactory.Demo/CSDemo.cs b/ICSharpCode.NRefactory.Demo/CSDemo.cs
index 37b6334b19..b712f1149b 100644
--- a/ICSharpCode.NRefactory.Demo/CSDemo.cs
+++ b/ICSharpCode.NRefactory.Demo/CSDemo.cs
@@ -316,7 +316,7 @@ namespace ICSharpCode.NRefactory.Demo
};
var searchScopes = fr.GetSearchScopes(entity);
- fr.FindReferencesInFile(searchScopes, parsedFile, compilationUnit, callback, CancellationToken.None);
+ fr.FindReferencesInFile(searchScopes, parsedFile, compilationUnit, compilation, callback, CancellationToken.None);
MessageBox.Show("Found " + referenceCount + " references to " + entity.FullName);
}
diff --git a/ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs b/ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs
index cf3a9e718b..205ea72d93 100644
--- a/ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs
+++ b/ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs
@@ -172,6 +172,8 @@ namespace ICSharpCode.NRefactory.TypeSystem
throw new ArgumentNullException("compilation");
if (typeDefinition == null)
return null;
+ if (typeDefinition.Compilation == compilation)
+ return typeDefinition;
return typeDefinition.ToTypeReference().Resolve(compilation.TypeResolveContext).GetDefinition();
}
@@ -184,8 +186,42 @@ namespace ICSharpCode.NRefactory.TypeSystem
throw new ArgumentNullException("compilation");
if (member == null)
return null;
+ if (member.Compilation == compilation)
+ return member;
return member.ToMemberReference().Resolve(compilation.TypeResolveContext);
}
+
+ ///
+ /// Imports a member from another compilation.
+ ///
+ public static IMethod Import(this ICompilation compilation, IMethod method)
+ {
+ return (IMethod)compilation.Import((IMember)method);
+ }
+
+ ///
+ /// Imports a member from another compilation.
+ ///
+ public static IField Import(this ICompilation compilation, IField field)
+ {
+ return (IField)compilation.Import((IMember)field);
+ }
+
+ ///
+ /// Imports a member from another compilation.
+ ///
+ public static IEvent Import(this ICompilation compilation, IEvent ev)
+ {
+ return (IEvent)compilation.Import((IMember)ev);
+ }
+
+ ///
+ /// Imports a member from another compilation.
+ ///
+ public static IProperty Import(this ICompilation compilation, IProperty property)
+ {
+ return (IProperty)compilation.Import((IMember)property);
+ }
#endregion
#region GetDelegateInvokeMethod