| File: FindSymbols\SymbolFinder_Declarations_CustomQueries.cs | Web Access |
| Project: src\roslyn\src\Workspaces\Core\Portable\Microsoft.CodeAnalysis.Workspaces.csproj (Microsoft.CodeAnalysis.Workspaces) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Internal.Log; using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Shared.Extensions; namespace Microsoft.CodeAnalysis.FindSymbols; // Logic related to finding declarations with a completely custom predicate goes here. // Completely custom predicates can not be optimized in any way as there is no way to // tell what the predicate will return true for. // // Also, because we have no control over these predicates, we cannot remote these queries // over to the OOP process. public static partial class SymbolFinder { /// <summary> /// Find the symbols for declarations made in source with a matching name. /// </summary> public static Task<IEnumerable<ISymbol>> FindSourceDeclarationsAsync(Solution solution, Func<string, bool> predicate, CancellationToken cancellationToken = default) => FindSourceDeclarationsAsync(solution, predicate, SymbolFilter.All, cancellationToken); /// <summary> /// Find the symbols for declarations made in source with a matching name. /// </summary> public static async Task<IEnumerable<ISymbol>> FindSourceDeclarationsAsync(Solution solution, Func<string, bool> predicate, SymbolFilter filter, CancellationToken cancellationToken = default) { using var query = SearchQuery.CreateCustom(predicate); var declarations = await FindSourceDeclarationsWithCustomQueryAsync( solution, query, filter, cancellationToken).ConfigureAwait(false); return declarations; } internal static async Task<ImmutableArray<ISymbol>> FindSourceDeclarationsWithCustomQueryAsync( 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 []; } using (Logger.LogBlock(FunctionId.SymbolFinder_Solution_Predicate_FindSourceDeclarationsAsync, cancellationToken)) { using var _ = ArrayBuilder<ISymbol>.GetInstance(out var result); foreach (var projectId in solution.ProjectIds) { var project = solution.GetRequiredProject(projectId); var symbols = await FindSourceDeclarationsWithCustomQueryAsync(project, query, filter, cancellationToken).ConfigureAwait(false); result.AddRange(symbols); } return result.ToImmutableAndClear(); } } /// <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, CancellationToken cancellationToken = default) => FindSourceDeclarationsAsync(project, predicate, SymbolFilter.All, cancellationToken); /// <summary> /// Find the symbols for declarations made in source with a matching name. /// </summary> public static async Task<IEnumerable<ISymbol>> FindSourceDeclarationsAsync(Project project, Func<string, bool> predicate, SymbolFilter filter, CancellationToken cancellationToken = default) { using var query = SearchQuery.CreateCustom(predicate); var declarations = await FindSourceDeclarationsWithCustomQueryAsync( project, query, filter, cancellationToken).ConfigureAwait(false); return declarations; } internal static async Task<ImmutableArray<ISymbol>> FindSourceDeclarationsWithCustomQueryAsync( 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 []; } using (Logger.LogBlock(FunctionId.SymbolFinder_Project_Predicate_FindSourceDeclarationsAsync, cancellationToken)) { if (await project.ContainsSymbolsWithNameAsync(query.GetPredicate(), filter, cancellationToken).ConfigureAwait(false)) { var compilation = await project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false); var unfiltered = compilation.GetSymbolsWithName(query.GetPredicate(), filter, cancellationToken) .ToImmutableArray(); return DeclarationFinder.FilterByCriteria(unfiltered, filter); } } return []; } }