Browse Source

FindReferences: add support for searching in a different compilation than the entity is defined in.

newNRvisualizers
Daniel Grunwald 14 years ago
parent
commit
93a5c13825
  1. 5
      ICSharpCode.NRefactory.CSharp/Resolver/FindReferenceSearchScope.cs
  2. 378
      ICSharpCode.NRefactory.CSharp/Resolver/FindReferences.cs
  3. 2
      ICSharpCode.NRefactory.CSharp/TypeSystem/ConstantValues.cs
  4. 2
      ICSharpCode.NRefactory.Demo/CSDemo.cs
  5. 36
      ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs

5
ICSharpCode.NRefactory.CSharp/Resolver/FindReferenceSearchScope.cs

@ -27,7 +27,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -27,7 +27,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
public interface IFindReferenceSearchScope
{
/// <summary>
/// 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.
/// </summary>
ICompilation Compilation { get; }
@ -51,6 +52,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -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.
/// </summary>
IResolveVisitorNavigator GetNavigator(FoundReferenceCallback callback);
IResolveVisitorNavigator GetNavigator(ICompilation compilation, FoundReferenceCallback callback);
}
}

378
ICSharpCode.NRefactory.CSharp/Resolver/FindReferences.cs

@ -20,6 +20,7 @@ using System; @@ -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 @@ -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<ICompilation, FindReferenceNavigator> factory;
FoundReferenceCallback callback;
public SearchScope(Func<ICompilation, FindReferenceNavigator> factory)
{
this.factory = factory;
}
ICompilation IFindReferenceSearchScope.Compilation {
get { return compilation; }
public SearchScope(string searchTerm, Func<ICompilation, FindReferenceNavigator> 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 @@ -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 @@ -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 @@ -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<IFindReferenceSearchScope>.Instance;
@ -208,12 +224,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -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 @@ -284,11 +300,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// <param name="context">The type resolve context to use for resolving the file.</param>
/// <param name="callback">Callback used to report the references that were found.</param>
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);
}
/// <summary>
@ -300,7 +316,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -300,7 +316,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// <param name="callback">Callback used to report the references that were found.</param>
/// <param name="cancellationToken">Cancellation token.</param>
public void FindReferencesInFile(IList<IFindReferenceSearchScope> 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 @@ -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 @@ -378,11 +414,24 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#endregion
#region Find Member References
class FindMemberReferences : SearchScope
SearchScope FindMemberReferences(IEntity member, Func<IMember, FindMemberReferencesNavigator> 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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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<IMethod, FindReferenceNavigator> 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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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;

2
ICSharpCode.NRefactory.CSharp/TypeSystem/ConstantValues.cs

@ -62,7 +62,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues @@ -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;
}

2
ICSharpCode.NRefactory.Demo/CSDemo.cs

@ -316,7 +316,7 @@ namespace ICSharpCode.NRefactory.Demo @@ -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);
}

36
ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs

@ -172,6 +172,8 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -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 @@ -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);
}
/// <summary>
/// Imports a member from another compilation.
/// </summary>
public static IMethod Import(this ICompilation compilation, IMethod method)
{
return (IMethod)compilation.Import((IMember)method);
}
/// <summary>
/// Imports a member from another compilation.
/// </summary>
public static IField Import(this ICompilation compilation, IField field)
{
return (IField)compilation.Import((IMember)field);
}
/// <summary>
/// Imports a member from another compilation.
/// </summary>
public static IEvent Import(this ICompilation compilation, IEvent ev)
{
return (IEvent)compilation.Import((IMember)ev);
}
/// <summary>
/// Imports a member from another compilation.
/// </summary>
public static IProperty Import(this ICompilation compilation, IProperty property)
{
return (IProperty)compilation.Import((IMember)property);
}
#endregion
#region GetDelegateInvokeMethod

Loading…
Cancel
Save