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)); } } }
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)); } }
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 AddCompilationDeclarationsWithNormalQueryAsync( Project project, SearchQuery query, SymbolFilter filter, ArrayBuilder <ISymbol> list, Compilation startingCompilation, IAssemblySymbol startingAssembly, CancellationToken cancellationToken) { Debug.Assert(query.Kind != SearchKind.Custom); using (Logger.LogBlock(FunctionId.SymbolFinder_Project_AddDeclarationsAsync, cancellationToken)) { if (!await project.ContainsSymbolsWithNameAsync(query.GetPredicate(), filter, cancellationToken).ConfigureAwait(false)) { return; } var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); var symbolsWithName = compilation.GetSymbolsWithName(query.GetPredicate(), filter, cancellationToken) .ToImmutableArray(); 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. symbolsWithName = symbolsWithName.Select(s => s.GetSymbolKey().Resolve(startingCompilation, cancellationToken: cancellationToken).Symbol) .WhereNotNull() .ToImmutableArray(); } list.AddRange(FilterByCriteria(symbolsWithName, filter)); } }
private static async Task AddCompilationDeclarationsWithNormalQueryAsync( Project project, SearchQuery query, SymbolFilter filter, ArrayBuilder <SymbolAndProjectId> 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.SelectAsArray(s => new SymbolAndProjectId(s, project.Id)); 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.WithSymbol(s.Symbol.GetSymbolKey().Resolve(startingCompilation, cancellationToken: cancellationToken).Symbol)) .Where(s => s.Symbol != null) .ToImmutableArray(); } list.AddRange(FilterByCriteria(symbolsWithName, filter)); } }
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()); } }
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(); }
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)); } }
private Task <IEnumerable <ISymbol> > FindAsyncWorker(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(); }
private static async Task AddCompilationDeclarationsWithNormalQueryAsync( Project project, SearchQuery query, SymbolFilter filter, ArrayBuilder <ISymbol> list, Compilation startingCompilation, IAssemblySymbol startingAssembly, CancellationToken cancellationToken) { if (!project.SupportsCompilation) { return; } 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); // Do a quick syntactic check first using our cheaply built indices. That will help us avoid creating // a compilation here if it's not necessary. In the case of an exact name search we can call a special // overload that quickly uses the direct bloom-filter identifier maps in the index. If it's nto an // exact name search, then we will run the query's predicate over every DeclaredSymbolInfo stored in // the doc. var containsSymbol = isExactNameSearch ? await project.ContainsSymbolsWithNameAsync(query.Name, 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)); } }
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, 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)); } } }
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); } }
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, 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)); } }