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
diff options
context:
space:
mode:
Diffstat (limited to 'main/src/core/MonoDevelop.Ide/MonoDevelop.Components.MainToolbar/ProjectSearchCategory.cs')
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Components.MainToolbar/ProjectSearchCategory.cs280
1 files changed, 113 insertions, 167 deletions
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.MainToolbar/ProjectSearchCategory.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.MainToolbar/ProjectSearchCategory.cs
index 3af7fa2545..1731f08255 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.MainToolbar/ProjectSearchCategory.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.MainToolbar/ProjectSearchCategory.cs
@@ -32,64 +32,89 @@ using MonoDevelop.Core.Instrumentation;
using MonoDevelop.Projects;
using MonoDevelop.Ide.Gui;
using MonoDevelop.Ide;
-using ICSharpCode.NRefactory.TypeSystem;
using MonoDevelop.Ide.TypeSystem;
using MonoDevelop.Core.Text;
using Gtk;
using System.Linq;
+using ICSharpCode.NRefactory6.CSharp;
+using Microsoft.CodeAnalysis;
+using System.Collections.Immutable;
+using System.Diagnostics;
+using System.Collections.Concurrent;
namespace MonoDevelop.Components.MainToolbar
{
class ProjectSearchCategory : SearchCategory
{
- SearchPopupWindow widget;
+ static SearchPopupWindow widget;
- public ProjectSearchCategory (SearchPopupWindow widget) : base (GettextCatalog.GetString("Solution"))
+ public ProjectSearchCategory (SearchPopupWindow widget) : base (GettextCatalog.GetString ("Solution"))
{
- this.widget = widget;
- this.lastResult = new WorkerResult (widget);
+ ProjectSearchCategory.widget = widget;
+ lastResult = new WorkerResult (widget);
}
+ internal static Task<ImmutableList<DeclaredSymbolInfo>> SymbolInfoTask;
+
static TimerCounter getMembersTimer = InstrumentationService.CreateTimerCounter ("Time to get all members", "NavigateToDialog");
+ static TimerCounter getTypesTimer = InstrumentationService.CreateTimerCounter ("Time to get all types", "NavigateToDialog");
+ static CancellationTokenSource symbolInfoTokenSrc = new CancellationTokenSource();
+ public static void UpdateSymbolInfos ()
+ {
+ symbolInfoTokenSrc.Cancel ();
+ symbolInfoTokenSrc = new CancellationTokenSource();
+ CancellationToken token = symbolInfoTokenSrc.Token;
+ lastResult = new WorkerResult (widget);
+ SymbolInfoTask = Task.Run (delegate {
+ return GetSymbolInfos (token);
+ }, token);
+ }
- static TimerCounter getTypesTimer = InstrumentationService.CreateTimerCounter ("Time to get all types", "NavigateToDialog");
+ static ImmutableList<DeclaredSymbolInfo> GetSymbolInfos (CancellationToken token)
+ {
+ getTypesTimer.BeginTiming ();
+ try {
+ var result = ImmutableList<DeclaredSymbolInfo>.Empty;
+ Stopwatch sw = new Stopwatch();
+ sw.Start ();
+ foreach (var workspace in TypeSystemService.AllWorkspaces) {
+ result = result.AddRange (workspace.CurrentSolution.Projects.Select (p => SearchAsync (p, token)).SelectMany (i => i));
+ }
+ sw.Stop ();
+ return result;
+ } catch (AggregateException ae) {
+ ae.Flatten ().Handle (ex => ex is TaskCanceledException);
+ return ImmutableList<DeclaredSymbolInfo>.Empty;
+ } catch (TaskCanceledException) {
+ return ImmutableList<DeclaredSymbolInfo>.Empty;
+ } finally {
+ getTypesTimer.EndTiming ();
+ }
+ }
- IEnumerable<ITypeDefinition> types {
- get {
- getTypesTimer.BeginTiming ();
+ static IEnumerable<DeclaredSymbolInfo> SearchAsync(Microsoft.CodeAnalysis.Project project, CancellationToken cancellationToken)
+ {
+ var result = new ConcurrentBag<DeclaredSymbolInfo> ();
+ Parallel.ForEach (project.Documents, async delegate (Microsoft.CodeAnalysis.Document document) {
try {
- foreach (Document doc in IdeApp.Workbench.Documents) {
- // We only want to check it here if it's not part
- // of the open combine. Otherwise, it will get
- // checked down below.
- if (doc.Project == null && doc.IsFile) {
- var info = doc.ParsedDocument;
- if (info != null) {
- var ctx = doc.Compilation;
- foreach (var type in ctx.MainAssembly.GetAllTypeDefinitions ()) {
- yield return type;
- }
- }
+ cancellationToken.ThrowIfCancellationRequested ();
+ var root = await document.GetSyntaxRootAsync (cancellationToken).ConfigureAwait (false);
+ foreach (var current in root.DescendantNodesAndSelf (CSharpSyntaxFactsService.DescentIntoSymbolForDeclarationSearch)) {
+ DeclaredSymbolInfo declaredSymbolInfo;
+ if (current.TryGetDeclaredSymbolInfo (out declaredSymbolInfo)) {
+ result.Add (declaredSymbolInfo);
}
}
-
- var projects = IdeApp.Workspace.GetAllProjects ();
-
- foreach (Project p in projects) {
- var pctx = TypeSystemService.GetCompilation (p);
- foreach (var type in pctx.MainAssembly.GetAllTypeDefinitions ())
- yield return type;
- }
- } finally {
- getTypesTimer.EndTiming ();
+ } catch (OperationCanceledException) {
}
- }
+ });
+ return (IEnumerable<DeclaredSymbolInfo>)result;
}
- WorkerResult lastResult;
- string[] typeTags = new [] { "type", "c", "s", "i", "e", "d"};
- string[] memberTags = new [] { "member", "m", "p", "f", "evt"};
+ static WorkerResult lastResult;
+ string[] typeTags = new [] { "type", "c", "s", "i", "e", "d" };
+ string[] memberTags = new [] { "member", "m", "p", "f", "evt" };
public override bool IsValidTag (string tag)
{
@@ -98,7 +123,7 @@ namespace MonoDevelop.Components.MainToolbar
public override Task<ISearchDataSource> GetResults (SearchPopupSearchPattern searchPattern, int resultsCount, CancellationToken token)
{
- return Task.Factory.StartNew (delegate {
+ return Task.Run (delegate {
if (searchPattern.Tag != null && !(typeTags.Contains (searchPattern.Tag) || memberTags.Contains (searchPattern.Tag)) || searchPattern.HasLineNumber)
return null;
try {
@@ -106,11 +131,12 @@ namespace MonoDevelop.Components.MainToolbar
newResult.pattern = searchPattern.Pattern;
newResult.IncludeFiles = true;
newResult.Tag = searchPattern.Tag;
- newResult.IncludeTypes = searchPattern.Tag == null || typeTags.Contains (searchPattern.Tag) ;
+ newResult.IncludeTypes = searchPattern.Tag == null || typeTags.Contains (searchPattern.Tag);
newResult.IncludeMembers = searchPattern.Tag == null || memberTags.Contains (searchPattern.Tag);
- var firstType = types.FirstOrDefault ();
- newResult.ambience = firstType != null ? AmbienceService.GetAmbienceForFile (firstType.Region.FileName) : AmbienceService.DefaultAmbience;
-
+ ImmutableList<DeclaredSymbolInfo> allTypes;
+ if (SymbolInfoTask == null)
+ SymbolInfoTask = Task.FromResult(GetSymbolInfos (token));
+ allTypes = SymbolInfoTask.Result;
string toMatch = searchPattern.Pattern;
newResult.matcher = StringMatcher.GetMatcher (toMatch, false);
newResult.FullSearch = toMatch.IndexOf ('.') > 0;
@@ -119,7 +145,7 @@ namespace MonoDevelop.Components.MainToolbar
oldLastResult = new WorkerResult (widget);
// var now = DateTime.Now;
- AllResults (oldLastResult, newResult, token);
+ AllResults (oldLastResult, newResult, allTypes, token);
newResult.results.SortUpToN (new DataItemComparer (token), resultsCount);
lastResult = newResult;
// Console.WriteLine ((now - DateTime.Now).TotalMilliseconds);
@@ -131,104 +157,58 @@ namespace MonoDevelop.Components.MainToolbar
}, token);
}
- void AllResults (WorkerResult lastResult, WorkerResult newResult, CancellationToken token)
+ void AllResults (WorkerResult lastResult, WorkerResult newResult, IReadOnlyList<DeclaredSymbolInfo> completeTypeList, CancellationToken token)
{
if (newResult.isGotoFilePattern)
return;
uint x = 0;
// Search Types
if (newResult.IncludeTypes && (newResult.Tag == null || typeTags.Any (t => t == newResult.Tag))) {
- newResult.filteredTypes = new List<ITypeDefinition> ();
- bool startsWithLastFilter = lastResult.pattern != null && newResult.pattern.StartsWith (lastResult.pattern, StringComparison.Ordinal) && lastResult.filteredTypes != null;
- var allTypes = startsWithLastFilter ? lastResult.filteredTypes : types;
+ newResult.filteredSymbols = new List<DeclaredSymbolInfo> ();
+ bool startsWithLastFilter = lastResult.pattern != null && newResult.pattern.StartsWith (lastResult.pattern, StringComparison.Ordinal) && lastResult.filteredSymbols != null;
+ var allTypes = startsWithLastFilter ? lastResult.filteredSymbols : completeTypeList;
foreach (var type in allTypes) {
- if (unchecked(x++) % 100 == 0 && token.IsCancellationRequested)
+ if (unchecked(x++) % 100 == 0 && token.IsCancellationRequested) {
+ newResult.filteredSymbols = null;
return;
+ }
+ if (type.Kind == DeclaredSymbolInfoKind.Constructor ||
+ type.Kind == DeclaredSymbolInfoKind.Module ||
+ type.Kind == DeclaredSymbolInfoKind.Indexer)
+ continue;
+
if (newResult.Tag != null) {
- if (newResult.Tag == "c" && type.Kind != TypeKind.Class)
+ if (newResult.Tag == "c" && type.Kind != DeclaredSymbolInfoKind.Class)
continue;
- if (newResult.Tag == "s" && type.Kind != TypeKind.Struct)
+ if (newResult.Tag == "s" && type.Kind != DeclaredSymbolInfoKind.Struct)
continue;
- if (newResult.Tag == "i" && type.Kind != TypeKind.Interface)
+ if (newResult.Tag == "i" && type.Kind != DeclaredSymbolInfoKind.Interface)
continue;
- if (newResult.Tag == "e" && type.Kind != TypeKind.Enum)
+ if (newResult.Tag == "e" && type.Kind != DeclaredSymbolInfoKind.Enum)
+ continue;
+ if (newResult.Tag == "d" && type.Kind != DeclaredSymbolInfoKind.Delegate)
+ continue;
+
+ if (newResult.Tag == "m" && type.Kind != DeclaredSymbolInfoKind.Method)
continue;
- if (newResult.Tag == "d" && type.Kind != TypeKind.Delegate)
+ if (newResult.Tag == "p" && type.Kind != DeclaredSymbolInfoKind.Property)
continue;
+ if (newResult.Tag == "f" && type.Kind != DeclaredSymbolInfoKind.Field)
+ continue;
+ if (newResult.Tag == "evt" && type.Kind != DeclaredSymbolInfoKind.Event)
+ continue;
+
}
SearchResult curResult = newResult.CheckType (type);
if (curResult != null) {
- newResult.filteredTypes.Add (type);
+ newResult.filteredSymbols.Add (type);
newResult.results.AddResult (curResult);
}
}
}
-
- // Search members
- if (newResult.IncludeMembers && (newResult.Tag == null || memberTags.Any (t => t == newResult.Tag))) {
- newResult.filteredMembers = new List<Tuple<ITypeDefinition, IUnresolvedMember>> ();
- bool startsWithLastFilter = lastResult.pattern != null && newResult.pattern.StartsWith (lastResult.pattern, StringComparison.Ordinal) && lastResult.filteredMembers != null;
- if (startsWithLastFilter) {
- foreach (var t in lastResult.filteredMembers) {
- if (unchecked(x++) % 100 == 0 && token.IsCancellationRequested)
- return;
- var member = t.Item2;
- if (newResult.Tag != null) {
- if (newResult.Tag == "m" && member.SymbolKind != SymbolKind.Method)
- continue;
- if (newResult.Tag == "p" && member.SymbolKind != SymbolKind.Property)
- continue;
- if (newResult.Tag == "f" && member.SymbolKind != SymbolKind.Field)
- continue;
- if (newResult.Tag == "evt" && member.SymbolKind != SymbolKind.Event)
- continue;
- }
- SearchResult curResult = newResult.CheckMember (t.Item1, member);
- if (curResult != null) {
- newResult.filteredMembers.Add (t);
- newResult.results.AddResult (curResult);
- }
- }
- } else {
- Func<IUnresolvedMember, bool> mPred = member => {
- if (newResult.Tag != null) {
- if (newResult.Tag == "m" && member.SymbolKind != SymbolKind.Method)
- return false;
- if (newResult.Tag == "p" && member.SymbolKind != SymbolKind.Property)
- return false;
- if (newResult.Tag == "f" && member.SymbolKind != SymbolKind.Field)
- return false;
- if (newResult.Tag == "evt" && member.SymbolKind != SymbolKind.Event)
- return false;
- }
- return newResult.IsMatchingMember (member);
- };
-
- getMembersTimer.BeginTiming ();
- try {
- foreach (var type in types) {
- if (type.Kind == TypeKind.Delegate)
- continue;
- foreach (var p in type.Parts) {
- foreach (var member in p.Members.Where (mPred)) {
- if (unchecked(x++) % 100 == 0 && token.IsCancellationRequested)
- return;
- SearchResult curResult = newResult.CheckMember (type, member);
- if (curResult != null) {
- newResult.filteredMembers.Add (Tuple.Create (type, member));
- newResult.results.AddResult (curResult);
- }
- }
- }
- }
- } finally {
- getMembersTimer.EndTiming ();
- }
- }
- }
}
-
+
class WorkerResult
{
public string Tag {
@@ -236,12 +216,12 @@ namespace MonoDevelop.Components.MainToolbar
set;
}
- public List<ProjectFile> filteredFiles;
- public List<ITypeDefinition> filteredTypes;
- public List<Tuple<ITypeDefinition, IUnresolvedMember>> filteredMembers;
+ public List<DeclaredSymbolInfo> filteredSymbols;
+
string pattern2;
char firstChar;
char[] firstChars;
+
public string pattern {
get {
return pattern2;
@@ -249,76 +229,42 @@ namespace MonoDevelop.Components.MainToolbar
set {
pattern2 = value;
if (pattern2.Length == 1) {
- firstChar = pattern2[0];
+ firstChar = pattern2 [0];
firstChars = new [] { char.ToUpper (firstChar), char.ToLower (firstChar) };
} else {
firstChars = null;
}
}
}
+
public bool isGotoFilePattern;
public ResultsDataSource results;
public bool FullSearch;
public bool IncludeFiles, IncludeTypes, IncludeMembers;
- public Ambience ambience;
public StringMatcher matcher;
-
+
public WorkerResult (Widget widget)
{
results = new ResultsDataSource (widget);
}
-
- internal SearchResult CheckFile (ProjectFile file)
- {
- int rank;
- string matchString = System.IO.Path.GetFileName (file.FilePath);
- if (MatchName (matchString, out rank))
- return new FileSearchResult (pattern, matchString, rank, file, true);
-
- if (!FullSearch)
- return null;
- matchString = FileSearchResult.GetRelProjectPath (file);
- if (MatchName (matchString, out rank))
- return new FileSearchResult (pattern, matchString, rank, file, false);
-
- return null;
- }
-
- internal SearchResult CheckType (ITypeDefinition type)
+
+ internal SearchResult CheckType (DeclaredSymbolInfo symbol)
{
int rank;
- if (MatchName (TypeSearchResult.GetPlainText (type, false), out rank)) {
- if (type.DeclaringType != null)
- rank--;
- return new TypeSearchResult (pattern, TypeSearchResult.GetPlainText (type, false), rank, type, false) { Ambience = ambience };
+ if (MatchName (symbol.Name, out rank)) {
+// if (type.ContainerDisplayName != null)
+// rank--;
+ return new DeclaredSymbolInfoResult (pattern, symbol.Name, rank, symbol, false);
}
if (!FullSearch)
return null;
- if (MatchName (TypeSearchResult.GetPlainText (type, true), out rank)) {
- if (type.DeclaringType != null)
- rank--;
- return new TypeSearchResult (pattern, TypeSearchResult.GetPlainText (type, true), rank, type, true) { Ambience = ambience };
+ if (MatchName (symbol.FullyQualifiedContainerName, out rank)) {
+// if (type.ContainingType != null)
+// rank--;
+ return new DeclaredSymbolInfoResult (pattern, symbol.FullyQualifiedContainerName, rank, symbol, true);
}
return null;
}
-
- internal SearchResult CheckMember (ITypeDefinition declaringType, IUnresolvedMember member)
- {
- int rank;
- bool useDeclaringTypeName = member is IUnresolvedMethod && (((IUnresolvedMethod)member).IsConstructor || ((IUnresolvedMethod)member).IsDestructor);
- string memberName = useDeclaringTypeName ? member.DeclaringTypeDefinition.Name : member.Name;
- if (MatchName (memberName, out rank))
- return new MemberSearchResult (pattern, memberName, rank, declaringType, member, false) { Ambience = ambience };
- return null;
- }
-
- internal bool IsMatchingMember (IUnresolvedMember member)
- {
- int rank;
- bool useDeclaringTypeName = member is IUnresolvedMethod && (((IUnresolvedMethod)member).IsConstructor || ((IUnresolvedMethod)member).IsDestructor);
- string memberName = useDeclaringTypeName ? member.DeclaringTypeDefinition.Name : member.Name;
- return MatchName (memberName, out rank);
- }
Dictionary<string, MatchResult> savedMatches = new Dictionary<string, MatchResult> (StringComparer.Ordinal);
@@ -335,7 +281,7 @@ namespace MonoDevelop.Components.MainToolbar
doesMatch = idx >= 0;
if (doesMatch) {
matchRank = int.MaxValue - (name.Length - 1) * 10 - idx;
- if (name[idx] != firstChar)
+ if (name [idx] != firstChar)
matchRank /= 2;
return true;
} else {