diff options
Diffstat (limited to 'main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles')
10 files changed, 283 insertions, 232 deletions
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FileProvider.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FileProvider.cs index cd1ab5e91b..0d1fd091d4 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FileProvider.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FileProvider.cs @@ -22,10 +22,10 @@ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE.
-
-using System.IO;
-using System.Linq;
+// THE SOFTWARE. + +using System.IO; +using System.Linq; using MonoDevelop.Projects; using MonoDevelop.Ide.Gui; using System.Text; @@ -80,8 +80,9 @@ namespace MonoDevelop.Ide.FindInFiles if (buffer != null) return buffer.ToString (); var doc = SearchDocument (); - if (doc != null) + if (doc != null && doc.Editor != null) { return doc.Editor.Text; + } try { if (!File.Exists (FileName)) return null; @@ -92,11 +93,11 @@ namespace MonoDevelop.Ide.FindInFiles } } - Document SearchDocument ()
- {
- return IdeApp.Workbench.Documents.FirstOrDefault(d => !string.IsNullOrEmpty (d.FileName) && Path.GetFullPath (d.FileName) == Path.GetFullPath (FileName));
- }
-
+ Document SearchDocument () + { + return IdeApp.Workbench.Documents.FirstOrDefault(d => !string.IsNullOrEmpty (d.FileName) && Path.GetFullPath (d.FileName) == Path.GetFullPath (FileName)); + } + Document document; StringBuilder buffer = null; bool somethingReplaced; diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FindInFilesDialog.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FindInFilesDialog.cs index 8ddfbccf09..136bb723de 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FindInFilesDialog.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FindInFilesDialog.cs @@ -735,7 +735,7 @@ namespace MonoDevelop.Ide.FindInFiles SearchReplace (comboboxentryFind.Entry.Text, null, GetScope (), GetFilterOptions (), () => UpdateStopButton ()); } - readonly static List<ISearchProgressMonitor> searchesInProgress = new List<ISearchProgressMonitor> (); + readonly static List<CancellationTokenSource> searchesInProgress = new List<CancellationTokenSource> (); void UpdateStopButton () { buttonStop.Sensitive = searchesInProgress.Count > 0; @@ -746,19 +746,19 @@ namespace MonoDevelop.Ide.FindInFiles lock (searchesInProgress) { if (searchesInProgress.Count == 0) return; - ISearchProgressMonitor monitor = searchesInProgress[searchesInProgress.Count - 1]; - monitor.AsyncOperation.Cancel (); + var cs = searchesInProgress[searchesInProgress.Count - 1]; + cs.Cancel (); } } - internal static void SearchReplace (string findPattern, string replacePattern, Scope scope, FilterOptions options, System.Action UpdateStopButton) + internal async static void SearchReplace (string findPattern, string replacePattern, Scope scope, FilterOptions options, System.Action UpdateStopButton) { if (find != null && find.IsRunning) { if (!MessageService.Confirm (GettextCatalog.GetString ("There is a search already in progress. Do you want to stop it?"), AlertButton.Stop)) return; lock (searchesInProgress) { - foreach (var mon in searchesInProgress) - mon.AsyncOperation.Cancel (); + foreach (var cs in searchesInProgress) + cs.Cancel (); searchesInProgress.Clear (); } } @@ -779,57 +779,52 @@ namespace MonoDevelop.Ide.FindInFiles return; } - ThreadPool.QueueUserWorkItem (delegate { - using (ISearchProgressMonitor searchMonitor = IdeApp.Workbench.ProgressMonitors.GetSearchProgressMonitor (true)) { - searchMonitor.ReportStatus (scope.GetDescription (options, pattern, null)); - - lock (searchesInProgress) - searchesInProgress.Add (searchMonitor); - if (UpdateStopButton != null) { - Application.Invoke (delegate { - UpdateStopButton (); - }); + using (SearchProgressMonitor searchMonitor = IdeApp.Workbench.ProgressMonitors.GetSearchProgressMonitor (true)) { + searchMonitor.ReportStatus (scope.GetDescription (options, pattern, null)); + var cs = CancellationTokenSource.CreateLinkedTokenSource (searchMonitor.CancellationToken); + lock (searchesInProgress) + searchesInProgress.Add (cs); + if (UpdateStopButton != null) + UpdateStopButton (); + + DateTime timer = DateTime.Now; + string errorMessage = null; + + try { + ResultQueue<SearchResult> results = new ResultQueue<SearchResult> (); + find.FindAll (scope, searchMonitor, pattern, replacePattern, options, results); + SearchResult[] res = await results.DequeueMany (); + while (res.Length > 0) { + if (cs.IsCancellationRequested) + return; + searchMonitor.ReportResults (res); + res = await results.DequeueMany (); } - - DateTime timer = DateTime.Now; - string errorMessage = null; - - try { - var results = new List<SearchResult> (); - foreach (SearchResult result in find.FindAll (scope, searchMonitor, pattern, replacePattern, options)) { - if (searchMonitor.IsCancelRequested) - return; - results.Add (result); - } - searchMonitor.ReportResults (results); - } catch (Exception ex) { - errorMessage = ex.Message; - LoggingService.LogError ("Error while search", ex); - } - - string message; - if (errorMessage != null) { - message = GettextCatalog.GetString ("The search could not be finished: {0}", errorMessage); - searchMonitor.ReportError (message, null); - } else if (searchMonitor.IsCancelRequested) { - message = GettextCatalog.GetString ("Search cancelled."); - searchMonitor.ReportWarning (message); - } else { - string matches = string.Format (GettextCatalog.GetPluralString ("{0} match found", "{0} matches found", find.FoundMatchesCount), find.FoundMatchesCount); - string files = string.Format (GettextCatalog.GetPluralString ("in {0} file.", "in {0} files.", find.SearchedFilesCount), find.SearchedFilesCount); - message = GettextCatalog.GetString ("Search completed.") + Environment.NewLine + matches + " " + files; - searchMonitor.ReportSuccess (message); - } - searchMonitor.ReportStatus (message); - searchMonitor.Log.WriteLine (GettextCatalog.GetString ("Search time: {0} seconds."), (DateTime.Now - timer).TotalSeconds); - searchesInProgress.Remove (searchMonitor); + } catch (Exception ex) { + errorMessage = ex.Message; + LoggingService.LogError ("Error while search", ex); } - if (UpdateStopButton != null) { - Application.Invoke (delegate { - UpdateStopButton (); - }); + + string message; + if (errorMessage != null) { + message = GettextCatalog.GetString ("The search could not be finished: {0}", errorMessage); + searchMonitor.ReportError (message, null); + } else if (cs.IsCancellationRequested) { + message = GettextCatalog.GetString ("Search cancelled."); + searchMonitor.ReportWarning (message); + } else { + string matches = string.Format (GettextCatalog.GetPluralString ("{0} match found", "{0} matches found", find.FoundMatchesCount), find.FoundMatchesCount); + string files = string.Format (GettextCatalog.GetPluralString ("in {0} file.", "in {0} files.", find.SearchedFilesCount), find.SearchedFilesCount); + message = GettextCatalog.GetString ("Search completed.") + Environment.NewLine + matches + " " + files; + searchMonitor.ReportSuccess (message); } - }); + searchMonitor.ReportStatus (message); + searchMonitor.Log.WriteLine (GettextCatalog.GetString ("Search time: {0} seconds."), (DateTime.Now - timer).TotalSeconds); + searchesInProgress.Remove (cs); + } + if (UpdateStopButton != null) { + UpdateStopButton (); + } } } } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FindReplace.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FindReplace.cs index 5953b25a5f..80b0c2677a 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FindReplace.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FindReplace.cs @@ -31,6 +31,9 @@ using System.Collections.Generic; using MonoDevelop.Core; using System.Linq; using Gtk; +using System.Threading.Tasks; +using System.Collections.Concurrent; +using System.Threading; namespace MonoDevelop.Ide.FindInFiles { @@ -71,7 +74,7 @@ namespace MonoDevelop.Ide.FindInFiles return true; } - public IEnumerable<SearchResult> FindAll (Scope scope, IProgressMonitor monitor, string pattern, string replacePattern, FilterOptions filter) + public async Task FindAll (Scope scope, ProgressMonitor monitor, string pattern, string replacePattern, FilterOptions filter, ResultQueue<SearchResult> results) { if (filter.RegexSearch) { RegexOptions regexOptions = RegexOptions.Compiled; @@ -84,42 +87,49 @@ namespace MonoDevelop.Ide.FindInFiles monitor.BeginTask (scope.GetDescription (filter, pattern, replacePattern), 50); try { - int totalWork = scope.GetTotalWork (filter); + int totalWork = await scope.GetTotalWork (filter); int step = Math.Max (1, totalWork / 50); string content; - - foreach (FileProvider provider in scope.GetFiles (monitor, filter)) { - if (monitor.IsCancelRequested)
- yield break; - SearchedFilesCount++; - try { - content = provider.ReadString (); + + var files = new ResultQueue<FileProvider> (); + scope.GetFiles (monitor, filter, files); + + await Task.Factory.StartNew (delegate { + FileProvider provider; + while (files.TryDequeue (out provider)) { + if (monitor.CancellationToken.IsCancellationRequested) + break;
+ SearchedFilesCount++; + try { + content = provider.ReadString (); + if (replacePattern != null) + provider.BeginReplace (content); + } catch (System.IO.FileNotFoundException) { + Application.Invoke (delegate { + MessageService.ShowError (string.Format (GettextCatalog.GetString ("File {0} not found.")), provider.FileName); + }); + continue; + } + foreach (SearchResult result in FindAll (monitor, provider, content, pattern, replacePattern, filter)) { + if (monitor.CancellationToken.IsCancellationRequested)
+ break; + FoundMatchesCount++; + results.Enqueue (result); + } if (replacePattern != null) - provider.BeginReplace (content); - } catch (System.IO.FileNotFoundException) { - Application.Invoke (delegate { - MessageService.ShowError (string.Format (GettextCatalog.GetString ("File {0} not found.")), provider.FileName); - }); - continue; - } - foreach (SearchResult result in FindAll (monitor, provider, content, pattern, replacePattern, filter)) { - if (monitor.IsCancelRequested)
- yield break; - FoundMatchesCount++; - yield return result; + provider.EndReplace ();
+ if (SearchedFilesCount % step == 0)
+ monitor.Step (1);
} - if (replacePattern != null) - provider.EndReplace ();
- if (SearchedFilesCount % step == 0)
- monitor.Step (1);
- } + results.SetComplete (); + }); } finally { monitor.EndTask (); IsRunning = false; } } - IEnumerable<SearchResult> FindAll (IProgressMonitor monitor, FileProvider provider, string content, string pattern, string replacePattern, FilterOptions filter) + IEnumerable<SearchResult> FindAll (ProgressMonitor monitor, FileProvider provider, string content, string pattern, string replacePattern, FilterOptions filter) { if (string.IsNullOrEmpty (pattern)) return Enumerable.Empty<SearchResult> (); @@ -130,12 +140,12 @@ namespace MonoDevelop.Ide.FindInFiles return Search (provider, content, pattern, replacePattern, filter); } - IEnumerable<SearchResult> RegexSearch (IProgressMonitor monitor, FileProvider provider, string content, string replacePattern, FilterOptions filter) + IEnumerable<SearchResult> RegexSearch (ProgressMonitor monitor, FileProvider provider, string content, string replacePattern, FilterOptions filter) { var results = new List<SearchResult> (); if (replacePattern == null) { foreach (Match match in regex.Matches (content)) { - if (monitor.IsCancelRequested) + if (monitor.CancellationToken.IsCancellationRequested) break; if (provider.SelectionStartPosition > -1 && match.Index < provider.SelectionStartPosition) continue; @@ -156,7 +166,7 @@ namespace MonoDevelop.Ide.FindInFiles } provider.BeginReplace (content); int delta = 0; - for (int i = 0; !monitor.IsCancelRequested && i < matches.Count; i++) { + for (int i = 0; !monitor.CancellationToken.IsCancellationRequested && i < matches.Count; i++) { Match match = matches[i]; if (!filter.WholeWordsOnly || FilterOptions.IsWholeWordAt (content, match.Index, match.Length)) { string replacement = match.Result (replacePattern); @@ -192,4 +202,66 @@ namespace MonoDevelop.Ide.FindInFiles } } } + + public class ResultQueue<T> + { + Queue<T> queue = new Queue<T>(); + bool complete; + + public void Enqueue (T v) + { + lock (queue) { + queue.Enqueue (v); + Monitor.PulseAll (queue); + } + } + + public bool TryDequeue (out T value) + { + lock (queue) { + if (queue.Count == 0) + WaitForValues (); + if (complete) { + value = default(T); + return false; + } + value = queue.Dequeue (); + return true; + } + } + + public async Task<T[]> DequeueMany () + { + lock (queue) { + if (queue.Count > 0 || complete) { + var res = queue.ToArray (); + queue.Clear (); + return res; + } + } + return await Task<T[]>.Factory.StartNew (() => { + WaitForValues (); + var res = queue.ToArray (); + queue.Clear (); + return res; + }); + } + + void WaitForValues () + { + lock (queue) { + while (queue.Count == 0 && !complete) { + Monitor.Wait (queue); + } + } + } + + public void SetComplete () + { + lock (queue) { + complete = true; + Monitor.PulseAll (queue); + } + } + } } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/ISearchProgressMonitor.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/ISearchProgressMonitor.cs index af1da6d9a8..0dacb70a51 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/ISearchProgressMonitor.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/ISearchProgressMonitor.cs @@ -32,7 +32,7 @@ using MonoDevelop.Core; namespace MonoDevelop.Ide.FindInFiles { - public interface ISearchProgressMonitor: IProgressMonitor + public interface ISearchProgressMonitor { void SetBasePath (string path); void ReportResult (SearchResult result); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/ReferencesFinder.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/ReferencesFinder.cs index 0600d9f415..9691a93978 100755..100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/ReferencesFinder.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/ReferencesFinder.cs @@ -76,12 +76,12 @@ namespace MonoDevelop.Ide.FindInFiles return codon != null ? codon.CreateFinder () : null; } - public static IEnumerable<MemberReference> FindReferences (object member, bool searchForAllOverloads, IProgressMonitor monitor = null) + public static IEnumerable<MemberReference> FindReferences (object member, bool searchForAllOverloads, ProgressMonitor monitor = null) { return FindReferences (IdeApp.ProjectOperations.CurrentSelectedSolution, member, searchForAllOverloads, RefactoryScope.Unknown, monitor); } - public static IEnumerable<MemberReference> FindReferences (object member, bool searchForAllOverloads, RefactoryScope scope, IProgressMonitor monitor = null) + public static IEnumerable<MemberReference> FindReferences (object member, bool searchForAllOverloads, RefactoryScope scope, ProgressMonitor monitor = null) { return FindReferences (IdeApp.ProjectOperations.CurrentSelectedSolution, member, searchForAllOverloads, scope, monitor); } @@ -95,7 +95,7 @@ namespace MonoDevelop.Ide.FindInFiles } static IEnumerable<SearchCollector.FileList> GetFileNames (Solution solution, object node, RefactoryScope scope, - IProgressMonitor monitor, IEnumerable<object> searchNodes) + ProgressMonitor monitor, IEnumerable<object> searchNodes) { if (!(node is IField) && !(node is IParameter) && node is IVariable || scope == RefactoryScope.File) { string fileName; @@ -147,7 +147,7 @@ namespace MonoDevelop.Ide.FindInFiles if (monitor != null) monitor.BeginTask (GettextCatalog.GetString ("Searching for references in solution..."), files.Count); foreach (var file in files) { - if (monitor != null && monitor.IsCancelRequested) + if (monitor != null && monitor.CancellationToken.IsCancellationRequested) yield break; yield return file; if (monitor != null) @@ -170,7 +170,7 @@ namespace MonoDevelop.Ide.FindInFiles return projects; } - public static IEnumerable<MemberReference> FindReferences (Solution solution, object member, bool searchForAllOverloads, RefactoryScope scope = RefactoryScope.Unknown, IProgressMonitor monitor = null) + public static IEnumerable<MemberReference> FindReferences (Solution solution, object member, bool searchForAllOverloads, RefactoryScope scope = RefactoryScope.Unknown, ProgressMonitor monitor = null) { if (member == null) yield break;
@@ -204,7 +204,7 @@ namespace MonoDevelop.Ide.FindInFiles foreach (var info in GetFileNames (solution, member, scope, monitor, searchNodes)) { string oldMime = null; foreach (var file in info.Files) { - if (monitor != null && monitor.IsCancelRequested) + if (monitor != null && monitor.CancellationToken.IsCancellationRequested) yield break; string mime = DesktopService.GetMimeTypeForUri (file); @@ -230,7 +230,7 @@ namespace MonoDevelop.Ide.FindInFiles foreach (var tuple in preparedFinders) { var finder = tuple.Item1; foreach (var foundReference in finder.FindReferences (tuple.Item2, tuple.Item3, tuple.Item4, monitor, searchNodes)) { - if (monitor != null && monitor.IsCancelRequested) + if (monitor != null && monitor.CancellationToken.IsCancellationRequested) yield break; var tag = Tuple.Create (foundReference.FileName, foundReference.Region); if (foundOccurrences.Contains (tag)) @@ -243,7 +243,7 @@ namespace MonoDevelop.Ide.FindInFiles monitor.EndTask (); } - public abstract IEnumerable<MemberReference> FindReferences (Project project, IProjectContent content, IEnumerable<FilePath> files, IProgressMonitor monitor, IEnumerable<object> searchedMembers);
+ public abstract IEnumerable<MemberReference> FindReferences (Project project, IProjectContent content, IEnumerable<FilePath> files, ProgressMonitor monitor, IEnumerable<object> searchedMembers);
internal static IEnumerable<IMember> CollectMembers (Solution solution, IMember member, RefactoryScope scope, bool includeOverloads = true)
{
@@ -252,8 +252,11 @@ namespace MonoDevelop.Ide.FindInFiles internal static IEnumerable<IEntity> CollectMembers (IType type) { - yield return (IEntity)type; - foreach (var c in type.GetDefinition ().GetMembers (m => m.SymbolKind == SymbolKind.Constructor, GetMemberOptions.IgnoreInheritedMembers)) { + var typeDefinition = type.GetDefinition (); + if (typeDefinition == null) + yield break; + yield return (IEntity)typeDefinition; + foreach (var c in typeDefinition.GetMembers (m => m.SymbolKind == SymbolKind.Constructor, GetMemberOptions.IgnoreInheritedMembers)) { if (!c.IsSynthetic) yield return c; } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/Scope.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/Scope.cs index fff1d1202b..ca62a49cd9 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/Scope.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/Scope.cs @@ -33,6 +33,7 @@ using MonoDevelop.Ide.Gui; using MonoDevelop.Core; using System.Security.Permissions; using System.Security; +using System.Threading.Tasks; namespace MonoDevelop.Ide.FindInFiles @@ -44,22 +45,24 @@ namespace MonoDevelop.Ide.FindInFiles set; } - public abstract int GetTotalWork (FilterOptions filterOptions); - public abstract IEnumerable<FileProvider> GetFiles (IProgressMonitor monitor, FilterOptions filterOptions); + public abstract Task<int> GetTotalWork (FilterOptions filterOptions); + public abstract Task GetFiles (ProgressMonitor monitor, FilterOptions filterOptions, ResultQueue<FileProvider> results); public abstract string GetDescription (FilterOptions filterOptions, string pattern, string replacePattern); } public class DocumentScope : Scope { - public override int GetTotalWork (FilterOptions filterOptions) + public override Task<int> GetTotalWork (FilterOptions filterOptions) { - return 1; + return Task.FromResult (1); }
- public override IEnumerable<FileProvider> GetFiles (IProgressMonitor monitor, FilterOptions filterOptions) + public override Task GetFiles (ProgressMonitor monitor, FilterOptions filterOptions, ResultQueue<FileProvider> results) { monitor.Log.WriteLine (GettextCatalog.GetString ("Looking in '{0}'", IdeApp.Workbench.ActiveDocument.FileName)); - yield return new FileProvider(IdeApp.Workbench.ActiveDocument.FileName); + results.Enqueue (new FileProvider(IdeApp.Workbench.ActiveDocument.FileName)); + results.SetComplete (); + return Task.FromResult (0); } public override string GetDescription(FilterOptions filterOptions, string pattern, string replacePattern) @@ -73,15 +76,17 @@ namespace MonoDevelop.Ide.FindInFiles public class SelectionScope : Scope { - public override int GetTotalWork (FilterOptions filterOptions) + public override Task<int> GetTotalWork (FilterOptions filterOptions) { - return 1; + return Task.FromResult (1); }
- public override IEnumerable<FileProvider> GetFiles (IProgressMonitor monitor, FilterOptions filterOptions) + public override Task GetFiles (ProgressMonitor monitor, FilterOptions filterOptions, ResultQueue<FileProvider> results) { var selection = IdeApp.Workbench.ActiveDocument.Editor.SelectionRange; - yield return new FileProvider(IdeApp.Workbench.ActiveDocument.FileName, null, selection.Offset, selection.EndOffset); + results.Enqueue (new FileProvider (IdeApp.Workbench.ActiveDocument.FileName, null, selection.Offset, selection.EndOffset)); + results.SetComplete (); + return Task.FromResult (0); } public override string GetDescription(FilterOptions filterOptions, string pattern, string replacePattern) @@ -95,40 +100,44 @@ namespace MonoDevelop.Ide.FindInFiles public class WholeSolutionScope : Scope { - public override int GetTotalWork (FilterOptions filterOptions) + public override Task<int> GetTotalWork (FilterOptions filterOptions) { int result = 0; if (IdeApp.Workspace.IsOpen) result = IdeApp.Workspace.GetAllProjects ().Sum (p => p.Files.Count); - return result; + return Task.FromResult (result); } - public override IEnumerable<FileProvider> GetFiles (IProgressMonitor monitor, FilterOptions filterOptions) + public async override Task GetFiles (ProgressMonitor monitor, FilterOptions filterOptions, ResultQueue<FileProvider> results) { if (IdeApp.Workspace.IsOpen) { var alreadyVisited = new HashSet<string> (); - foreach (var solutionFolder in IdeApp.Workspace.GetAllSolutionItems().OfType<SolutionFolder>()) { - monitor.Log.WriteLine (GettextCatalog.GetString ("Looking in solution folder '{0}'", solutionFolder.Name)); - foreach (var file in solutionFolder.Files.Where (f => filterOptions.NameMatches (f.FileName) && File.Exists (f.FullPath))) { + var allFiles = IdeApp.Workspace.GetAllSolutionItems ().OfType<SolutionFolder> ().SelectMany (sf => sf.Files).Where (f => filterOptions.NameMatches (f.FileName)).Select (f => f.FullPath).ToArray (); + await Task.Factory.StartNew (delegate { + foreach (var file in allFiles.Where (f => File.Exists (f.FullPath))) { if (!IncludeBinaryFiles && !DesktopService.GetFileIsText (file.FullPath)) continue; if (alreadyVisited.Contains (file.FullPath)) continue; alreadyVisited.Add (file.FileName); - yield return new FileProvider (file.FullPath); + results.Enqueue (new FileProvider (file.FullPath)); } - } - foreach (Project project in IdeApp.Workspace.GetAllProjects ()) { - monitor.Log.WriteLine (GettextCatalog.GetString ("Looking in project '{0}'", project.Name)); - foreach (ProjectFile file in project.Files.Where (f => filterOptions.NameMatches (f.Name) && File.Exists (f.Name))) { - if (!IncludeBinaryFiles && !DesktopService.GetFileIsText (file.FilePath)) + results.SetComplete (); + }); + + var allProjectFiles = IdeApp.Workspace.GetAllProjects ().SelectMany (project => project.Files).Where (f => filterOptions.NameMatches (f.Name)).Select (f => new Tuple<Project,string>(f.Project,f.Name)).ToArray (); + await Task.Factory.StartNew (delegate { + foreach (var ft in allProjectFiles.Where (f => File.Exists (f.Item2))) { + var file = ft.Item2; + if (!IncludeBinaryFiles && !DesktopService.GetFileIsText (file)) continue; - if (alreadyVisited.Contains (file.Name)) + if (alreadyVisited.Contains (file)) continue; - alreadyVisited.Add (file.Name); - yield return new FileProvider (file.Name, project); + alreadyVisited.Add (file); + results.Enqueue (new FileProvider (file, ft.Item1)); } - } + results.SetComplete (); + }); } } @@ -144,9 +153,9 @@ namespace MonoDevelop.Ide.FindInFiles {
readonly Project project; - public override int GetTotalWork (FilterOptions filterOptions) + public override Task<int> GetTotalWork (FilterOptions filterOptions) { - return project.Files.Count; + return Task.FromResult (project.Files.Count); } public WholeProjectScope (Project project) @@ -157,21 +166,26 @@ namespace MonoDevelop.Ide.FindInFiles this.project = project; } - public override IEnumerable<FileProvider> GetFiles (IProgressMonitor monitor, FilterOptions filterOptions) + public override Task GetFiles (ProgressMonitor monitor, FilterOptions filterOptions, ResultQueue<FileProvider> results) { if (IdeApp.Workspace.IsOpen) { monitor.Log.WriteLine (GettextCatalog.GetString ("Looking in project '{0}'", project.Name)); var alreadyVisited = new HashSet<string> (); - foreach (ProjectFile file in project.Files.Where (f => filterOptions.NameMatches (f.Name) && File.Exists (f.Name))) { - if (!IncludeBinaryFiles && !DesktopService.GetFileIsText (file.Name)) - continue; + var allFiles = project.Files.Where (f => filterOptions.NameMatches (f.Name) && File.Exists (f.Name)).Select (f => f.Name).ToArray (); + return Task.Factory.StartNew (delegate { + foreach (string file in allFiles) { + if (!IncludeBinaryFiles && !DesktopService.GetFileIsText (file)) + continue; - if (alreadyVisited.Contains (file.Name)) - continue; - alreadyVisited.Add (file.Name); - yield return new FileProvider (file.Name, project); - } + if (alreadyVisited.Contains (file)) + continue; + alreadyVisited.Add (file); + results.Enqueue (new FileProvider (file, project)); + } + results.SetComplete (); + }); } + return Task.FromResult (0); } public override string GetDescription (FilterOptions filterOptions, string pattern, string replacePattern) @@ -185,18 +199,20 @@ namespace MonoDevelop.Ide.FindInFiles public class AllOpenFilesScope : Scope { - public override int GetTotalWork (FilterOptions filterOptions) + public override Task<int> GetTotalWork (FilterOptions filterOptions) { - return IdeApp.Workbench.Documents.Count; + return Task.FromResult (IdeApp.Workbench.Documents.Count); }
- public override IEnumerable<FileProvider> GetFiles (IProgressMonitor monitor, FilterOptions filterOptions) + public override Task GetFiles (ProgressMonitor monitor, FilterOptions filterOptions, ResultQueue<FileProvider> results) { foreach (Document document in IdeApp.Workbench.Documents) { monitor.Log.WriteLine (GettextCatalog.GetString ("Looking in '{0}'", document.FileName)); if (!string.IsNullOrEmpty (document.FileName) && filterOptions.NameMatches (document.FileName)) - yield return new FileProvider (document.FileName); + results.Enqueue (new FileProvider (document.FileName)); } + results.SetComplete (); + return Task.FromResult (0); } public override string GetDescription (FilterOptions filterOptions, string pattern, string replacePattern) @@ -218,9 +234,11 @@ namespace MonoDevelop.Ide.FindInFiles set; } - public override int GetTotalWork (FilterOptions filterOptions) + public override Task<int> GetTotalWork (FilterOptions filterOptions) { - return GetFileNames (null, filterOptions).Count (); + return Task<int>.Factory.StartNew (delegate { + return GetFileNames (null, filterOptions).Count (); + }); } public DirectoryScope (string path, bool recurse) @@ -229,7 +247,7 @@ namespace MonoDevelop.Ide.FindInFiles this.recurse = recurse; } - IEnumerable<string> GetFileNames (IProgressMonitor monitor, FilterOptions filterOptions) + IEnumerable<string> GetFileNames (ProgressMonitor monitor, FilterOptions filterOptions) { if (monitor != null) monitor.Log.WriteLine (GettextCatalog.GetString ("Looking in '{0}'", path)); @@ -282,9 +300,13 @@ namespace MonoDevelop.Ide.FindInFiles } } - public override IEnumerable<FileProvider> GetFiles (IProgressMonitor monitor, FilterOptions filterOptions)
- {
- return GetFileNames (monitor, filterOptions).Select (file => new FileProvider (file));
+ public override Task GetFiles (ProgressMonitor monitor, FilterOptions filterOptions, ResultQueue<FileProvider> results)
+ { + return Task.Factory.StartNew (delegate {
+ foreach (var r in GetFileNames (monitor, filterOptions).Select (file => new FileProvider (file))) + results.Enqueue (r); + results.SetComplete (); + });
}
public override string GetDescription (FilterOptions filterOptions, string pattern, string replacePattern) diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchCollector.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchCollector.cs index 34f423630a..e33d6099f4 100755 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchCollector.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchCollector.cs @@ -249,7 +249,10 @@ namespace MonoDevelop.Ide.FindInFiles else { foreach (var project in ReferenceFinder.GetAllReferencingProjects (solution, sourceProject)) { if (entity.Accessibility == Accessibility.Internal || entity.Accessibility == Accessibility.ProtectedAndInternal) { - if (!entity.ParentAssembly.InternalsVisibleTo (TypeSystemService.GetProjectContentWrapper (project).Compilation.MainAssembly)) + var wrapper = TypeSystemService.GetProjectContentWrapper (project); + if (wrapper == null) + continue; + if (!entity.ParentAssembly.InternalsVisibleTo (wrapper.Compilation.MainAssembly)) continue; } AddProject (project); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchProgressMonitor.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchProgressMonitor.cs index 4923f53fd3..d695fc29fa 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchProgressMonitor.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchProgressMonitor.cs @@ -34,55 +34,52 @@ using MonoDevelop.Ide.Gui; namespace MonoDevelop.Ide.FindInFiles { - class SearchProgressMonitor : BaseProgressMonitor, ISearchProgressMonitor + public class SearchProgressMonitor : ProgressMonitor, ISearchProgressMonitor { SearchResultPad outputPad;
- readonly IProgressMonitor statusMonitor;
- public SearchProgressMonitor (Pad pad) + public SearchProgressMonitor (Pad pad): base (Runtime.MainSynchronizationContext) { + AddSlaveMonitor (IdeApp.Workbench.ProgressMonitors.GetStatusProgressMonitor (GettextCatalog.GetString ("Searching..."), Stock.StatusSearch, false, true, false, pad)); + outputPad = (SearchResultPad) pad.Content; - outputPad.AsyncOperation = AsyncOperation; + outputPad.CancellationTokenSource = CancellationTokenSource; outputPad.BeginProgress (pad.Title); - statusMonitor = IdeApp.Workbench.ProgressMonitors.GetStatusProgressMonitor (GettextCatalog.GetString ("Searching..."), Stock.StatusSearch, false, true, false, pad); - } - - [FreeDispatch] - public bool AllowReuse { - get { return outputPad.AllowReuse; } } - [FreeDispatch] public void SetBasePath (string path) { outputPad.BasePath = path; } - [AsyncDispatch] public void ReportResult (SearchResult result) { - try { - outputPad.ReportResult (result); - } catch (Exception ex) { - LoggingService.LogError ("Error adding search result for file {0}:{1} to result pad:\n{2}", - result.FileName, result.Offset, ex.ToString ()); - } + DispatchService.GuiDispatch (delegate { + try { + outputPad.ReportResult (result); + } catch (Exception ex) { + LoggingService.LogError ("Error adding search result for file {0}:{1} to result pad:\n{2}", + result.FileName, result.Offset, ex.ToString ()); + } + }); } - [AsyncDispatch] public void ReportResults (IEnumerable<SearchResult> results) { - try { - outputPad.ReportResults (results); - } catch (Exception ex) { - LoggingService.LogError ("Error adding search results.", ex.ToString ()); - } + DispatchService.GuiDispatch (delegate { + try { + outputPad.ReportResults (results); + } catch (Exception ex) { + LoggingService.LogError ("Error adding search results.", ex.ToString ()); + } + }); } - [AsyncDispatch] public void ReportStatus (string resultMessage) { - outputPad.ReportStatus (resultMessage); + DispatchService.GuiDispatch (delegate { + outputPad.ReportStatus (resultMessage); + }); } protected override void OnWriteLog (string text) @@ -93,8 +90,6 @@ namespace MonoDevelop.Ide.FindInFiles protected override void OnCompleted () { - statusMonitor.Dispose (); - if (outputPad == null) throw GetDisposedException (); outputPad.WriteText ("\n"); @@ -104,8 +99,8 @@ namespace MonoDevelop.Ide.FindInFiles foreach (string msg in Warnings) outputPad.WriteText (msg + "\n"); - foreach (string msg in Errors) - outputPad.WriteText (msg + "\n"); + foreach (var msg in Errors) + outputPad.WriteText (msg.Message + "\n"); outputPad.EndProgress (); base.OnCompleted (); @@ -117,47 +112,5 @@ namespace MonoDevelop.Ide.FindInFiles { return new InvalidOperationException ("Search progress monitor already disposed."); } - - public override void ReportError (string message, Exception ex) - { - base.ReportError (message, ex); - statusMonitor.ReportError (message, ex); - } - - public override void ReportSuccess (string message) - { - base.ReportSuccess (message); - statusMonitor.ReportSuccess (message); - } - - public override void ReportWarning (string message) - { - base.ReportWarning (message); - statusMonitor.ReportWarning (message); - } - - public override void Step (int work) - { - base.Step (work); - statusMonitor.Step (work); - } - - public override void BeginStepTask (string name, int totalWork, int stepSize) - { - base.BeginStepTask (name, totalWork, stepSize); - statusMonitor.BeginStepTask (name, totalWork, stepSize); - } - - public override void BeginTask (string name, int totalWork) - { - base.BeginTask (name, totalWork); - statusMonitor.BeginTask (name, totalWork); - } - - public override void EndTask () - { - base.EndTask (); - statusMonitor.EndTask (); - } } }
\ No newline at end of file diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchResultPad.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchResultPad.cs index 961d59f6b1..0a9fe845e0 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchResultPad.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchResultPad.cs @@ -30,7 +30,8 @@ using System.Collections.Generic; using MonoDevelop.Ide.Gui; using MonoDevelop.Core; using MonoDevelop.Components.Commands; -using MonoDevelop.Ide.Commands;
+using MonoDevelop.Ide.Commands; +using System.Threading;
namespace MonoDevelop.Ide.FindInFiles { @@ -50,12 +51,12 @@ namespace MonoDevelop.Ide.FindInFiles } } - public IAsyncOperation AsyncOperation { + public CancellationTokenSource CancellationTokenSource { get { - return widget.AsyncOperation; + return widget.CancellationTokenSource; } set { - widget.AsyncOperation = value; + widget.CancellationTokenSource = value; } } public bool FocusPad { diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchResultWidget.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchResultWidget.cs index 35c90f9a7c..5048ae13af 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchResultWidget.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/SearchResultWidget.cs @@ -42,6 +42,7 @@ using MonoDevelop.Ide.Gui.Content; using MonoDevelop.Ide.Navigation; using MonoDevelop.Ide.Gui.Components; using MonoDevelop.Components; +using System.Threading; namespace MonoDevelop.Ide.FindInFiles { @@ -68,7 +69,7 @@ namespace MonoDevelop.Ide.FindInFiles set; } - public IAsyncOperation AsyncOperation { + public CancellationTokenSource CancellationTokenSource { get; set; } @@ -225,8 +226,8 @@ namespace MonoDevelop.Ide.FindInFiles void ButtonStopClicked (object sender, EventArgs e) { - if (AsyncOperation != null) - AsyncOperation.Cancel (); + if (CancellationTokenSource != null) + CancellationTokenSource.Cancel (); } void TreeviewSearchResultsRowActivated(object o, RowActivatedArgs args) |