public async Task<IEnumerable<ISymbol>> FindAsync( SearchQuery query, AsyncLazy<IAssemblySymbol> lazyAssembly, SymbolFilter filter, CancellationToken cancellationToken) { return SymbolFinder.FilterByCriteria( await FindAsyncWorker(query, lazyAssembly, cancellationToken).ConfigureAwait(false), filter); }
public Task<IEnumerable<ISymbol>> FindAsync(SearchQuery query, AsyncLazy<IAssemblySymbol> lazyAssembly, CancellationToken cancellationToken) { // If the query has a specific string provided, then call into the SymbolTreeInfo // helpers optimized for lookup based on an exact name. switch (query.Kind) { case SearchKind.Exact: return this.FindAsync(lazyAssembly, query.Name, ignoreCase: false, cancellationToken: cancellationToken); case SearchKind.ExactIgnoreCase: return this.FindAsync(lazyAssembly, query.Name, ignoreCase: true, cancellationToken: cancellationToken); case SearchKind.Fuzzy: return this.FuzzyFindAsync(lazyAssembly, query.Name, cancellationToken); case SearchKind.Custom: // Otherwise, we'll have to do a slow linear search over all possible symbols. return this.FindAsync(lazyAssembly, query.GetPredicate(), cancellationToken); } throw new InvalidOperationException(); }
public Task<IEnumerable<ISymbol>> FindAsync(SearchQuery query, IAssemblySymbol assembly, CancellationToken cancellationToken) { return FindAsync(query, new AsyncLazy<IAssemblySymbol>(assembly), cancellationToken); }
internal static async Task<IEnumerable<ISymbol>> FindSourceDeclarationsAsync(Project project, SearchQuery query, SymbolFilter filter, CancellationToken cancellationToken) { if (project == null) { throw new ArgumentNullException(nameof(project)); } if (query.Name != null && string.IsNullOrWhiteSpace(query.Name)) { return SpecializedCollections.EmptyEnumerable<ISymbol>(); } using (Logger.LogBlock(FunctionId.SymbolFinder_Project_Predicate_FindSourceDeclarationsAsync, cancellationToken)) { var result = new List<ISymbol>(); if (!await project.ContainsSymbolsWithNameAsync(query.GetPredicate(), filter, cancellationToken).ConfigureAwait(false)) { return result; } var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); result.AddRange(FilterByCriteria(compilation.GetSymbolsWithName(query.GetPredicate(), filter, cancellationToken), filter)); return result; } }
public async Task<IEnumerable<ISymbol>> FindAsync( SearchQuery query, AsyncLazy<IAssemblySymbol> lazyAssembly, SymbolFilter filter, CancellationToken cancellationToken) { // All entrypoints to this function are Find functions that are only searching // for specific strings (i.e. they never do a custom search). Debug.Assert(query.Kind != SearchKind.Custom); return SymbolFinder.FilterByCriteria( await FindAsyncWorker(query, lazyAssembly, cancellationToken).ConfigureAwait(false), filter); }
private static async Task AddDeclarationsAsync( Solution solution, IAssemblySymbol assembly, string filePath, SearchQuery query, SymbolFilter filter, List<ISymbol> list, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.SymbolFinder_Assembly_AddDeclarationsAsync, cancellationToken)) { var info = await SymbolTreeInfo.GetInfoForAssemblyAsync(solution, assembly, filePath, cancellationToken).ConfigureAwait(false); list.AddRange(FilterByCriteria(Find(query, info, assembly, cancellationToken), filter)); } }
private static async Task<IEnumerable<ISymbol>> FindSourceDeclarationsAsyncImpl( Project project, SearchQuery query, SymbolFilter filter, CancellationToken cancellationToken) { var list = new List<ISymbol>(); await AddDeclarationsAsync(project, query, filter, list, cancellationToken).ConfigureAwait(false); return list; }
private static async Task<IEnumerable<ISymbol>> FindDeclarationsAsyncImpl( Project project, SearchQuery query, SymbolFilter criteria, bool includeDirectReferences, CancellationToken cancellationToken) { var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); var list = new List<ISymbol>(); // get declarations from the compilation's assembly await AddDeclarationsAsync(project, query, criteria, list, cancellationToken).ConfigureAwait(false); // get declarations from directly referenced projects and metadata if (includeDirectReferences) { foreach (var assembly in compilation.GetReferencedAssemblySymbols()) { var assemblyProject = project.Solution.GetProject(assembly, cancellationToken); if (assemblyProject != null) { await AddDeclarationsAsync(assemblyProject, query, criteria, list, compilation, assembly, cancellationToken).ConfigureAwait(false); } else { await AddDeclarationsAsync( project.Solution, assembly, GetMetadataReferenceFilePath(compilation.GetMetadataReference(assembly)), query, criteria, list, cancellationToken).ConfigureAwait(false); } } } return TranslateNamespaces(list, compilation); }
private static async Task AddDeclarationsAsync( Project project, SearchQuery query, SymbolFilter filter, List<ISymbol> list, Compilation startingCompilation, IAssemblySymbol startingAssembly, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.SymbolFinder_Project_AddDeclarationsAsync, cancellationToken)) using (var set = SharedPools.Default<HashSet<ISymbol>>().GetPooledObject()) { if (!await project.ContainsSymbolsWithNameAsync(query.GetPredicate(), filter, cancellationToken).ConfigureAwait(false)) { return; } var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); if (startingCompilation != null && startingAssembly != null && compilation.Assembly != startingAssembly) { // Return symbols from skeleton assembly in this case so that symbols have the same language as startingCompilation. list.AddRange( FilterByCriteria(compilation.GetSymbolsWithName(query.GetPredicate(), filter, cancellationToken), filter) .Select(s => s.GetSymbolKey().Resolve(startingCompilation, cancellationToken: cancellationToken).Symbol).WhereNotNull()); } else { list.AddRange(FilterByCriteria(compilation.GetSymbolsWithName(query.GetPredicate(), filter, cancellationToken), filter)); } } }
private static async Task<ImmutableArray<ISymbol>> FindDeclarationsAsyncImpl( Project project, SearchQuery query, SymbolFilter criteria, CancellationToken cancellationToken) { // All entrypoints to this function are Find functions that are only searching // for specific strings (i.e. they never do a custom search). Debug.Assert(query.Kind != SearchKind.Custom); var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); var list = ArrayBuilder<ISymbol>.GetInstance(); // get declarations from the compilation's assembly await AddDeclarationsAsync(project, query, criteria, list, cancellationToken).ConfigureAwait(false); // get declarations from directly referenced projects and metadata foreach (var assembly in compilation.GetReferencedAssemblySymbols()) { var assemblyProject = project.Solution.GetProject(assembly, cancellationToken); if (assemblyProject != null) { await AddDeclarationsAsync(assemblyProject, query, criteria, list, compilation, assembly, cancellationToken).ConfigureAwait(false); } else { await AddDeclarationsAsync( project.Solution, assembly, compilation.GetMetadataReference(assembly) as PortableExecutableReference, query, criteria, list, cancellationToken).ConfigureAwait(false); } } return TranslateNamespaces(list.ToImmutableAndFree(), compilation); }
private static Task AddDeclarationsAsync( Project project, SearchQuery query, SymbolFilter filter, ArrayBuilder<ISymbol> list, CancellationToken cancellationToken) { return AddDeclarationsAsync( project, query, filter, list, startingCompilation: null, startingAssembly: null, cancellationToken: cancellationToken); }
private static async Task AddDeclarationsAsync( Solution solution, IAssemblySymbol assembly, PortableExecutableReference referenceOpt, SearchQuery query, SymbolFilter filter, List<ISymbol> list, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.SymbolFinder_Assembly_AddDeclarationsAsync, cancellationToken)) { if (referenceOpt != null) { var info = await SymbolTreeInfo.TryGetInfoForAssemblyAsync(solution, assembly, referenceOpt, cancellationToken).ConfigureAwait(false); if (info != null) { list.AddRange(FilterByCriteria(Find(query, info, assembly, cancellationToken), filter)); } } } }
internal static Task<ImmutableArray<ISymbol>> FindDeclarationsAsync( Project project, SearchQuery query, SymbolFilter filter, CancellationToken cancellationToken) { // All entrypoints to this function are Find functions that are only searching // for specific strings (i.e. they never do a custom search). Debug.Assert(query.Kind != SearchKind.Custom); if (project == null) { throw new ArgumentNullException(nameof(project)); } if (query.Name != null && string.IsNullOrWhiteSpace(query.Name)) { return SpecializedTasks.EmptyImmutableArray<ISymbol>(); } using (Logger.LogBlock(FunctionId.SymbolFinder_FindDeclarationsAsync, cancellationToken)) { return FindDeclarationsAsyncImpl(project, query, filter, cancellationToken); } }
private static async Task AddDeclarationsAsync( Solution solution, IAssemblySymbol assembly, string filePath, SearchQuery query, SymbolFilter filter, List<ISymbol> list, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.SymbolFinder_Assembly_AddDeclarationsAsync, cancellationToken)) { var info = await SymbolTreeInfo.GetInfoForAssemblyAsync(solution, assembly, filePath, cancellationToken).ConfigureAwait(false); // If the query has a specific string provided, then call into the SymbolTreeInfo // helpers optimized for lookup based on an exact name. if (query.Name != null) { if (info.HasSymbols(query.Name, query.IgnoreCase)) { list.AddRange(FilterByCriteria(info.Find(assembly, query.Name, query.IgnoreCase, cancellationToken), filter)); } } else { // Otherwise, we'll have to do a slow linear search over all possible symbols. list.AddRange(FilterByCriteria(info.Find(assembly, query.Predicate, cancellationToken), filter)); } } }
private static async Task AddCompilationDeclarationsWithNormalQueryAsync( Project project, SearchQuery query, SymbolFilter filter, ArrayBuilder <ISymbol> list, Compilation startingCompilation, IAssemblySymbol startingAssembly, CancellationToken cancellationToken ) { Contract.ThrowIfTrue( query.Kind == SearchKind.Custom, "Custom queries are not supported in this API" ); using ( Logger.LogBlock( FunctionId.SymbolFinder_Project_AddDeclarationsAsync, cancellationToken ) ) { var syntaxFacts = project.LanguageServices.GetService <ISyntaxFactsService>(); // If this is an exact query, we can speed things up by just calling into the // compilation entrypoints that take a string directly. // // the search is 'exact' if it's either an exact-case-sensitive search, // or it's an exact-case-insensitive search and we're in a case-insensitive // language. var isExactNameSearch = query.Kind == SearchKind.Exact || (query.Kind == SearchKind.ExactIgnoreCase && !syntaxFacts.IsCaseSensitive); // Note: we first call through the project. This has an optimization where it will // use the DeclarationOnlyCompilation if we have one, avoiding needing to build the // full compilation if we don't have that. var containsSymbol = isExactNameSearch ? await project .ContainsSymbolsWithNameAsync(query.Name, filter, cancellationToken) .ConfigureAwait(false) : await project .ContainsSymbolsWithNameAsync( query.GetPredicate(), filter, cancellationToken ) .ConfigureAwait(false); if (!containsSymbol) { return; } var compilation = await project .GetCompilationAsync(cancellationToken) .ConfigureAwait(false); var symbols = isExactNameSearch ? compilation.GetSymbolsWithName(query.Name, filter, cancellationToken) : compilation.GetSymbolsWithName( query.GetPredicate(), filter, cancellationToken ); var symbolsWithName = symbols.ToImmutableArray(); if ( startingCompilation != null && startingAssembly != null && !Equals(compilation.Assembly, startingAssembly) ) { // Return symbols from skeleton assembly in this case so that symbols have // the same language as startingCompilation. symbolsWithName = symbolsWithName .Select( s => s.GetSymbolKey(cancellationToken) .Resolve( startingCompilation, cancellationToken: cancellationToken ).Symbol ) .WhereNotNull() .ToImmutableArray(); } list.AddRange(FilterByCriteria(symbolsWithName, filter)); } }
private static async Task AddDeclarationsAsync( Solution solution, IAssemblySymbol assembly, PortableExecutableReference referenceOpt, SearchQuery query, SymbolFilter filter, List<ISymbol> list, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.SymbolFinder_Assembly_AddDeclarationsAsync, cancellationToken)) { if (referenceOpt != null) { var info = await SymbolTreeInfo.GetInfoForMetadataReferenceAsync( solution, referenceOpt, loadOnly: false, cancellationToken: cancellationToken).ConfigureAwait(false); if (info != null) { var symbols = await info.FindAsync(query, assembly, filter, cancellationToken).ConfigureAwait(false); list.AddRange(symbols); } } } }
internal static async Task <IEnumerable <ISymbol> > FindSourceDeclarationsAsync(Project project, SearchQuery query, SymbolFilter filter, CancellationToken cancellationToken) { if (project == null) { throw new ArgumentNullException(nameof(project)); } if (query.Name != null && string.IsNullOrWhiteSpace(query.Name)) { return(SpecializedCollections.EmptyEnumerable <ISymbol>()); } using (Logger.LogBlock(FunctionId.SymbolFinder_Project_Predicate_FindSourceDeclarationsAsync, cancellationToken)) { var result = new List <ISymbol>(); if (!await project.ContainsSymbolsWithNameAsync(query.GetPredicate(), filter, cancellationToken).ConfigureAwait(false)) { return(result); } var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); result.AddRange(FilterByCriteria(compilation.GetSymbolsWithName(query.GetPredicate(), filter, cancellationToken), filter)); return(result); } }
private static async Task AddDeclarationsAsync( Project project, SearchQuery query, SymbolFilter filter, ArrayBuilder<ISymbol> list, Compilation startingCompilation, IAssemblySymbol startingAssembly, CancellationToken cancellationToken) { using (Logger.LogBlock(FunctionId.SymbolFinder_Project_AddDeclarationsAsync, cancellationToken)) { if (!await project.ContainsSymbolsWithNameAsync(query.GetPredicate(), filter, cancellationToken).ConfigureAwait(false)) { return; } var unfilteredSymbols = await GetUnfilteredSymbolsAsync( project, query, filter, startingCompilation, startingAssembly, cancellationToken).ConfigureAwait(false); list.AddRange(FilterByCriteria(unfilteredSymbols, filter)); } }
internal static Task<IEnumerable<ISymbol>> FindDeclarationsAsync( Project project, SearchQuery query, SymbolFilter filter, bool includeDirectReferences, CancellationToken cancellationToken) { if (project == null) { throw new ArgumentNullException(nameof(project)); } if (query.Name != null && string.IsNullOrWhiteSpace(query.Name)) { return SpecializedTasks.EmptyEnumerable<ISymbol>(); } using (Logger.LogBlock(FunctionId.SymbolFinder_FindDeclarationsAsync, cancellationToken)) { return FindDeclarationsAsyncImpl(project, query, filter, includeDirectReferences, cancellationToken); } }
private static async Task<ImmutableArray<ISymbol>> GetUnfilteredSymbolsAsync( Project project, SearchQuery query, SymbolFilter filter, Compilation startingCompilation, IAssemblySymbol startingAssembly, CancellationToken cancellationToken) { var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); if (startingCompilation != null && startingAssembly != null && compilation.Assembly != startingAssembly) { // Return symbols from skeleton assembly in this case so that symbols have the same language as startingCompilation. return compilation.GetSymbolsWithName(query.GetPredicate(), filter, cancellationToken) .Select(s => s.GetSymbolKey().Resolve(startingCompilation, cancellationToken: cancellationToken).Symbol) .WhereNotNull() .ToImmutableArray(); } else { return compilation.GetSymbolsWithName(query.GetPredicate(), filter, cancellationToken) .ToImmutableArray(); } }
private static async Task AddDeclarationsAsync( Project project, SearchQuery query, SymbolFilter filter, List<ISymbol> list, CancellationToken cancellationToken) { await AddDeclarationsAsync( project, query, filter, list, startingCompilation: null, startingAssembly: null, cancellationToken: cancellationToken).ConfigureAwait(false); }
private static async Task AddDeclarationsAsync( Solution solution, IAssemblySymbol assembly, PortableExecutableReference referenceOpt, SearchQuery query, SymbolFilter filter, ArrayBuilder<ISymbol> list, CancellationToken cancellationToken) { // All entrypoints to this function are Find functions that are only searching // for specific strings (i.e. they never do a custom search). Debug.Assert(query.Kind != SearchKind.Custom); using (Logger.LogBlock(FunctionId.SymbolFinder_Assembly_AddDeclarationsAsync, cancellationToken)) { if (referenceOpt != null) { var info = await SymbolTreeInfo.TryGetInfoForMetadataReferenceAsync( solution, referenceOpt, loadOnly: false, cancellationToken: cancellationToken).ConfigureAwait(false); if (info != null) { var symbols = await info.FindAsync(query, assembly, filter, cancellationToken).ConfigureAwait(false); list.AddRange(symbols); } } } }
internal static async Task<IEnumerable<ISymbol>> FindDeclarationsAsync( Solution solution, IAssemblySymbol assembly, string filePath, SearchQuery query, SymbolFilter filter, CancellationToken cancellationToken) { if (query.Name != null && string.IsNullOrWhiteSpace(query.Name)) { return SpecializedCollections.EmptyEnumerable<ISymbol>(); } var result = new List<ISymbol>(); await AddDeclarationsAsync(solution, assembly, filePath, query, filter, result, cancellationToken).ConfigureAwait(false); return result; }
private static async Task<ImmutableArray<ISymbol>> FindSourceDeclarationsAsyncImpl( Solution solution, SearchQuery query, SymbolFilter filter, CancellationToken cancellationToken) { if (query.Name != null && string.IsNullOrWhiteSpace(query.Name)) { return ImmutableArray<ISymbol>.Empty; } var result = ArrayBuilder<ISymbol>.GetInstance(); foreach (var projectId in solution.ProjectIds) { var project = solution.GetProject(projectId); var symbols = await FindSourceDeclarationsAsyncImpl(project, query, filter, cancellationToken).ConfigureAwait(false); result.AddRange(symbols); } return result.ToImmutableAndFree(); }
private static async Task<IEnumerable<ISymbol>> FindSourceDeclarationsAsyncImpl( Solution solution, SearchQuery query, SymbolFilter filter, CancellationToken cancellationToken) { if (query.Name != null && string.IsNullOrWhiteSpace(query.Name)) { return SpecializedCollections.EmptyEnumerable<ISymbol>(); } var result = new List<ISymbol>(); foreach (var projectId in solution.ProjectIds) { var project = solution.GetProject(projectId); var symbols = await FindSourceDeclarationsAsyncImpl(project, query, filter, cancellationToken).ConfigureAwait(false); result.AddRange(symbols); } return result; }
private static async Task<ImmutableArray<ISymbol>> FindSourceDeclarationsAsyncImpl( Project project, SearchQuery query, SymbolFilter filter, CancellationToken cancellationToken) { var list = ArrayBuilder<ISymbol>.GetInstance(); await AddDeclarationsAsync(project, query, filter, list, cancellationToken).ConfigureAwait(false); return list.ToImmutableAndFree(); }
internal static async Task<IEnumerable<ISymbol>> FindSourceDeclarationsAsync(Solution solution, SearchQuery query, SymbolFilter filter, CancellationToken cancellationToken) { if (solution == null) { throw new ArgumentNullException(nameof(solution)); } if (query.Name != null && string.IsNullOrWhiteSpace(query.Name)) { return SpecializedCollections.EmptyEnumerable<ISymbol>(); } using (Logger.LogBlock(FunctionId.SymbolFinder_Solution_Predicate_FindSourceDeclarationsAsync, cancellationToken)) { var result = new List<ISymbol>(); foreach (var projectId in solution.ProjectIds) { var project = solution.GetProject(projectId); var symbols = await FindSourceDeclarationsAsync(project, query, filter, cancellationToken).ConfigureAwait(false); result.AddRange(symbols); } return result; } }
internal static async Task<ImmutableArray<ISymbol>> FindSourceDeclarationsAsync( Project project, SearchQuery query, SymbolFilter filter, CancellationToken cancellationToken) { if (project == null) { throw new ArgumentNullException(nameof(project)); } if (query.Name != null && string.IsNullOrWhiteSpace(query.Name)) { return ImmutableArray<ISymbol>.Empty; } using (Logger.LogBlock(FunctionId.SymbolFinder_Project_Predicate_FindSourceDeclarationsAsync, cancellationToken)) { if (!await project.ContainsSymbolsWithNameAsync(query.GetPredicate(), filter, cancellationToken).ConfigureAwait(false)) { return ImmutableArray<ISymbol>.Empty; } var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); var unfiltered = compilation.GetSymbolsWithName(query.GetPredicate(), filter, cancellationToken).ToImmutableArray(); return FilterByCriteria(unfiltered, filter); } }
public Task<IEnumerable<ISymbol>> FindAsync( SearchQuery query, IAssemblySymbol assembly, SymbolFilter filter, CancellationToken cancellationToken) { // All entrypoints to this function are Find functions that are only searching // for specific strings (i.e. they never do a custom search). Debug.Assert(query.Kind != SearchKind.Custom); return this.FindAsync(query, new AsyncLazy<IAssemblySymbol>(assembly), filter, cancellationToken); }
internal static async Task <IEnumerable <ISymbol> > FindSourceDeclarationsAsync(Solution solution, SearchQuery query, SymbolFilter filter, CancellationToken cancellationToken) { if (solution == null) { throw new ArgumentNullException(nameof(solution)); } if (query.Name != null && string.IsNullOrWhiteSpace(query.Name)) { return(SpecializedCollections.EmptyEnumerable <ISymbol>()); } using (Logger.LogBlock(FunctionId.SymbolFinder_Solution_Predicate_FindSourceDeclarationsAsync, cancellationToken)) { var result = new List <ISymbol>(); foreach (var projectId in solution.ProjectIds) { var project = solution.GetProject(projectId); var symbols = await FindSourceDeclarationsAsync(project, query, filter, cancellationToken).ConfigureAwait(false); result.AddRange(symbols); } return(result); } }
private Task<IEnumerable<ISymbol>> FindAsyncWorker( SearchQuery query, AsyncLazy<IAssemblySymbol> lazyAssembly, CancellationToken cancellationToken) { // All entrypoints to this function are Find functions that are only searching // for specific strings (i.e. they never do a custom search). Debug.Assert(query.Kind != SearchKind.Custom); // If the query has a specific string provided, then call into the SymbolTreeInfo // helpers optimized for lookup based on an exact name. switch (query.Kind) { case SearchKind.Exact: return this.FindAsync(lazyAssembly, query.Name, ignoreCase: false, cancellationToken: cancellationToken); case SearchKind.ExactIgnoreCase: return this.FindAsync(lazyAssembly, query.Name, ignoreCase: true, cancellationToken: cancellationToken); case SearchKind.Fuzzy: return this.FuzzyFindAsync(lazyAssembly, query.Name, cancellationToken); } throw new InvalidOperationException(); }
internal static Task<IEnumerable<ISymbol>> FindDeclarationsAsync( Project project, SearchQuery query, bool includeDirectReferences, CancellationToken cancellationToken) { return FindDeclarationsAsync(project, query, SymbolFilter.All, includeDirectReferences, cancellationToken); }
public Task <IEnumerable <ISymbol> > FindAsync(SearchQuery query, IAssemblySymbol assembly, CancellationToken cancellationToken) { return(FindAsync(query, new AsyncLazy <IAssemblySymbol>(assembly), cancellationToken)); }
/// <summary> /// Find the symbols for declarations made in source with a matching name. /// </summary> public static Task <IEnumerable <ISymbol> > FindSourceDeclarationsAsync(Project project, Func <string, bool> predicate, SymbolFilter filter, CancellationToken cancellationToken = default(CancellationToken)) { return(FindSourceDeclarationsAsync(project, SearchQuery.CreateCustom(predicate), filter, cancellationToken)); }