diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/FindReferences.cs b/ICSharpCode.NRefactory.CSharp/Resolver/FindReferences.cs
index 960b5f7ea3..42fe828b26 100644
--- a/ICSharpCode.NRefactory.CSharp/Resolver/FindReferences.cs
+++ b/ICSharpCode.NRefactory.CSharp/Resolver/FindReferences.cs
@@ -189,7 +189,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
SearchScope additionalScope = null;
switch (entity.EntityType) {
case EntityType.TypeDefinition:
- scope = FindTypeDefinitionReferences((ITypeDefinition)entity, this.FindTypeReferencesEvenIfAliased);
+ scope = FindTypeDefinitionReferences((ITypeDefinition)entity, this.FindTypeReferencesEvenIfAliased, out additionalScope);
break;
case EntityType.Field:
if (entity.DeclaringTypeDefinition != null && entity.DeclaringTypeDefinition.Kind == TypeKind.Enum)
@@ -353,14 +353,28 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#endregion
#region Find TypeDefinition References
- SearchScope FindTypeDefinitionReferences(ITypeDefinition typeDefinition, bool findTypeReferencesEvenIfAliased)
+ SearchScope FindTypeDefinitionReferences(ITypeDefinition typeDefinition, bool findTypeReferencesEvenIfAliased, out SearchScope additionalScope)
{
string searchTerm = null;
- if (!findTypeReferencesEvenIfAliased && ReflectionHelper.GetTypeCode(typeDefinition) == TypeCode.Empty) {
- // not a built-in type
+ additionalScope = null;
+ if (!findTypeReferencesEvenIfAliased && KnownTypeReference.GetCSharpNameByTypeCode(typeDefinition.KnownTypeCode) == null) {
+ // We can optimize the search by looking only for the type references with the right identifier,
+ // but only if it's not a primitive type and we're not looking for indirect references (through an alias)
searchTerm = typeDefinition.Name;
+ if (searchTerm.Length > 9 && searchTerm.EndsWith("Attribute", StringComparison.Ordinal)) {
+ // The type might be an attribute, so we also need to look for the short form:
+ string shortForm = searchTerm.Substring(0, searchTerm.Length - 9);
+ additionalScope = new SearchScope(
+ shortForm,
+ delegate (ICompilation compilation) {
+ ITypeDefinition imported = compilation.Import(typeDefinition);
+ if (imported != null)
+ return new FindTypeDefinitionReferencesNavigator(imported, shortForm);
+ else
+ return null;
+ });
+ }
}
-
return new SearchScope(
searchTerm,
delegate (ICompilation compilation) {
@@ -404,7 +418,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (searchTerm == null && node is PrimitiveType)
return true;
- return node is TypeDeclaration || node is DelegateDeclaration;
+ TypeDeclaration typeDecl = node as TypeDeclaration;
+ if (typeDecl != null)
+ return searchTerm == null || typeDecl.Name == searchTerm;
+
+ DelegateDeclaration delegateDecl = node as DelegateDeclaration;
+ if (delegateDecl != null)
+ return searchTerm == null || delegateDecl.Name == searchTerm;
+
+ return false;
}
internal override bool IsMatch(ResolveResult rr)
@@ -872,9 +894,13 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
{
ctor = (IMethod)ctor.MemberDefinition;
string searchTerm = null;
- if (ReflectionHelper.GetTypeCode(ctor.DeclaringTypeDefinition) == TypeCode.Empty) {
+ if (KnownTypeReference.GetCSharpNameByTypeCode(ctor.DeclaringTypeDefinition.KnownTypeCode) == null) {
// not a built-in type
searchTerm = ctor.DeclaringTypeDefinition.Name;
+ if (searchTerm.Length > 9 && searchTerm.EndsWith("Attribute", StringComparison.Ordinal)) {
+ // we also need to look for the short form
+ searchTerm = null;
+ }
}
return new SearchScope(
searchTerm,
@@ -898,7 +924,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
internal override bool CanMatch(AstNode node)
{
- return node is ObjectCreateExpression || node is ConstructorDeclaration;
+ return node is ObjectCreateExpression || node is ConstructorDeclaration || node is Attribute;
}
internal override bool IsMatch(ResolveResult rr)
diff --git a/ICSharpCode.NRefactory.Demo/CSDemo.cs b/ICSharpCode.NRefactory.Demo/CSDemo.cs
index b712f1149b..144b4723e1 100644
--- a/ICSharpCode.NRefactory.Demo/CSDemo.cs
+++ b/ICSharpCode.NRefactory.Demo/CSDemo.cs
@@ -312,10 +312,12 @@ namespace ICSharpCode.NRefactory.Demo
FindReferences fr = new FindReferences();
int referenceCount = 0;
FoundReferenceCallback callback = delegate(AstNode matchNode, ResolveResult result) {
+ Debug.WriteLine(matchNode.StartLocation + " - " + matchNode + " - " + result);
referenceCount++;
};
var searchScopes = fr.GetSearchScopes(entity);
+ Debug.WriteLine("Find references to " + entity.ReflectionName);
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 1746e1bfad..8fa9699ef7 100644
--- a/ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs
+++ b/ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs
@@ -252,16 +252,33 @@ namespace ICSharpCode.NRefactory.TypeSystem
#endregion
#region GetType/Member
+ ///
+ /// Gets all unresolved type definitions from the file.
+ /// For partial classes, each part is returned.
+ ///
public static IEnumerable GetAllTypeDefinitions (this IParsedFile file)
{
return TreeTraversal.PreOrder(file.TopLevelTypeDefinitions, t => t.NestedTypes);
}
+ ///
+ /// Gets all unresolved type definitions from the assembly.
+ /// For partial classes, each part is returned.
+ ///
+ public static IEnumerable GetAllTypeDefinitions (this IUnresolvedAssembly assembly)
+ {
+ return TreeTraversal.PreOrder(assembly.TopLevelTypeDefinitions, t => t.NestedTypes);
+ }
+
public static IEnumerable GetAllTypeDefinitions (this IAssembly assembly)
{
return TreeTraversal.PreOrder(assembly.TopLevelTypeDefinitions, t => t.NestedTypes);
}
+ ///
+ /// Gets all type definitions in the compilation.
+ /// This may include types from referenced assemblies that are not accessible in the main assembly.
+ ///
public static IEnumerable GetAllTypeDefinitions (this ICompilation compilation)
{
return compilation.MainAssembly.GetAllTypeDefinitions()
diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultSolutionSnapshot.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultSolutionSnapshot.cs
index 2114f0c4b3..f32676c220 100644
--- a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultSolutionSnapshot.cs
+++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultSolutionSnapshot.cs
@@ -24,7 +24,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
///
/// Default implementation of ISolutionSnapshot.
///
- public sealed class DefaultSolutionSnapshot : ISolutionSnapshot
+ public class DefaultSolutionSnapshot : ISolutionSnapshot
{
ConcurrentDictionary dictionary = new ConcurrentDictionary();