Browse Source

FindReferences: API idea for new options

newNRvisualizers
Daniel Grunwald 14 years ago
parent
commit
2e40a3483b
  1. 42
      ICSharpCode.NRefactory.CSharp/Resolver/FindReferencedEntities.cs
  2. 35
      ICSharpCode.NRefactory.CSharp/Resolver/FindReferences.cs
  3. 24
      ICSharpCode.NRefactory.CSharp/Resolver/TypeInference.cs
  4. 19
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/TypeInferenceTests.cs

42
ICSharpCode.NRefactory.CSharp/Resolver/FindReferencedEntities.cs

@ -27,13 +27,39 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -27,13 +27,39 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// </summary>
public sealed class FindReferencedEntities : IResolveVisitorNavigator
{
readonly Action<AstNode, IEntity> referenceFound;
readonly Action<AstNode, IMember> memberReferenceFound;
readonly Action<AstNode, IType> typeReferenceFound;
/// <summary>
/// Creates a new FindReferencedEntities instance that
/// looks for entity definitions.
/// The visitor will report type definitions and member definitions (not specialized members).
/// </summary>
public FindReferencedEntities(Action<AstNode, IEntity> referenceFound)
{
if (referenceFound == null)
throw new ArgumentNullException("referenceFound");
this.referenceFound = referenceFound;
this.memberReferenceFound = (node, member) => referenceFound(node, member.MemberDefinition);
this.typeReferenceFound = (node, type) => {
var def = type.GetDefinition();
if (def != null)
referenceFound(node, def);
};
}
/// <summary>
/// Creates a new FindReferencedEntities instance that
/// looks for types and members.
/// The visitor will report parameterized types and potentially specialized members.
/// </summary>
public FindReferencedEntities(Action<AstNode, IType> typeReferenceFound, Action<AstNode, IMember> memberReferenceFound)
{
if (typeReferenceFound == null)
throw new ArgumentNullException("typeReferenceFound");
if (memberReferenceFound == null)
throw new ArgumentNullException("memberReferenceFound");
this.typeReferenceFound = typeReferenceFound;
this.memberReferenceFound = memberReferenceFound;
}
public ResolveVisitorNavigationMode Scan(AstNode node)
@ -48,28 +74,26 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -48,28 +74,26 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
MemberResolveResult mrr = result as MemberResolveResult;
if (mrr != null) {
referenceFound(node, mrr.Member.MemberDefinition);
memberReferenceFound(node, mrr.Member);
}
TypeResolveResult trr = result as TypeResolveResult;
if (trr != null) {
ITypeDefinition typeDef = trr.Type.GetDefinition();
if (typeDef != null)
referenceFound(node, typeDef);
typeReferenceFound(node, trr.Type);
}
ForEachResolveResult ferr = result as ForEachResolveResult;
if (ferr != null) {
Resolved(node, ferr.GetEnumeratorCall);
if (ferr.CurrentProperty != null)
referenceFound(node, ferr.CurrentProperty.MemberDefinition);
memberReferenceFound(node, ferr.CurrentProperty);
if (ferr.MoveNextMethod != null)
referenceFound(node, ferr.MoveNextMethod.MemberDefinition);
memberReferenceFound(node, ferr.MoveNextMethod);
}
}
public void ProcessConversion(Expression expression, ResolveResult result, Conversion conversion, IType targetType)
{
if (conversion.IsUserDefined || conversion.IsMethodGroupConversion) {
referenceFound(expression, conversion.Method.MemberDefinition);
memberReferenceFound(expression, conversion.Method);
}
}
}

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

@ -42,9 +42,42 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -42,9 +42,42 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
{
#region Properties
/// <summary>
/// Gets/Sets whether to find type references even if an alias is being used.
/// Specifies whether to find type references even if an alias is being used.
/// Aliases may be <c>var</c> or <c>using Alias = ...;</c>.
/// </summary>
public bool FindTypeReferencesEvenIfAliased { get; set; }
/// <summary>
/// Specifies whether find references should only look for specialized matches
/// with equal type parameter substitution to the member we are searching for.
/// </summary>
public bool FindOnlySpecializedReferences { get; set; }
/// <summary>
/// If this option is enabled, find references on a overridden member
/// will find calls to the base member.
/// </summary>
public bool FindCallsThroughVirtualBaseMethod { get; set; }
/// <summary>
/// If this option is enabled, find references on a member implementing
/// an interface will also find calls to the interface.
/// </summary>
public bool FindCallsThroughInterface { get; set; }
/// <summary>
/// If this option is enabled, find references will look for all references
/// to the virtual method slot.
/// </summary>
public bool WholeVirtualSlot { get; set; }
/// <summary>
/// Specifies whether to look for references in documentation comments.
/// This will find entity references in <c>cref</c> attributes and
/// parameter references in <c>&lt;param&gt;</c> and <c>&lt;paramref&gt;</c> tags.
/// TODO: implement this feature.
/// </summary>
public bool SearchInDocumentationComments { get; set; }
#endregion
#region GetEffectiveAccessibility

24
ICSharpCode.NRefactory.CSharp/Resolver/TypeInference.cs

@ -629,15 +629,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -629,15 +629,12 @@ 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 && IsIEnumerableCollectionOrList(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()) {
@ -677,20 +674,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -677,20 +674,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
Log.Unindent();
}
}
static bool IsIEnumerableCollectionOrList(ParameterizedType rt)
{
if (rt == null || rt.TypeParameterCount != 1)
return false;
switch (rt.GetDefinition().FullName) {
case "System.Collections.Generic.IList":
case "System.Collections.Generic.ICollection":
case "System.Collections.Generic.IEnumerable":
return true;
default:
return false;
}
}
#endregion
#region MakeUpperBoundInference (§7.5.2.10)
@ -713,15 +696,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -713,15 +696,12 @@ 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 && IsIEnumerableCollectionOrList(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()) {

19
ICSharpCode.NRefactory.Tests/CSharp/Resolver/TypeInferenceTests.cs

@ -70,6 +70,25 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -70,6 +70,25 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
Assert.IsTrue(success);
}
[Test]
public void ArrayToReadOnlyList()
{
ITypeParameter tp = new DefaultTypeParameter(compilation, EntityType.Method, 0, "T");
IType stringType = compilation.FindType(KnownTypeCode.String);
ITypeDefinition readOnlyListType = compilation.FindType(KnownTypeCode.IReadOnlyListOfT).GetDefinition();
if (readOnlyListType == null)
Assert.Ignore(".NET 4.5 IReadOnlyList not available");
bool success;
Assert.AreEqual(
new [] { stringType },
ti.InferTypeArguments(new [] { tp },
new [] { new ResolveResult(new ArrayType(compilation, stringType)) },
new [] { new ParameterizedType(readOnlyListType, new [] { tp }) },
out success));
Assert.IsTrue(success);
}
[Test]
public void EnumerableToArrayInContravariantType()
{

Loading…
Cancel
Save