Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/main/src
diff options
context:
space:
mode:
authorMike Krüger <mkrueger@xamarin.com>2015-02-08 11:38:13 +0300
committerMike Krüger <mkrueger@xamarin.com>2015-02-08 11:38:13 +0300
commit9c6b75f690aca613f96d394b1fba7b91ec09cec8 (patch)
tree58552ee1d3c98841936aa61c1596750c61e74968 /main/src
parentb97c166e7e4228a3fdf5f8e6f1420f44fc809938 (diff)
parent1c124233f582672b5184226bdbcaed0e33c62998 (diff)
Merge pull request #733 from mhutch/fix-find-derived-symbols
Fix find derived symbols
Diffstat (limited to 'main/src')
-rw-r--r--main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring.addin.xml2
-rw-r--r--main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring/FindDerivedClassesHandler.cs205
-rw-r--r--main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring/FindDerivedSymbolsHandler.cs90
-rw-r--r--main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring/RefactoryCommands.cs15
4 files changed, 131 insertions, 181 deletions
diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring.addin.xml b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring.addin.xml
index d20c6f8c42..aa4e755af5 100644
--- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring.addin.xml
+++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring.addin.xml
@@ -90,7 +90,7 @@
_label = "_Find References of All Overloads" />
<Command id = "MonoDevelop.Refactoring.RefactoryCommands.FindDerivedClasses"
defaultHandler = "MonoDevelop.Refactoring.FindDerivedClassesHandler"
- _label = "Find _Derived Classes" />
+ _label = "Find _Derived Symbols" />
</Category>
<Category _name = "Refactoring" id = "Refactoring">
diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring/FindDerivedClassesHandler.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring/FindDerivedClassesHandler.cs
index d1d99c2b41..63b5365aeb 100644
--- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring/FindDerivedClassesHandler.cs
+++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring/FindDerivedClassesHandler.cs
@@ -1,21 +1,21 @@
-//
+//
// FindDerivedClassesHandler.cs
-//
+//
// Author:
// Mike Krüger <mkrueger@novell.com>
-//
+//
// Copyright (c) 2010 Novell, Inc (http://www.novell.com)
-//
+//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
-//
+//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
-//
+//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -28,7 +28,6 @@ using System;
using MonoDevelop.Core;
using MonoDevelop.Ide.Gui;
using MonoDevelop.Components.Commands;
-using MonoDevelop.Ide.Gui.Content;
using MonoDevelop.Refactoring;
using MonoDevelop.Ide;
using ICSharpCode.NRefactory.TypeSystem;
@@ -37,12 +36,11 @@ using System.Collections.Generic;
using System.Threading;
using MonoDevelop.Projects;
using MonoDevelop.Ide.FindInFiles;
-using ICSharpCode.NRefactory.CSharp.Resolver;
-using ICSharpCode.NRefactory.TypeSystem.Implementation;
-using System.Linq;
using Mono.TextEditor;
using ICSharpCode.NRefactory.Semantics;
using System.Threading.Tasks;
+using System.Linq;
+using System.Collections.Concurrent;
namespace MonoDevelop.Refactoring
{
@@ -50,102 +48,125 @@ namespace MonoDevelop.Refactoring
{
public static void FindDerivedClasses (ITypeDefinition cls)
{
+ FindDerivedSymbols (cls, null);
+ }
+
+ public static void FindDerivedMembers (IMember member)
+ {
+ var cls = member.DeclaringTypeDefinition;
+ if (cls == null)
+ return;
+ FindDerivedSymbols (cls, member);
+ }
+
+ static void FindDerivedSymbols (ITypeDefinition cls, IMember member)
+ {
var solution = IdeApp.ProjectOperations.CurrentSelectedSolution;
if (solution == null)
return;
-
+
var sourceProject = TypeSystemService.GetProject (cls);
if (sourceProject == null)
return;
-
- var projects = ReferenceFinder.GetAllReferencingProjects (solution, sourceProject);
- ThreadPool.QueueUserWorkItem (delegate {
- using (var monitor = IdeApp.Workbench.ProgressMonitors.GetSearchProgressMonitor (true, true)) {
- var cache = new Dictionary<string, TextEditorData> ();
- monitor.BeginTask (GettextCatalog.GetString ("Searching for derived classes in solution..."), projects.Count);
-
- Parallel.ForEach (projects, p => {
- var comp = TypeSystemService.GetCompilation (p);
- if (comp == null)
- return;
- var importedType = comp.Import (cls);
- if (importedType == null) {
+
+ var compilations = ReferenceFinder.GetAllReferencingProjects (solution, sourceProject)
+ .Select (TypeSystemService.GetCompilation).Where (c => c != null).ToList ();
+
+ using (var monitor = IdeApp.Workbench.ProgressMonitors.GetSearchProgressMonitor (true, true)) {
+ var label = member == null
+ ? GettextCatalog.GetString ("Searching for derived classes in solution...")
+ : GettextCatalog.GetString ("Searching for derived members in solution...");
+ monitor.BeginTask (label, compilations.Count);
+
+ Parallel.ForEach (compilations, comp => {
+ var importedType = comp.Import (cls);
+ if (importedType == null) {
+ return;
+ }
+
+ IMember impMember = null;
+ if (member != null) {
+ impMember = comp.Import (member);
+ if (impMember == null) {
return;
}
- foreach (var type in comp.MainAssembly.GetAllTypeDefinitions ()) {
- if (!type.IsDerivedFrom (importedType))
+ }
+
+ foreach (var derivedType in comp.MainAssembly.GetAllTypeDefinitions ()) {
+ if (!derivedType.IsDerivedFrom (importedType))
+ continue;
+
+ IEntity result;
+ if (member != null) {
+ result = FindDerivedMember (impMember, derivedType);
+ if (result == null)
continue;
- TextEditorData textFile;
- if (!cache.TryGetValue (type.Region.FileName, out textFile)) {
- cache [type.Region.FileName] = textFile = TextFileProvider.Instance.GetTextEditorData (type.Region.FileName);
- }
- int position = textFile.LocationToOffset (type.Region.Begin);
- string keyword;
- switch (type.Kind) {
- case TypeKind.Interface:
- keyword = "interface";
- break;
- case TypeKind.Struct:
- keyword = "struct";
- break;
- case TypeKind.Delegate:
- keyword = "delegate";
- break;
- case TypeKind.Enum:
- keyword = "enum";
- break;
- default:
- keyword = "class";
- break;
- }
- while (position < textFile.Length - keyword.Length) {
- if (textFile.GetTextAt (position, keyword.Length) == keyword) {
- position += keyword.Length;
- while (position < textFile.Length && textFile.GetCharAt (position) == ' ' || textFile.GetCharAt (position) == '\t')
- position++;
- break;
- }
- position++;
- }
- monitor.ReportResult (new MonoDevelop.Ide.FindInFiles.SearchResult (new FileProvider (type.Region.FileName, p), position, 0));
+ } else {
+ result = derivedType;
}
- monitor.Step (1);
- });
- foreach (var tf in cache.Values) {
- if (tf.Parent == null)
- tf.Dispose ();
+
+ ReportResult (monitor, result);
}
- monitor.EndTask ();
- }
- });
+ monitor.Step (1);
+ });
+
+ monitor.EndTask ();
+ };
+ }
+
+ static IMember FindDerivedMember (IMember importedMember, ITypeDefinition derivedType)
+ {
+ IMember derivedMember;
+ if (importedMember.DeclaringTypeDefinition.Kind == TypeKind.Interface) {
+ derivedMember = derivedType.GetMembers (null, GetMemberOptions.IgnoreInheritedMembers)
+ .FirstOrDefault (m => m.ImplementedInterfaceMembers.Any (im => im.Region == importedMember.Region));
+ }
+ else {
+ derivedMember = InheritanceHelper.GetDerivedMember (importedMember, derivedType);
+ }
+ return derivedMember;
}
-
+
+ static void ReportResult (ISearchProgressMonitor monitor, IEntity result)
+ {
+ string filename = result.Region.FileName;
+ if (string.IsNullOrEmpty (filename))
+ return;
+
+ var textFile = TextFileProvider.Instance.GetTextEditorData (filename);
+ var start = textFile.LocationToOffset (result.Region.Begin);
+ textFile.SearchRequest.SearchPattern = result.Name;
+ var sr = textFile.SearchForward (start);
+ if (sr != null)
+ start = sr.Offset;
+
+ if (textFile.Parent == null)
+ textFile.Dispose ();
+
+ monitor.ReportResult (new MemberReference (result, result.Region, start, result.Name.Length));
+ }
+
protected override void Run (object data)
{
-// var doc = IdeApp.Workbench.ActiveDocument;
-// if (doc == null || doc.FileName == FilePath.Null)
-// return;
-// ResolveResult resolveResult;
-// var item = CurrentRefactoryOperationsHandler.GetItem (doc, out resolveResult);
-//
-// IMember eitem = resolveResult != null ? (resolveResult.CallingMember ?? resolveResult.CallingType) : null;
-// string itemName = null;
-// if (item is IMember)
-// itemName = ((IMember)item).FullName;
-// if (item != null && eitem != null && (eitem.Equals (item) || (eitem.FullName == itemName && !(eitem is IProperty) && !(eitem is IMethod)))) {
-// item = eitem;
-// eitem = null;
-// }
-// ITypeDefinition eclass = null;
-// if (item is ITypeDefinition) {
-// if (((ITypeDefinition)item).Kind == TypeKind.Interface)
-// eclass = CurrentRefactoryOperationsHandler.FindEnclosingClass (ctx, editor.Name, line, column); else
-// eclass = (IType)item;
-// if (eitem is IMethod && ((IMethod)eitem).IsConstructor && eitem.DeclaringType.Equals (item)) {
-// item = eitem;
-// eitem = null;
-// }
-// }
+ var doc = IdeApp.Workbench.ActiveDocument;
+ if (doc == null || doc.FileName == FilePath.Null)
+ return;
+
+ ResolveResult resolveResult;
+ var item = CurrentRefactoryOperationsHandler.GetItem (doc, out resolveResult);
+
+ var typeDef = item as ITypeDefinition;
+ if (typeDef != null && ((typeDef.Kind == TypeKind.Class && !typeDef.IsSealed) || typeDef.Kind == TypeKind.Interface)) {
+ FindDerivedClasses (typeDef);
+ return;
+ }
+
+ var member = item as IMember;
+ var handler = new FindDerivedSymbolsHandler (member);
+ if (handler.IsValid) {
+ handler.Run ();
+ return;
+ }
}
}
}
diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring/FindDerivedSymbolsHandler.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring/FindDerivedSymbolsHandler.cs
index a034b677f0..50c204a767 100644
--- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring/FindDerivedSymbolsHandler.cs
+++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring/FindDerivedSymbolsHandler.cs
@@ -41,98 +41,26 @@ namespace MonoDevelop.Refactoring
{
class FindDerivedSymbolsHandler
{
- Ide.Gui.Document doc;
- readonly IMember entity;
+ readonly IMember member;
-
- public FindDerivedSymbolsHandler (Ide.Gui.Document doc, IMember entity)
- {
- this.doc = doc;
- this.entity = entity;
- }
-
- static bool IsReferenced (Project project, Project referencedProject)
+ public FindDerivedSymbolsHandler (IMember member)
{
- return project == referencedProject ||
- project.GetReferencedItems (IdeApp.Workspace.ActiveConfiguration).Contains (referencedProject);
- }
-
- Task<HashSet<IAssembly>> GetAllAssemblies (Project referencedProject)
- {
- var solution = IdeApp.ProjectOperations.CurrentSelectedSolution;
- return Task.Factory.StartNew (delegate {
- var assemblies = new HashSet<IAssembly> ();
- foreach (var project in solution.GetAllProjects ()) {
- if (!IsReferenced (project, referencedProject))
- continue;
- var comp = TypeSystemService.GetCompilation (project);
- if (comp == null)
- continue;
- assemblies.Add (comp.MainAssembly);
- }
- return assemblies;
- });
+ this.member = member;
}
public bool IsValid {
get {
- return true;
+ if (IdeApp.ProjectOperations.CurrentSelectedSolution == null)
+ return false;
+ if (TypeSystemService.GetProject (member) == null)
+ return false;
+ return member.IsVirtual || member.IsAbstract || member.DeclaringType.Kind == TypeKind.Interface;
}
}
public void Run ()
{
- var assemblies = GetAllAssemblies (doc.Project);
- assemblies.ContinueWith (delegate(Task<HashSet<IAssembly>> arg) {
- var monitor = IdeApp.Workbench.ProgressMonitors.GetSearchProgressMonitor (true, true);
- monitor.BeginTask (GettextCatalog.GetString ("Building type graph in solution ..."), 1);
- var tg = new TypeGraph (arg.Result);
- var node = tg.GetNode (entity.DeclaringTypeDefinition);
- monitor.EndTask ();
- if (node == null) {
- monitor.Dispose ();
- return;
- }
- Gtk.Application.Invoke (delegate {
- try {
- Stack<IList<TypeGraphNode>> derivedTypes = new Stack<IList<TypeGraphNode>> ();
- derivedTypes.Push (node.DerivedTypes);
- HashSet<ITypeDefinition> visitedType = new HashSet<ITypeDefinition> ();
- while (derivedTypes.Count > 0) {
- foreach (var derived in derivedTypes.Pop ()) {
- if (visitedType.Contains (derived.TypeDefinition))
- continue;
- derivedTypes.Push (tg.GetNode (derived.TypeDefinition).DerivedTypes);
- visitedType.Add (derived.TypeDefinition);
- var impMember = derived.TypeDefinition.Compilation.Import (entity);
- if (impMember == null)
- continue;
- IMember derivedMember;
- if (entity.DeclaringTypeDefinition.Kind == TypeKind.Interface) {
- derivedMember = derived.TypeDefinition.GetMembers (null, GetMemberOptions.IgnoreInheritedMembers).FirstOrDefault (
- m => m.ImplementedInterfaceMembers.Any (im => im.Region == entity.Region)
- );
- } else {
- derivedMember = InheritanceHelper.GetDerivedMember (impMember, derived.TypeDefinition);
- }
- if (derivedMember == null || string.IsNullOrEmpty (derivedMember.Region.FileName))
- continue;
- var tf = TextFileProvider.Instance.GetReadOnlyTextEditorData (derivedMember.Region.FileName);
- var start = tf.LocationToOffset (derivedMember.Region.Begin);
- tf.SearchRequest.SearchPattern = derivedMember.Name;
- var sr = tf.SearchForward (start);
- if (sr != null)
- start = sr.Offset;
-
- monitor.ReportResult (new MemberReference (derivedMember, derivedMember.Region, start, derivedMember.Name.Length));
- }
- }
- } finally {
- monitor.Dispose ();
- }
- });
- });
-
+ FindDerivedClassesHandler.FindDerivedMembers (member);
}
}
}
diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring/RefactoryCommands.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring/RefactoryCommands.cs
index 375ea3edf1..2f5ac1f714 100644
--- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring/RefactoryCommands.cs
+++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring/RefactoryCommands.cs
@@ -350,12 +350,11 @@ namespace MonoDevelop.Refactoring
if (item is IMember) {
var member = (IMember)item;
- if (member.IsVirtual || member.IsAbstract || member.DeclaringType.Kind == TypeKind.Interface) {
- var handler = new FindDerivedSymbolsHandler (doc, member);
- if (handler.IsValid) {
- ainfo.Add (GettextCatalog.GetString ("Find Derived Symbols"), new System.Action (handler.Run));
- added = true;
- }
+ var handler = new FindDerivedSymbolsHandler (member);
+ if (handler.IsValid) {
+ var a = ainfo.Add (GettextCatalog.GetString ("Find Derived Symbols"), new Action (handler.Run));
+ a.AccelKey = IdeApp.CommandService.GetCommandInfo (RefactoryCommands.FindDerivedClasses).AccelKey;
+ added = true;
}
}
if (item is IMember) {
@@ -378,7 +377,9 @@ namespace MonoDevelop.Refactoring
}
}
if ((cls.Kind == TypeKind.Class && !cls.IsSealed) || cls.Kind == TypeKind.Interface) {
- ainfo.Add (cls.Kind != TypeKind.Interface ? GettextCatalog.GetString ("Find _derived classes") : GettextCatalog.GetString ("Find _implementor classes"), new System.Action (new FindDerivedClasses (cls).Run));
+ var label = cls.Kind != TypeKind.Interface ? GettextCatalog.GetString ("Find _derived classes") : GettextCatalog.GetString ("Find _implementor classes");
+ var a = ainfo.Add (label, new System.Action (new FindDerivedClasses (cls).Run));
+ a.AccelKey = IdeApp.CommandService.GetCommandInfo (RefactoryCommands.FindDerivedClasses).AccelKey;
}
ainfo.Add (GettextCatalog.GetString ("Find Extension Methods"), new System.Action (new FindExtensionMethodHandler (doc, cls).Run));
added = true;