/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Workspaces/Remote/ServiceHub/Services/SymbolFinder/RemoteSymbolFinderService.cs
248 строк
12 KB
Cyrus Najmabadi
Remove unnecessary imports
10 мар 2025, 17:04
10 мар 2025, 17:04
58c992f
Код
Авторство
О чём код?
// 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.Immutable; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.FindSymbols; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.Utilities; using Microsoft.CodeAnalysis.Text; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.Remote; internal sealed class RemoteSymbolFinderService : BrokeredServiceBase, IRemoteSymbolFinderService { internal sealed class Factory : FactoryBase<IRemoteSymbolFinderService, IRemoteSymbolFinderService.ICallback> { protected override IRemoteSymbolFinderService CreateService(in ServiceConstructionArguments arguments, RemoteCallback<IRemoteSymbolFinderService.ICallback> callback) => new RemoteSymbolFinderService(arguments, callback); } private readonly RemoteCallback<IRemoteSymbolFinderService.ICallback> _callback; public RemoteSymbolFinderService(in ServiceConstructionArguments arguments, RemoteCallback<IRemoteSymbolFinderService.ICallback> callback) : base(arguments) { _callback = callback; } public ValueTask FindReferencesAsync( Checksum solutionChecksum, RemoteServiceCallbackId callbackId, SerializableSymbolAndProjectId symbolAndProjectIdArg, ImmutableArray<DocumentId> documentArgs, FindReferencesSearchOptions options, CancellationToken cancellationToken) { return RunServiceAsync(solutionChecksum, async solution => { var symbol = await symbolAndProjectIdArg.TryRehydrateAsync( solution, cancellationToken).ConfigureAwait(false); var progressCallback = new FindReferencesProgressCallback(solution, _callback, callbackId); if (symbol == null) { await progressCallback.OnStartedAsync(cancellationToken).ConfigureAwait(false); await progressCallback.OnCompletedAsync(cancellationToken).ConfigureAwait(false); return; } // NOTE: In projection scenarios, we might get a set of documents to search // that are not all the same language and might not exist in the OOP process // (like the JS parts of a .cshtml file). Filter them out here. This will // need to be revisited if we someday support FAR between these languages. var documents = documentArgs.IsDefault ? null : documentArgs.Select(solution.GetDocument).WhereNotNull().ToImmutableHashSet(); await SymbolFinder.FindReferencesInCurrentProcessAsync( symbol, solution, progressCallback, documents, options, cancellationToken).ConfigureAwait(false); }, cancellationToken); } public ValueTask FindLiteralReferencesAsync(Checksum solutionChecksum, RemoteServiceCallbackId callbackId, object value, TypeCode typeCode, CancellationToken cancellationToken) { return RunServiceAsync(solutionChecksum, async solution => { var convertedType = System.Convert.ChangeType(value, typeCode); var progressCallback = new FindLiteralReferencesProgressCallback(_callback, callbackId); await SymbolFinder.FindLiteralReferencesInCurrentProcessAsync( convertedType, solution, progressCallback, cancellationToken).ConfigureAwait(false); }, cancellationToken); } private static ImmutableArray<SerializableSymbolAndProjectId> Convert(ImmutableArray<ISymbol> items, Solution solution, CancellationToken cancellationToken) { var result = new FixedSizeArrayBuilder<SerializableSymbolAndProjectId>(items.Length); foreach (var item in items) result.Add(SerializableSymbolAndProjectId.Dehydrate(solution, item, cancellationToken)); return result.MoveToImmutable(); } public ValueTask<ImmutableArray<SerializableSymbolAndProjectId>> FindAllDeclarationsWithNormalQueryAsync( Checksum solutionChecksum, ProjectId projectId, string name, SearchKind searchKind, SymbolFilter criteria, CancellationToken cancellationToken) { return RunServiceAsync(solutionChecksum, async solution => { var project = solution.GetRequiredProject(projectId); using var query = SearchQuery.Create(name, searchKind); var result = await DeclarationFinder.FindAllDeclarationsWithNormalQueryInCurrentProcessAsync( project, query, criteria, cancellationToken).ConfigureAwait(false); return Convert(result, solution, cancellationToken); }, cancellationToken); } public ValueTask<ImmutableArray<SerializableSymbolAndProjectId>> FindSolutionSourceDeclarationsWithNormalQueryAsync( Checksum solutionChecksum, string name, bool ignoreCase, SymbolFilter criteria, CancellationToken cancellationToken) { return RunServiceAsync(solutionChecksum, async solution => { var result = await DeclarationFinder.FindSourceDeclarationsWithNormalQueryInCurrentProcessAsync( solution, name, ignoreCase, criteria, cancellationToken).ConfigureAwait(false); return Convert(result, solution, cancellationToken); }, cancellationToken); } public ValueTask<ImmutableArray<SerializableSymbolAndProjectId>> FindProjectSourceDeclarationsWithNormalQueryAsync( Checksum solutionChecksum, ProjectId projectId, string name, bool ignoreCase, SymbolFilter criteria, CancellationToken cancellationToken) { return RunServiceAsync(solutionChecksum, async solution => { var project = solution.GetRequiredProject(projectId); var result = await DeclarationFinder.FindSourceDeclarationsWithNormalQueryInCurrentProcessAsync( project, name, ignoreCase, criteria, cancellationToken).ConfigureAwait(false); return Convert(result, solution, cancellationToken); }, cancellationToken); } public ValueTask<ImmutableArray<SerializableSymbolAndProjectId>> FindSolutionSourceDeclarationsWithPatternAsync( Checksum solutionChecksum, string pattern, SymbolFilter criteria, CancellationToken cancellationToken) { return RunServiceAsync(solutionChecksum, async solution => { var result = await DeclarationFinder.FindSourceDeclarationsWithPatternInCurrentProcessAsync( solution, pattern, criteria, cancellationToken).ConfigureAwait(false); return Convert(result, solution, cancellationToken); }, cancellationToken); } public ValueTask<ImmutableArray<SerializableSymbolAndProjectId>> FindProjectSourceDeclarationsWithPatternAsync( Checksum solutionChecksum, ProjectId projectId, string pattern, SymbolFilter criteria, CancellationToken cancellationToken) { return RunServiceAsync(solutionChecksum, async solution => { var project = solution.GetRequiredProject(projectId); var result = await DeclarationFinder.FindSourceDeclarationsWithPatternInCurrentProcessAsync( project, pattern, criteria, cancellationToken).ConfigureAwait(false); return Convert(result, solution, cancellationToken); }, cancellationToken); } private sealed class FindLiteralReferencesProgressCallback : IStreamingFindLiteralReferencesProgress, IStreamingProgressTracker { private readonly RemoteCallback<IRemoteSymbolFinderService.ICallback> _callback; private readonly RemoteServiceCallbackId _callbackId; public IStreamingProgressTracker ProgressTracker { get; } public FindLiteralReferencesProgressCallback(RemoteCallback<IRemoteSymbolFinderService.ICallback> callback, RemoteServiceCallbackId callbackId) { _callback = callback; _callbackId = callbackId; ProgressTracker = this; } public ValueTask OnReferenceFoundAsync(Document document, TextSpan span, CancellationToken cancellationToken) => _callback.InvokeAsync((callback, cancellationToken) => callback.OnLiteralReferenceFoundAsync(_callbackId, document.Id, span, cancellationToken), cancellationToken); public ValueTask AddItemsAsync(int count, CancellationToken cancellationToken) => _callback.InvokeAsync((callback, cancellationToken) => callback.AddLiteralItemsAsync(_callbackId, count, cancellationToken), cancellationToken); public ValueTask ItemsCompletedAsync(int count, CancellationToken cancellationToken) => _callback.InvokeAsync((callback, cancellationToken) => callback.LiteralItemsCompletedAsync(_callbackId, count, cancellationToken), cancellationToken); } private sealed class FindReferencesProgressCallback : IStreamingFindReferencesProgress, IStreamingProgressTracker { private readonly Solution _solution; private readonly RemoteCallback<IRemoteSymbolFinderService.ICallback> _callback; private readonly RemoteServiceCallbackId _callbackId; public IStreamingProgressTracker ProgressTracker { get; } public FindReferencesProgressCallback(Solution solution, RemoteCallback<IRemoteSymbolFinderService.ICallback> callback, RemoteServiceCallbackId callbackId) { _solution = solution; _callback = callback; _callbackId = callbackId; ProgressTracker = this; } public ValueTask OnStartedAsync(CancellationToken cancellationToken) => _callback.InvokeAsync((callback, cancellationToken) => callback.OnStartedAsync(_callbackId, cancellationToken), cancellationToken); public ValueTask OnCompletedAsync(CancellationToken cancellationToken) => _callback.InvokeAsync((callback, cancellationToken) => callback.OnCompletedAsync(_callbackId, cancellationToken), cancellationToken); public ValueTask OnDefinitionFoundAsync(SymbolGroup group, CancellationToken cancellationToken) { var dehydratedGroup = SerializableSymbolGroup.Dehydrate(_solution, group, cancellationToken); return _callback.InvokeAsync( (callback, cancellationToken) => callback.OnDefinitionFoundAsync(_callbackId, dehydratedGroup, cancellationToken), cancellationToken); } public async ValueTask OnReferencesFoundAsync( ImmutableArray<(SymbolGroup group, ISymbol symbol, ReferenceLocation location)> references, CancellationToken cancellationToken) { var dehydrated = references.SelectAsArray( static (reference, tuple) => ( SerializableSymbolGroup.Dehydrate(tuple.solution, reference.group, tuple.cancellationToken), SerializableSymbolAndProjectId.Dehydrate(tuple.solution, reference.symbol, tuple.cancellationToken), SerializableReferenceLocation.Dehydrate(reference.location, tuple.cancellationToken)), (solution: _solution, cancellationToken)); await _callback.InvokeAsync( (callback, cancellationToken) => callback.OnReferencesFoundAsync( _callbackId, dehydrated, cancellationToken), cancellationToken).ConfigureAwait(false); } public ValueTask AddItemsAsync(int count, CancellationToken cancellationToken) => _callback.InvokeAsync((callback, cancellationToken) => callback.AddReferenceItemsAsync(_callbackId, count, cancellationToken), cancellationToken); public ValueTask ItemsCompletedAsync(int count, CancellationToken cancellationToken) => _callback.InvokeAsync((callback, cancellationToken) => callback.ReferenceItemsCompletedAsync(_callbackId, count, cancellationToken), cancellationToken); } }