diff --git a/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindBaseSymbolsCommandHandler.cs b/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindBaseSymbolsCommandHandler.cs index 66bcf8b11d006..b8c7e78a52f70 100644 --- a/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindBaseSymbolsCommandHandler.cs +++ b/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindBaseSymbolsCommandHandler.cs @@ -66,31 +66,32 @@ private async Task StreamingFindBaseSymbolsAsync( { using var token = _asyncListener.BeginAsyncOperation(nameof(StreamingFindBaseSymbolsAsync)); - var context = presenter.StartSearch(EditorFeaturesResources.Navigating, supportsReferences: true, cancellationToken); + var (context, combinedCancellationToken) = presenter.StartSearch(EditorFeaturesResources.Navigating, supportsReferences: true, cancellationToken); + cancellationToken = combinedCancellationToken; using (Logger.LogBlock( FunctionId.CommandHandler_FindAllReference, KeyValueLogMessage.Create(LogType.UserAction, m => m["type"] = "streaming"), - context.CancellationToken)) + cancellationToken)) { try { #pragma warning disable CA2007 // Consider calling ConfigureAwait on the awaited task - var relevantSymbol = await FindUsagesHelpers.GetRelevantSymbolAndProjectAtPositionAsync(document, caretPosition, context.CancellationToken); + var relevantSymbol = await FindUsagesHelpers.GetRelevantSymbolAndProjectAtPositionAsync(document, caretPosition, cancellationToken); #pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task var overriddenSymbol = relevantSymbol?.symbol.GetOverriddenMember(); while (overriddenSymbol != null) { - if (context.CancellationToken.IsCancellationRequested) + if (cancellationToken.IsCancellationRequested) { return; } var definitionItem = overriddenSymbol.ToNonClassifiedDefinitionItem(document.Project.Solution, true); #pragma warning disable CA2007 // Consider calling ConfigureAwait on the awaited task - await context.OnDefinitionFoundAsync(definitionItem); + await context.OnDefinitionFoundAsync(definitionItem, cancellationToken); #pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task // try getting the next one @@ -99,7 +100,7 @@ private async Task StreamingFindBaseSymbolsAsync( } finally { - await context.OnCompletedAsync().ConfigureAwait(false); + await context.OnCompletedAsync(cancellationToken).ConfigureAwait(false); } } } diff --git a/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindDerivedSymbolsCommandHandler.cs b/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindDerivedSymbolsCommandHandler.cs index 33c8e08fb4427..ddd9058de4c1d 100644 --- a/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindDerivedSymbolsCommandHandler.cs +++ b/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindDerivedSymbolsCommandHandler.cs @@ -91,37 +91,38 @@ private async Task FindDerivedSymbolsAsync( { using var token = _asyncListener.BeginAsyncOperation(nameof(FindDerivedSymbolsAsync)); - var context = presenter.StartSearch(EditorFeaturesResources.Navigating, supportsReferences: true, cancellationToken); + var (context, combinedCancellationToken) = presenter.StartSearch(EditorFeaturesResources.Navigating, supportsReferences: true, cancellationToken); + cancellationToken = combinedCancellationToken; try { using (Logger.LogBlock( FunctionId.CommandHandler_FindAllReference, KeyValueLogMessage.Create(LogType.UserAction, m => m["type"] = "streaming"), - context.CancellationToken)) + cancellationToken)) { #pragma warning disable CA2007 // Consider calling ConfigureAwait on the awaited task - var candidateSymbolProjectPair = await FindUsagesHelpers.GetRelevantSymbolAndProjectAtPositionAsync(document, caretPosition, context.CancellationToken); + var candidateSymbolProjectPair = await FindUsagesHelpers.GetRelevantSymbolAndProjectAtPositionAsync(document, caretPosition, cancellationToken); #pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task if (candidateSymbolProjectPair?.symbol == null) return; #pragma warning disable CA2007 // Consider calling ConfigureAwait on the awaited task var candidates = await GatherSymbolsAsync(candidateSymbolProjectPair.Value.symbol, - document.Project.Solution, context.CancellationToken); + document.Project.Solution, cancellationToken); #pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task foreach (var candidate in candidates) { var definitionItem = candidate.ToNonClassifiedDefinitionItem(document.Project.Solution, true); #pragma warning disable CA2007 // Consider calling ConfigureAwait on the awaited task - await context.OnDefinitionFoundAsync(definitionItem); + await context.OnDefinitionFoundAsync(definitionItem, cancellationToken); #pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task } } } finally { - await context.OnCompletedAsync().ConfigureAwait(false); + await context.OnCompletedAsync(cancellationToken).ConfigureAwait(false); } } catch (OperationCanceledException) diff --git a/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindExtensionMethodsCommandHandler.cs b/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindExtensionMethodsCommandHandler.cs index ccb0fdc0ab362..541093fc3e5bf 100644 --- a/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindExtensionMethodsCommandHandler.cs +++ b/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindExtensionMethodsCommandHandler.cs @@ -68,15 +68,16 @@ private async Task FindExtensionMethodsAsync( { using var token = _asyncListener.BeginAsyncOperation(nameof(FindExtensionMethodsAsync)); - var context = presenter.StartSearch(EditorFeaturesResources.Navigating, supportsReferences: true, cancellationToken); + var (context, combinedCancellationToken) = presenter.StartSearch(EditorFeaturesResources.Navigating, supportsReferences: true, cancellationToken); + cancellationToken = combinedCancellationToken; using (Logger.LogBlock( FunctionId.CommandHandler_FindAllReference, KeyValueLogMessage.Create(LogType.UserAction, m => m["type"] = "streaming"), - context.CancellationToken)) + cancellationToken)) { #pragma warning disable CA2007 // Consider calling ConfigureAwait on the awaited task - var candidateSymbolProjectPair = await FindUsagesHelpers.GetRelevantSymbolAndProjectAtPositionAsync(document, caretPosition, context.CancellationToken); + var candidateSymbolProjectPair = await FindUsagesHelpers.GetRelevantSymbolAndProjectAtPositionAsync(document, caretPosition, cancellationToken); #pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task var symbol = candidateSymbolProjectPair?.symbol as INamedTypeSymbol; @@ -84,27 +85,27 @@ private async Task FindExtensionMethodsAsync( // if we didn't get the right symbol, just abort if (symbol == null) { - await context.OnCompletedAsync().ConfigureAwait(false); + await context.OnCompletedAsync(cancellationToken).ConfigureAwait(false); return; } Compilation compilation; if (!document.Project.TryGetCompilation(out compilation)) { - await context.OnCompletedAsync().ConfigureAwait(false); + await context.OnCompletedAsync(cancellationToken).ConfigureAwait(false); return; } var solution = document.Project.Solution; - foreach (var type in compilation.Assembly.GlobalNamespace.GetAllTypes(context.CancellationToken)) + foreach (var type in compilation.Assembly.GlobalNamespace.GetAllTypes(cancellationToken)) { if (!type.MightContainExtensionMethods) continue; foreach (var extMethod in type.GetMembers().OfType().Where(method => method.IsExtensionMethod)) { - if (context.CancellationToken.IsCancellationRequested) + if (cancellationToken.IsCancellationRequested) break; var reducedMethod = extMethod.ReduceExtensionMethod(symbol); @@ -112,24 +113,24 @@ private async Task FindExtensionMethodsAsync( { var loc = extMethod.Locations.First(); - var sourceDefinition = await SymbolFinder.FindSourceDefinitionAsync(reducedMethod, solution, context.CancellationToken).ConfigureAwait(false); + var sourceDefinition = await SymbolFinder.FindSourceDefinitionAsync(reducedMethod, solution, cancellationToken).ConfigureAwait(false); // And if our definition actually is from source, then let's re-figure out what project it came from if (sourceDefinition != null) { - var originatingProject = solution.GetProject(sourceDefinition.ContainingAssembly, context.CancellationToken); + var originatingProject = solution.GetProject(sourceDefinition.ContainingAssembly, cancellationToken); var definitionItem = reducedMethod.ToNonClassifiedDefinitionItem(solution, true); #pragma warning disable CA2007 // Consider calling ConfigureAwait on the awaited task - await context.OnDefinitionFoundAsync(definitionItem); + await context.OnDefinitionFoundAsync(definitionItem, cancellationToken); #pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task } } } } - await context.OnCompletedAsync().ConfigureAwait(false); + await context.OnCompletedAsync(cancellationToken).ConfigureAwait(false); } } catch (OperationCanceledException) diff --git a/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindImplementingMembersCommandHandler.cs b/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindImplementingMembersCommandHandler.cs index ce37f9c2f5860..8a08c6e8e9a06 100644 --- a/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindImplementingMembersCommandHandler.cs +++ b/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindImplementingMembersCommandHandler.cs @@ -69,17 +69,18 @@ private async Task FindImplementingMembersAsync( // Let the presented know we're starting a search. We pass in no cancellation token here as this // operation itself is fire-and-forget and the user won't cancel the operation through us (though // the window itself can cancel the operation if it is taken over for another find operation. - var context = presenter.StartSearch(EditorFeaturesResources.Navigating, supportsReferences: true, cancellationToken); + var (context, combinedCancellationToken) = presenter.StartSearch(EditorFeaturesResources.Navigating, supportsReferences: true, cancellationToken); + cancellationToken = combinedCancellationToken; using (Logger.LogBlock( FunctionId.CommandHandler_FindAllReference, KeyValueLogMessage.Create(LogType.UserAction, m => m["type"] = "streaming"), - context.CancellationToken)) + cancellationToken)) { try { #pragma warning disable CA2007 // Consider calling ConfigureAwait on the awaited task - var relevantSymbol = await FindUsagesHelpers.GetRelevantSymbolAndProjectAtPositionAsync(document, caretPosition, context.CancellationToken); + var relevantSymbol = await FindUsagesHelpers.GetRelevantSymbolAndProjectAtPositionAsync(document, caretPosition, cancellationToken); #pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task var interfaceSymbol = relevantSymbol?.symbol as INamedTypeSymbol; @@ -118,20 +119,20 @@ private async Task FindImplementingMembersAsync( // we can search for implementations of the interface, within this type #pragma warning disable CA2007 // Consider calling ConfigureAwait on the awaited task - await InspectInterfaceAsync(context, interfaceSymbol, namedTypeSymbol, document.Project); + await InspectInterfaceAsync(context, interfaceSymbol, namedTypeSymbol, document.Project, cancellationToken); #pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task // now, we iterate on interfaces of our interfaces foreach (var iFace in interfaceSymbol.AllInterfaces) { #pragma warning disable CA2007 // Consider calling ConfigureAwait on the awaited task - await InspectInterfaceAsync(context, iFace, namedTypeSymbol, document.Project); + await InspectInterfaceAsync(context, iFace, namedTypeSymbol, document.Project, cancellationToken); #pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task } } finally { - await context.OnCompletedAsync().ConfigureAwait(false); + await context.OnCompletedAsync(cancellationToken).ConfigureAwait(false); } } } @@ -143,11 +144,12 @@ private async Task FindImplementingMembersAsync( } } - private static async Task InspectInterfaceAsync(IFindUsagesContext context, INamedTypeSymbol interfaceSymbol, INamedTypeSymbol namedTypeSymbol, Project project) + private static async Task InspectInterfaceAsync( + IFindUsagesContext context, INamedTypeSymbol interfaceSymbol, INamedTypeSymbol namedTypeSymbol, Project project, CancellationToken cancellationToken) { foreach (var interfaceMember in interfaceSymbol.GetMembers()) { - if (context.CancellationToken.IsCancellationRequested) + if (cancellationToken.IsCancellationRequested) return; var impl = namedTypeSymbol.FindImplementationForInterfaceMember(interfaceMember); @@ -156,7 +158,7 @@ private static async Task InspectInterfaceAsync(IFindUsagesContext context, INam var definitionItem = impl.ToNonClassifiedDefinitionItem(project.Solution, true); #pragma warning disable CA2007 // Consider calling ConfigureAwait on the awaited task - await context.OnDefinitionFoundAsync(definitionItem); + await context.OnDefinitionFoundAsync(definitionItem, cancellationToken); #pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task } } diff --git a/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindMemberOverloadsCommandHandler.cs b/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindMemberOverloadsCommandHandler.cs index 201037f4d185f..bb87550980785 100644 --- a/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindMemberOverloadsCommandHandler.cs +++ b/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindMemberOverloadsCommandHandler.cs @@ -64,18 +64,19 @@ private async Task FindMemberOverloadsAsync( { using var token = _asyncListener.BeginAsyncOperation(nameof(FindMemberOverloadsAsync)); - var context = presenter.StartSearch( + var (context, combinedCancellationToken) = presenter.StartSearch( EditorFeaturesResources.Navigating, supportsReferences: true, cancellationToken); + cancellationToken = combinedCancellationToken; using (Logger.LogBlock( FunctionId.CommandHandler_FindAllReference, KeyValueLogMessage.Create(LogType.UserAction, m => m["type"] = "streaming"), - context.CancellationToken)) + cancellationToken)) { try { #pragma warning disable CA2007 // Consider calling ConfigureAwait on the awaited task - var candidateSymbolProjectPair = await FindUsagesHelpers.GetRelevantSymbolAndProjectAtPositionAsync(document, caretPosition, context.CancellationToken); + var candidateSymbolProjectPair = await FindUsagesHelpers.GetRelevantSymbolAndProjectAtPositionAsync(document, caretPosition, cancellationToken); #pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task // we need to get the containing type (i.e. class) @@ -90,13 +91,13 @@ private async Task FindMemberOverloadsAsync( { var definitionItem = curSymbol.ToNonClassifiedDefinitionItem(document.Project.Solution, true); #pragma warning disable CA2007 // Consider calling ConfigureAwait on the awaited task - await context.OnDefinitionFoundAsync(definitionItem); + await context.OnDefinitionFoundAsync(definitionItem, cancellationToken); #pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task } } finally { - await context.OnCompletedAsync().ConfigureAwait(false); + await context.OnCompletedAsync(cancellationToken).ConfigureAwait(false); } } } diff --git a/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindReferencesOfOverloadsCommandHandler.cs b/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindReferencesOfOverloadsCommandHandler.cs index 302272ee68d8e..103c81e1ff438 100644 --- a/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindReferencesOfOverloadsCommandHandler.cs +++ b/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindReferencesOfOverloadsCommandHandler.cs @@ -105,12 +105,13 @@ private async Task StreamingFindReferencesAsync( using var token = _asyncListener.BeginAsyncOperation(nameof(StreamingFindReferencesAsync)); - var context = presenter.StartSearch(EditorFeaturesResources.Find_References, supportsReferences: true, cancellationToken); + var (context, combinedCancellationToken) = presenter.StartSearch(EditorFeaturesResources.Find_References, supportsReferences: true, cancellationToken); + cancellationToken = combinedCancellationToken; using (Logger.LogBlock( FunctionId.CommandHandler_FindAllReference, KeyValueLogMessage.Create(LogType.UserAction, m => m["type"] = "streaming"), - context.CancellationToken)) + cancellationToken)) { var symbolsToLookup = new List(); @@ -124,11 +125,11 @@ private async Task StreamingFindReferencesAsync( continue; } - foreach (var sym in SymbolFinder.FindSimilarSymbols(curSymbol, compilation, context.CancellationToken)) + foreach (var sym in SymbolFinder.FindSimilarSymbols(curSymbol, compilation, cancellationToken)) { // assumption here is, that FindSimilarSymbols returns symbols inside same project #pragma warning disable CA2007 // Consider calling ConfigureAwait on the awaited task - var symbolsToAdd = await GatherSymbolsAsync(sym, document.Project.Solution, context.CancellationToken); + var symbolsToAdd = await GatherSymbolsAsync(sym, document.Project.Solution, cancellationToken); #pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task symbolsToLookup.AddRange(symbolsToAdd); } @@ -137,7 +138,7 @@ private async Task StreamingFindReferencesAsync( foreach (var candidate in symbolsToLookup) { #pragma warning disable CA2007 // Consider calling ConfigureAwait on the awaited task - await AbstractFindUsagesService.FindSymbolReferencesAsync(context, candidate, document.Project); + await AbstractFindUsagesService.FindSymbolReferencesAsync(context, candidate, document.Project, cancellationToken); #pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task } @@ -146,7 +147,7 @@ private async Task StreamingFindReferencesAsync( // that means that a new search has started. We don't care about telling the // context it has completed. In the latter case something wrong has happened // and we don't want to run any more code in this particular context. - await context.OnCompletedAsync().ConfigureAwait(false); + await context.OnCompletedAsync(cancellationToken).ConfigureAwait(false); } } catch (OperationCanceledException) diff --git a/src/EditorFeatures/Core/CommandHandlers/AbstractGoToCommandHandler.cs b/src/EditorFeatures/Core/CommandHandlers/AbstractGoToCommandHandler.cs index d961bdbe78da2..37fe2284a4677 100644 --- a/src/EditorFeatures/Core/CommandHandlers/AbstractGoToCommandHandler.cs +++ b/src/EditorFeatures/Core/CommandHandlers/AbstractGoToCommandHandler.cs @@ -39,7 +39,7 @@ public AbstractGoToCommandHandler( public abstract string DisplayName { get; } protected abstract string ScopeDescription { get; } protected abstract FunctionId FunctionId { get; } - protected abstract Task FindActionAsync(TLanguageService service, Document document, int caretPosition, IFindUsagesContext context); + protected abstract Task FindActionAsync(TLanguageService service, Document document, int caretPosition, IFindUsagesContext context, CancellationToken cancellationToken); public CommandState GetCommandState(TCommandArgs args) { @@ -119,9 +119,9 @@ private async Task NavigateToOrPresentResultsAsync( // the individual TLanguageService. Once we get the results back we'll then decide // what to do with them. If we get only a single result back, then we'll just go // directly to it. Otherwise, we'll present the results in the IStreamingFindUsagesPresenter. - var context = new SimpleFindUsagesContext(cancellationToken); + var context = new SimpleFindUsagesContext(); - await FindActionAsync(service, document, caretPosition, context).ConfigureAwait(false); + await FindActionAsync(service, document, caretPosition, context, cancellationToken).ConfigureAwait(false); if (context.Message != null) return context.Message; diff --git a/src/EditorFeatures/Core/FindReferences/FindReferencesCommandHandler.cs b/src/EditorFeatures/Core/FindReferences/FindReferencesCommandHandler.cs index 139a71759f8dd..26f5d80a5cfb8 100644 --- a/src/EditorFeatures/Core/FindReferences/FindReferencesCommandHandler.cs +++ b/src/EditorFeatures/Core/FindReferences/FindReferencesCommandHandler.cs @@ -117,7 +117,7 @@ private async Task StreamingFindReferencesAsync( // Let the presented know we're starting a search. It will give us back the context object that the FAR // service will push results into. This operation is not externally cancellable. Instead, the find refs // window will cancel it if another request is made to use it. - var context = presenter.StartSearchWithCustomColumns( + var (context, cancellationToken) = presenter.StartSearchWithCustomColumns( EditorFeaturesResources.Find_References, supportsReferences: true, includeContainingTypeAndMemberColumns: document.Project.SupportsCompilation, @@ -127,15 +127,15 @@ private async Task StreamingFindReferencesAsync( using (Logger.LogBlock( FunctionId.CommandHandler_FindAllReference, KeyValueLogMessage.Create(LogType.UserAction, m => m["type"] = "streaming"), - context.CancellationToken)) + cancellationToken)) { try { - await findUsagesService.FindReferencesAsync(document, caretPosition, context).ConfigureAwait(false); + await findUsagesService.FindReferencesAsync(document, caretPosition, context, cancellationToken).ConfigureAwait(false); } finally { - await context.OnCompletedAsync().ConfigureAwait(false); + await context.OnCompletedAsync(cancellationToken).ConfigureAwait(false); } } } diff --git a/src/EditorFeatures/Core/FindUsages/AbstractFindUsagesService.DefinitionTrackingContext.cs b/src/EditorFeatures/Core/FindUsages/AbstractFindUsagesService.DefinitionTrackingContext.cs index 838f11f6990b5..805cb5746ede7 100644 --- a/src/EditorFeatures/Core/FindUsages/AbstractFindUsagesService.DefinitionTrackingContext.cs +++ b/src/EditorFeatures/Core/FindUsages/AbstractFindUsagesService.DefinitionTrackingContext.cs @@ -33,33 +33,30 @@ private class DefinitionTrackingContext : IFindUsagesContext public DefinitionTrackingContext(IFindUsagesContext underlyingContext) => _underlyingContext = underlyingContext; - public CancellationToken CancellationToken - => _underlyingContext.CancellationToken; - public IStreamingProgressTracker ProgressTracker => _underlyingContext.ProgressTracker; - public ValueTask ReportMessageAsync(string message) - => _underlyingContext.ReportMessageAsync(message); + public ValueTask ReportMessageAsync(string message, CancellationToken cancellationToken) + => _underlyingContext.ReportMessageAsync(message, cancellationToken); - public ValueTask SetSearchTitleAsync(string title) - => _underlyingContext.SetSearchTitleAsync(title); + public ValueTask SetSearchTitleAsync(string title, CancellationToken cancellationToken) + => _underlyingContext.SetSearchTitleAsync(title, cancellationToken); - public ValueTask OnReferenceFoundAsync(SourceReferenceItem reference) - => _underlyingContext.OnReferenceFoundAsync(reference); + public ValueTask OnReferenceFoundAsync(SourceReferenceItem reference, CancellationToken cancellationToken) + => _underlyingContext.OnReferenceFoundAsync(reference, cancellationToken); [Obsolete("Use ProgressTracker instead", error: false)] - public ValueTask ReportProgressAsync(int current, int maximum) - => _underlyingContext.ReportProgressAsync(current, maximum); + public ValueTask ReportProgressAsync(int current, int maximum, CancellationToken cancellationToken) + => _underlyingContext.ReportProgressAsync(current, maximum, cancellationToken); - public ValueTask OnDefinitionFoundAsync(DefinitionItem definition) + public ValueTask OnDefinitionFoundAsync(DefinitionItem definition, CancellationToken cancellationToken) { lock (_gate) { _definitions.Add(definition); } - return _underlyingContext.OnDefinitionFoundAsync(definition); + return _underlyingContext.OnDefinitionFoundAsync(definition, cancellationToken); } public ImmutableArray GetDefinitions() diff --git a/src/EditorFeatures/Core/FindUsages/AbstractFindUsagesService.ProgressAdapter.cs b/src/EditorFeatures/Core/FindUsages/AbstractFindUsagesService.ProgressAdapter.cs index e605ce3a0ef3f..886564d876238 100644 --- a/src/EditorFeatures/Core/FindUsages/AbstractFindUsagesService.ProgressAdapter.cs +++ b/src/EditorFeatures/Core/FindUsages/AbstractFindUsagesService.ProgressAdapter.cs @@ -38,12 +38,12 @@ public FindLiteralsProgressAdapter( _definition = definition; } - public async ValueTask OnReferenceFoundAsync(Document document, TextSpan span) + public async ValueTask OnReferenceFoundAsync(Document document, TextSpan span, CancellationToken cancellationToken) { var documentSpan = await ClassifiedSpansAndHighlightSpanFactory.GetClassifiedDocumentSpanAsync( - document, span, _context.CancellationToken).ConfigureAwait(false); + document, span, cancellationToken).ConfigureAwait(false); await _context.OnReferenceFoundAsync(new SourceReferenceItem( - _definition, documentSpan, SymbolUsageInfo.None)).ConfigureAwait(false); + _definition, documentSpan, SymbolUsageInfo.None), cancellationToken).ConfigureAwait(false); } } @@ -83,18 +83,17 @@ public FindReferencesProgressAdapter( // Do nothing functions. The streaming far service doesn't care about // any of these. - public ValueTask OnStartedAsync() => default; - public ValueTask OnCompletedAsync() => default; - public ValueTask OnFindInDocumentStartedAsync(Document document) => default; - public ValueTask OnFindInDocumentCompletedAsync(Document document) => default; + public ValueTask OnStartedAsync(CancellationToken cancellationToken) => default; + public ValueTask OnCompletedAsync(CancellationToken cancellationToken) => default; + public ValueTask OnFindInDocumentStartedAsync(Document document, CancellationToken cancellationToken) => default; + public ValueTask OnFindInDocumentCompletedAsync(Document document, CancellationToken cancellationToken) => default; // More complicated forwarding functions. These need to map from the symbols // used by the FAR engine to the INavigableItems used by the streaming FAR // feature. - private async ValueTask GetDefinitionItemAsync(SymbolGroup group) + private async ValueTask GetDefinitionItemAsync(SymbolGroup group, CancellationToken cancellationToken) { - var cancellationToken = _context.CancellationToken; using (await _gate.DisposableWaitAsync(cancellationToken).ConfigureAwait(false)) { if (!_definitionToItem.TryGetValue(group, out var definitionItem)) @@ -104,7 +103,7 @@ private async ValueTask GetDefinitionItemAsync(SymbolGroup group isPrimary: _definitionToItem.Count == 0, includeHiddenLocations: false, _options, - _context.CancellationToken).ConfigureAwait(false); + cancellationToken).ConfigureAwait(false); _definitionToItem[group] = definitionItem; } @@ -113,21 +112,21 @@ private async ValueTask GetDefinitionItemAsync(SymbolGroup group } } - public async ValueTask OnDefinitionFoundAsync(SymbolGroup group) + public async ValueTask OnDefinitionFoundAsync(SymbolGroup group, CancellationToken cancellationToken) { - var definitionItem = await GetDefinitionItemAsync(group).ConfigureAwait(false); - await _context.OnDefinitionFoundAsync(definitionItem).ConfigureAwait(false); + var definitionItem = await GetDefinitionItemAsync(group, cancellationToken).ConfigureAwait(false); + await _context.OnDefinitionFoundAsync(definitionItem, cancellationToken).ConfigureAwait(false); } - public async ValueTask OnReferenceFoundAsync(SymbolGroup group, ISymbol definition, ReferenceLocation location) + public async ValueTask OnReferenceFoundAsync(SymbolGroup group, ISymbol definition, ReferenceLocation location, CancellationToken cancellationToken) { - var definitionItem = await GetDefinitionItemAsync(group).ConfigureAwait(false); + var definitionItem = await GetDefinitionItemAsync(group, cancellationToken).ConfigureAwait(false); var referenceItem = await location.TryCreateSourceReferenceItemAsync( definitionItem, includeHiddenLocations: false, - cancellationToken: _context.CancellationToken).ConfigureAwait(false); + cancellationToken).ConfigureAwait(false); if (referenceItem != null) - await _context.OnReferenceFoundAsync(referenceItem).ConfigureAwait(false); + await _context.OnReferenceFoundAsync(referenceItem, cancellationToken).ConfigureAwait(false); } } } diff --git a/src/EditorFeatures/Core/FindUsages/AbstractFindUsagesService_FindImplementations.cs b/src/EditorFeatures/Core/FindUsages/AbstractFindUsagesService_FindImplementations.cs index cd831496af0df..d8a3921993deb 100644 --- a/src/EditorFeatures/Core/FindUsages/AbstractFindUsagesService_FindImplementations.cs +++ b/src/EditorFeatures/Core/FindUsages/AbstractFindUsagesService_FindImplementations.cs @@ -18,29 +18,27 @@ namespace Microsoft.CodeAnalysis.Editor.FindUsages { internal abstract partial class AbstractFindUsagesService { - public async Task FindImplementationsAsync(Document document, int position, IFindUsagesContext context) + public async Task FindImplementationsAsync( + Document document, int position, IFindUsagesContext context, CancellationToken cancellationToken) { - var cancellationToken = context.CancellationToken; - // If this is a symbol from a metadata-as-source project, then map that symbol back to a symbol in the primary workspace. var symbolAndProjectOpt = await FindUsagesHelpers.GetRelevantSymbolAndProjectAtPositionAsync( document, position, cancellationToken).ConfigureAwait(false); if (symbolAndProjectOpt == null) { await context.ReportMessageAsync( - EditorFeaturesResources.Cannot_navigate_to_the_symbol_under_the_caret).ConfigureAwait(false); + EditorFeaturesResources.Cannot_navigate_to_the_symbol_under_the_caret, cancellationToken).ConfigureAwait(false); return; } var symbolAndProject = symbolAndProjectOpt.Value; await FindImplementationsAsync( - symbolAndProject.symbol, symbolAndProject.project, context).ConfigureAwait(false); + symbolAndProject.symbol, symbolAndProject.project, context, cancellationToken).ConfigureAwait(false); } public static async Task FindImplementationsAsync( - ISymbol symbol, Project project, IFindUsagesContext context) + ISymbol symbol, Project project, IFindUsagesContext context, CancellationToken cancellationToken) { - var cancellationToken = context.CancellationToken; var solution = project.Solution; var client = await RemoteHostClient.TryGetClientAsync(solution.Workspace, cancellationToken).ConfigureAwait(false); if (client != null) @@ -61,35 +59,34 @@ await client.TryInvokeAsync( { // Couldn't effectively search in OOP. Perform the search in-process. await FindImplementationsInCurrentProcessAsync( - symbol, project, context).ConfigureAwait(false); + symbol, project, context, cancellationToken).ConfigureAwait(false); } } private static async Task FindImplementationsInCurrentProcessAsync( - ISymbol symbol, Project project, IFindUsagesContext context) + ISymbol symbol, Project project, IFindUsagesContext context, CancellationToken cancellationToken) { - var cancellationToken = context.CancellationToken; - var solution = project.Solution; var (implementations, message) = await FindSourceImplementationsAsync( solution, symbol, cancellationToken).ConfigureAwait(false); if (message != null) { - await context.ReportMessageAsync(message).ConfigureAwait(false); + await context.ReportMessageAsync(message, cancellationToken).ConfigureAwait(false); return; } await context.SetSearchTitleAsync( string.Format(EditorFeaturesResources._0_implementations, - FindUsagesHelpers.GetDisplayName(symbol))).ConfigureAwait(false); + FindUsagesHelpers.GetDisplayName(symbol)), + cancellationToken).ConfigureAwait(false); foreach (var implementation in implementations) { var definitionItem = await implementation.ToClassifiedDefinitionItemAsync( solution, isPrimary: true, includeHiddenLocations: false, FindReferencesSearchOptions.Default, cancellationToken).ConfigureAwait(false); - await context.OnDefinitionFoundAsync(definitionItem).ConfigureAwait(false); + await context.OnDefinitionFoundAsync(definitionItem, cancellationToken).ConfigureAwait(false); } } diff --git a/src/EditorFeatures/Core/FindUsages/AbstractFindUsagesService_FindReferences.cs b/src/EditorFeatures/Core/FindUsages/AbstractFindUsagesService_FindReferences.cs index 21683c9a1427f..a30d57c0f41f6 100644 --- a/src/EditorFeatures/Core/FindUsages/AbstractFindUsagesService_FindReferences.cs +++ b/src/EditorFeatures/Core/FindUsages/AbstractFindUsagesService_FindReferences.cs @@ -19,7 +19,7 @@ namespace Microsoft.CodeAnalysis.Editor.FindUsages internal abstract partial class AbstractFindUsagesService { async Task IFindUsagesService.FindReferencesAsync( - Document document, int position, IFindUsagesContext context) + Document document, int position, IFindUsagesContext context, CancellationToken cancellationToken) { var definitionTrackingContext = new DefinitionTrackingContext(context); @@ -29,12 +29,12 @@ async Task IFindUsagesService.FindReferencesAsync( // // Any async calls before GetThirdPartyDefinitions must be ConfigureAwait(true). await FindLiteralOrSymbolReferencesAsync( - document, position, definitionTrackingContext).ConfigureAwait(true); + document, position, definitionTrackingContext, cancellationToken).ConfigureAwait(true); // After the FAR engine is done call into any third party extensions to see // if they want to add results. var thirdPartyDefinitions = GetThirdPartyDefinitions( - document.Project.Solution, definitionTrackingContext.GetDefinitions(), context.CancellationToken); + document.Project.Solution, definitionTrackingContext.GetDefinitions(), cancellationToken); // From this point on we can do ConfigureAwait(false) as we're not calling back // into third parties anymore. @@ -42,27 +42,28 @@ await FindLiteralOrSymbolReferencesAsync( foreach (var definition in thirdPartyDefinitions) { // Don't need ConfigureAwait(true) here - await context.OnDefinitionFoundAsync(definition).ConfigureAwait(false); + await context.OnDefinitionFoundAsync(definition, cancellationToken).ConfigureAwait(false); } } Task IFindUsagesLSPService.FindReferencesAsync( - Document document, int position, IFindUsagesContext context) + Document document, int position, IFindUsagesContext context, CancellationToken cancellationToken) { // We don't need to get third party definitions when finding references in LSP. // Currently, 3rd party definitions = XAML definitions, and XAML will provide // references via LSP instead of hooking into Roslyn. // This also means that we don't need to be on the UI thread. - return FindLiteralOrSymbolReferencesAsync(document, position, new DefinitionTrackingContext(context)); + return FindLiteralOrSymbolReferencesAsync( + document, position, new DefinitionTrackingContext(context), cancellationToken); } private static async Task FindLiteralOrSymbolReferencesAsync( - Document document, int position, IFindUsagesContext context) + Document document, int position, IFindUsagesContext context, CancellationToken cancellationToken) { // First, see if we're on a literal. If so search for literals in the solution with // the same value. var found = await TryFindLiteralReferencesAsync( - document, position, context).ConfigureAwait(false); + document, position, context, cancellationToken).ConfigureAwait(false); if (found) { return; @@ -70,7 +71,7 @@ private static async Task FindLiteralOrSymbolReferencesAsync( // Wasn't a literal. Try again as a symbol. await FindSymbolReferencesAsync( - document, position, context).ConfigureAwait(false); + document, position, context, cancellationToken).ConfigureAwait(false); } private static ImmutableArray GetThirdPartyDefinitions( @@ -85,9 +86,8 @@ private static ImmutableArray GetThirdPartyDefinitions( } private static async Task FindSymbolReferencesAsync( - Document document, int position, IFindUsagesContext context) + Document document, int position, IFindUsagesContext context, CancellationToken cancellationToken) { - var cancellationToken = context.CancellationToken; cancellationToken.ThrowIfCancellationRequested(); // If this is a symbol from a metadata-as-source project, then map that symbol back to a symbol in the primary workspace. @@ -99,7 +99,7 @@ private static async Task FindSymbolReferencesAsync( var (symbol, project) = symbolAndProjectOpt.Value; await FindSymbolReferencesAsync( - context, symbol, project).ConfigureAwait(false); + context, symbol, project, cancellationToken).ConfigureAwait(false); } /// @@ -107,10 +107,12 @@ await FindSymbolReferencesAsync( /// and want to push all the references to it into the Streaming-Find-References window. /// public static async Task FindSymbolReferencesAsync( - IFindUsagesContext context, ISymbol symbol, Project project) + IFindUsagesContext context, ISymbol symbol, Project project, CancellationToken cancellationToken) { - await context.SetSearchTitleAsync(string.Format(EditorFeaturesResources._0_references, - FindUsagesHelpers.GetDisplayName(symbol))).ConfigureAwait(false); + await context.SetSearchTitleAsync( + string.Format(EditorFeaturesResources._0_references, + FindUsagesHelpers.GetDisplayName(symbol)), + cancellationToken).ConfigureAwait(false); var options = FindReferencesSearchOptions.GetFeatureOptionsForStartingSymbol(symbol); @@ -118,16 +120,16 @@ await context.SetSearchTitleAsync(string.Format(EditorFeaturesResources._0_refer // engine will push results into the 'progress' instance passed into it. // We'll take those results, massage them, and forward them along to the // FindReferencesContext instance we were given. - await FindReferencesAsync(context, symbol, project, options).ConfigureAwait(false); + await FindReferencesAsync(context, symbol, project, options, cancellationToken).ConfigureAwait(false); } public static async Task FindReferencesAsync( IFindUsagesContext context, ISymbol symbol, Project project, - FindReferencesSearchOptions options) + FindReferencesSearchOptions options, + CancellationToken cancellationToken) { - var cancellationToken = context.CancellationToken; var solution = project.Solution; var client = await RemoteHostClient.TryGetClientAsync(solution.Workspace, cancellationToken).ConfigureAwait(false); if (client != null) @@ -148,7 +150,7 @@ public static async Task FindReferencesAsync( { // Couldn't effectively search in OOP. Perform the search in-process. await FindReferencesInCurrentProcessAsync( - context, symbol, project, options).ConfigureAwait(false); + context, symbol, project, options, cancellationToken).ConfigureAwait(false); } } @@ -156,17 +158,17 @@ private static Task FindReferencesInCurrentProcessAsync( IFindUsagesContext context, ISymbol symbol, Project project, - FindReferencesSearchOptions options) + FindReferencesSearchOptions options, + CancellationToken cancellationToken) { var progress = new FindReferencesProgressAdapter(project.Solution, context, options); return SymbolFinder.FindReferencesAsync( - symbol, project.Solution, progress, documents: null, options, context.CancellationToken); + symbol, project.Solution, progress, documents: null, options, cancellationToken); } private static async Task TryFindLiteralReferencesAsync( - Document document, int position, IFindUsagesContext context) + Document document, int position, IFindUsagesContext context, CancellationToken cancellationToken) { - var cancellationToken = context.CancellationToken; cancellationToken.ThrowIfCancellationRequested(); var syntaxTree = await document.GetRequiredSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); @@ -197,7 +199,7 @@ private static async Task TryFindLiteralReferencesAsync( return false; var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); - var symbol = semanticModel.GetSymbolInfo(token.Parent).Symbol ?? semanticModel.GetDeclaredSymbol(token.Parent); + var symbol = semanticModel.GetSymbolInfo(token.Parent, cancellationToken).Symbol ?? semanticModel.GetDeclaredSymbol(token.Parent, cancellationToken); // Numeric labels are available in VB. In that case we want the normal FAR engine to // do the searching. For these literals we want to find symbolic results and not @@ -213,7 +215,7 @@ private static async Task TryFindLiteralReferencesAsync( } var searchTitle = string.Format(EditorFeaturesResources._0_references, title); - await context.SetSearchTitleAsync(searchTitle).ConfigureAwait(false); + await context.SetSearchTitleAsync(searchTitle, cancellationToken).ConfigureAwait(false); var solution = document.Project.Solution; @@ -223,7 +225,7 @@ private static async Task TryFindLiteralReferencesAsync( ImmutableArray.Create(TextTags.StringLiteral), ImmutableArray.Create(new TaggedText(TextTags.Text, searchTitle))); - await context.OnDefinitionFoundAsync(definition).ConfigureAwait(false); + await context.OnDefinitionFoundAsync(definition, cancellationToken).ConfigureAwait(false); var progressAdapter = new FindLiteralsProgressAdapter(context, definition); diff --git a/src/EditorFeatures/Core/FindUsages/FindUsagesContext.cs b/src/EditorFeatures/Core/FindUsages/FindUsagesContext.cs index 445f450662f4a..f02db9c0a5822 100644 --- a/src/EditorFeatures/Core/FindUsages/FindUsagesContext.cs +++ b/src/EditorFeatures/Core/FindUsages/FindUsagesContext.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Shared.Utilities; @@ -12,26 +10,24 @@ namespace Microsoft.CodeAnalysis.FindUsages { internal abstract class FindUsagesContext : IFindUsagesContext { - public virtual CancellationToken CancellationToken { get; } - public IStreamingProgressTracker ProgressTracker { get; } protected FindUsagesContext() => this.ProgressTracker = new StreamingProgressTracker(this.ReportProgressAsync); - public virtual ValueTask ReportMessageAsync(string message) => default; + public virtual ValueTask ReportMessageAsync(string message, CancellationToken cancellationToken) => default; - public virtual ValueTask SetSearchTitleAsync(string title) => default; + public virtual ValueTask SetSearchTitleAsync(string title, CancellationToken cancellationToken) => default; - public virtual ValueTask OnCompletedAsync() => default; + public virtual ValueTask OnCompletedAsync(CancellationToken cancellationToken) => default; - public virtual ValueTask OnDefinitionFoundAsync(DefinitionItem definition) => default; + public virtual ValueTask OnDefinitionFoundAsync(DefinitionItem definition, CancellationToken cancellationToken) => default; - public virtual ValueTask OnReferenceFoundAsync(SourceReferenceItem reference) => default; + public virtual ValueTask OnReferenceFoundAsync(SourceReferenceItem reference, CancellationToken cancellationToken) => default; - protected virtual ValueTask ReportProgressAsync(int current, int maximum) => default; + protected virtual ValueTask ReportProgressAsync(int current, int maximum, CancellationToken cancellationToken) => default; - ValueTask IFindUsagesContext.ReportProgressAsync(int current, int maximum) - => ReportProgressAsync(current, maximum); + ValueTask IFindUsagesContext.ReportProgressAsync(int current, int maximum, CancellationToken cancellationToken) + => ReportProgressAsync(current, maximum, cancellationToken); } } diff --git a/src/EditorFeatures/Core/FindUsages/IFindUsagesLSPService.cs b/src/EditorFeatures/Core/FindUsages/IFindUsagesLSPService.cs index cfca2911abfb6..5533dd10c364a 100644 --- a/src/EditorFeatures/Core/FindUsages/IFindUsagesLSPService.cs +++ b/src/EditorFeatures/Core/FindUsages/IFindUsagesLSPService.cs @@ -2,8 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - +using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.FindUsages; using Microsoft.CodeAnalysis.Host; @@ -16,12 +15,12 @@ internal interface IFindUsagesLSPService : ILanguageService /// Finds the references for the symbol at the specific position in the document, /// pushing the results into the context instance. /// - Task FindReferencesAsync(Document document, int position, IFindUsagesContext context); + Task FindReferencesAsync(Document document, int position, IFindUsagesContext context, CancellationToken cancellationToken); /// /// Finds the implementations for the symbol at the specific position in the document, /// pushing the results into the context instance. /// - Task FindImplementationsAsync(Document document, int position, IFindUsagesContext context); + Task FindImplementationsAsync(Document document, int position, IFindUsagesContext context, CancellationToken cancellationToken); } } diff --git a/src/EditorFeatures/Core/FindUsages/IFindUsagesService.cs b/src/EditorFeatures/Core/FindUsages/IFindUsagesService.cs index 9b92dbaf237fc..e6c247e4bd999 100644 --- a/src/EditorFeatures/Core/FindUsages/IFindUsagesService.cs +++ b/src/EditorFeatures/Core/FindUsages/IFindUsagesService.cs @@ -2,8 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - +using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.FindUsages; using Microsoft.CodeAnalysis.Host; @@ -16,12 +15,12 @@ internal interface IFindUsagesService : ILanguageService /// Finds the references for the symbol at the specific position in the document, /// pushing the results into the context instance. /// - Task FindReferencesAsync(Document document, int position, IFindUsagesContext context); + Task FindReferencesAsync(Document document, int position, IFindUsagesContext context, CancellationToken cancellationToken); /// /// Finds the implementations for the symbol at the specific position in the document, /// pushing the results into the context instance. /// - Task FindImplementationsAsync(Document document, int position, IFindUsagesContext context); + Task FindImplementationsAsync(Document document, int position, IFindUsagesContext context, CancellationToken cancellationToken); } } diff --git a/src/EditorFeatures/Core/FindUsages/SimpleFindUsagesContext.cs b/src/EditorFeatures/Core/FindUsages/SimpleFindUsagesContext.cs index cf6becce0a3cd..6adc1175310ee 100644 --- a/src/EditorFeatures/Core/FindUsages/SimpleFindUsagesContext.cs +++ b/src/EditorFeatures/Core/FindUsages/SimpleFindUsagesContext.cs @@ -25,21 +25,20 @@ internal class SimpleFindUsagesContext : FindUsagesContext private readonly ImmutableArray.Builder _referenceItems = ImmutableArray.CreateBuilder(); - public override CancellationToken CancellationToken { get; } - - public SimpleFindUsagesContext(CancellationToken cancellationToken) - => CancellationToken = cancellationToken; + public SimpleFindUsagesContext() + { + } public string Message { get; private set; } public string SearchTitle { get; private set; } - public override ValueTask ReportMessageAsync(string message) + public override ValueTask ReportMessageAsync(string message, CancellationToken cancellationToken) { Message = message; return default; } - public override ValueTask SetSearchTitleAsync(string title) + public override ValueTask SetSearchTitleAsync(string title, CancellationToken cancellationToken) { SearchTitle = title; return default; @@ -61,7 +60,7 @@ public ImmutableArray GetReferences() } } - public override ValueTask OnDefinitionFoundAsync(DefinitionItem definition) + public override ValueTask OnDefinitionFoundAsync(DefinitionItem definition, CancellationToken cancellationToken) { lock (_gate) { @@ -71,7 +70,7 @@ public override ValueTask OnDefinitionFoundAsync(DefinitionItem definition) return default; } - public override ValueTask OnReferenceFoundAsync(SourceReferenceItem reference) + public override ValueTask OnReferenceFoundAsync(SourceReferenceItem reference, CancellationToken cancellationToken) { lock (_gate) { diff --git a/src/EditorFeatures/Core/GoToBase/AbstractGoToBaseService.cs b/src/EditorFeatures/Core/GoToBase/AbstractGoToBaseService.cs index e5c1ee377a2c8..060fd12c467c9 100644 --- a/src/EditorFeatures/Core/GoToBase/AbstractGoToBaseService.cs +++ b/src/EditorFeatures/Core/GoToBase/AbstractGoToBaseService.cs @@ -5,6 +5,7 @@ #nullable disable using System.Linq; +using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Editor.FindUsages; using Microsoft.CodeAnalysis.FindSymbols; @@ -14,16 +15,15 @@ namespace Microsoft.CodeAnalysis.Editor.GoToBase { internal abstract partial class AbstractGoToBaseService : IGoToBaseService { - public async Task FindBasesAsync(Document document, int position, IFindUsagesContext context) + public async Task FindBasesAsync(Document document, int position, IFindUsagesContext context, CancellationToken cancellationToken) { - var cancellationToken = context.CancellationToken; var symbolAndProjectOpt = await FindUsagesHelpers.GetRelevantSymbolAndProjectAtPositionAsync( document, position, cancellationToken).ConfigureAwait(false); if (symbolAndProjectOpt == null) { await context.ReportMessageAsync( - EditorFeaturesResources.Cannot_navigate_to_the_symbol_under_the_caret).ConfigureAwait(false); + EditorFeaturesResources.Cannot_navigate_to_the_symbol_under_the_caret, cancellationToken).ConfigureAwait(false); return; } @@ -34,7 +34,8 @@ await context.ReportMessageAsync( await context.SetSearchTitleAsync( string.Format(EditorFeaturesResources._0_bases, - FindUsagesHelpers.GetDisplayName(symbol))).ConfigureAwait(false); + FindUsagesHelpers.GetDisplayName(symbol)), + cancellationToken).ConfigureAwait(false); var found = false; @@ -50,22 +51,21 @@ await context.SetSearchTitleAsync( var definitionItem = await sourceDefinition.ToClassifiedDefinitionItemAsync( solution, isPrimary: true, includeHiddenLocations: false, FindReferencesSearchOptions.Default, cancellationToken: cancellationToken).ConfigureAwait(false); - await context.OnDefinitionFoundAsync(definitionItem).ConfigureAwait(false); + await context.OnDefinitionFoundAsync(definitionItem, cancellationToken).ConfigureAwait(false); found = true; } else if (baseSymbol.Locations.Any(l => l.IsInMetadata)) { var definitionItem = baseSymbol.ToNonClassifiedDefinitionItem( solution, includeHiddenLocations: true); - await context.OnDefinitionFoundAsync(definitionItem).ConfigureAwait(false); + await context.OnDefinitionFoundAsync(definitionItem, cancellationToken).ConfigureAwait(false); found = true; } } if (!found) { - await context.ReportMessageAsync(EditorFeaturesResources.The_symbol_has_no_base) - .ConfigureAwait(false); + await context.ReportMessageAsync(EditorFeaturesResources.The_symbol_has_no_base, cancellationToken).ConfigureAwait(false); } } } diff --git a/src/EditorFeatures/Core/GoToBase/GoToBaseCommandHandler.cs b/src/EditorFeatures/Core/GoToBase/GoToBaseCommandHandler.cs index 16e189a741f66..04cfe1904074e 100644 --- a/src/EditorFeatures/Core/GoToBase/GoToBaseCommandHandler.cs +++ b/src/EditorFeatures/Core/GoToBase/GoToBaseCommandHandler.cs @@ -6,6 +6,7 @@ using System; using System.ComponentModel.Composition; +using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Editor.CommandHandlers; using Microsoft.CodeAnalysis.Editor.Host; @@ -38,7 +39,7 @@ public GoToBaseCommandHandler( protected override FunctionId FunctionId => FunctionId.CommandHandler_GoToBase; - protected override Task FindActionAsync(IGoToBaseService service, Document document, int caretPosition, IFindUsagesContext context) - => service.FindBasesAsync(document, caretPosition, context); + protected override Task FindActionAsync(IGoToBaseService service, Document document, int caretPosition, IFindUsagesContext context, CancellationToken cancellationToken) + => service.FindBasesAsync(document, caretPosition, context, cancellationToken); } } diff --git a/src/EditorFeatures/Core/GoToBase/IGoToBaseService.cs b/src/EditorFeatures/Core/GoToBase/IGoToBaseService.cs index 0451b71417598..ec7acee0f8a91 100644 --- a/src/EditorFeatures/Core/GoToBase/IGoToBaseService.cs +++ b/src/EditorFeatures/Core/GoToBase/IGoToBaseService.cs @@ -2,8 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - +using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.FindUsages; using Microsoft.CodeAnalysis.Host; @@ -16,6 +15,6 @@ internal interface IGoToBaseService : ILanguageService /// Finds the base members overridden or implemented by the symbol at the specific position in the document, /// pushing the results into the context instance. /// - Task FindBasesAsync(Document document, int position, IFindUsagesContext context); + Task FindBasesAsync(Document document, int position, IFindUsagesContext context, CancellationToken cancellationToken); } } diff --git a/src/EditorFeatures/Core/GoToImplementation/GoToImplementationCommandHandler.cs b/src/EditorFeatures/Core/GoToImplementation/GoToImplementationCommandHandler.cs index d1e60b2e4ca19..aa4c44d7a5569 100644 --- a/src/EditorFeatures/Core/GoToImplementation/GoToImplementationCommandHandler.cs +++ b/src/EditorFeatures/Core/GoToImplementation/GoToImplementationCommandHandler.cs @@ -2,10 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System; using System.ComponentModel.Composition; +using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Editor.CommandHandlers; using Microsoft.CodeAnalysis.Editor.Commanding.Commands; @@ -39,7 +38,7 @@ public GoToImplementationCommandHandler( protected override FunctionId FunctionId => FunctionId.CommandHandler_GoToImplementation; - protected override Task FindActionAsync(IFindUsagesService service, Document document, int caretPosition, IFindUsagesContext context) - => service.FindImplementationsAsync(document, caretPosition, context); + protected override Task FindActionAsync(IFindUsagesService service, Document document, int caretPosition, IFindUsagesContext context, CancellationToken cancellationToken) + => service.FindImplementationsAsync(document, caretPosition, context, cancellationToken); } } diff --git a/src/EditorFeatures/Core/Host/IStreamingFindReferencesPresenter.cs b/src/EditorFeatures/Core/Host/IStreamingFindReferencesPresenter.cs index ecbfb2c367b63..54463970c7ef9 100644 --- a/src/EditorFeatures/Core/Host/IStreamingFindReferencesPresenter.cs +++ b/src/EditorFeatures/Core/Host/IStreamingFindReferencesPresenter.cs @@ -34,14 +34,14 @@ internal interface IStreamingFindUsagesPresenter /// items in isolation. /// External cancellation token controlling whether finding shoudl be canceled /// or not. This will be combined with a cancellation token owned by the . - /// Callers should consider to be the source of truth for + /// Callers should consider the cancellation token returned to be the source of truth for /// cancellation from that point on. - FindUsagesContext StartSearch(string title, bool supportsReferences, CancellationToken cancellationToken); + (FindUsagesContext context, CancellationToken cancellationToken) StartSearch(string title, bool supportsReferences, CancellationToken cancellationToken); /// /// Call this method to display the Containing Type, Containing Member, or Kind columns /// - FindUsagesContext StartSearchWithCustomColumns(string title, bool supportsReferences, bool includeContainingTypeAndMemberColumns, bool includeKindColumn, CancellationToken cancellationToken); + (FindUsagesContext context, CancellationToken cancellationToken) StartSearchWithCustomColumns(string title, bool supportsReferences, bool includeContainingTypeAndMemberColumns, bool includeKindColumn, CancellationToken cancellationToken); /// /// Clears all the items from the presenter. @@ -103,15 +103,16 @@ public static async Task TryNavigateToOrPresentItemsAsync( // We have multiple definitions, or we have definitions with multiple locations. Present this to the // user so they can decide where they want to go to. If we cancel this will trigger the context to // cancel as well. - var context = presenter.StartSearch(title, supportsReferences: false, cancellationToken); + var (context, combinedCancellationToken) = presenter.StartSearch(title, supportsReferences: false, cancellationToken); + cancellationToken = combinedCancellationToken; try { foreach (var definition in nonExternalItems) - await context.OnDefinitionFoundAsync(definition).ConfigureAwait(false); + await context.OnDefinitionFoundAsync(definition, cancellationToken).ConfigureAwait(false); } finally { - await context.OnCompletedAsync().ConfigureAwait(false); + await context.OnCompletedAsync(cancellationToken).ConfigureAwait(false); } } diff --git a/src/EditorFeatures/Test/FindReferences/FindReferencesCommandHandlerTests.cs b/src/EditorFeatures/Test/FindReferences/FindReferencesCommandHandlerTests.cs index 349d6236857f4..8d5db6c0bac2a 100644 --- a/src/EditorFeatures/Test/FindReferences/FindReferencesCommandHandlerTests.cs +++ b/src/EditorFeatures/Test/FindReferences/FindReferencesCommandHandlerTests.cs @@ -31,7 +31,7 @@ private class MockFindUsagesContext : FindUsagesContext { public readonly List Result = new List(); - public override ValueTask OnDefinitionFoundAsync(DefinitionItem definition) + public override ValueTask OnDefinitionFoundAsync(DefinitionItem definition, CancellationToken cancellationToken) { lock (Result) { @@ -49,15 +49,15 @@ private class MockStreamingFindUsagesPresenter : IStreamingFindUsagesPresenter public MockStreamingFindUsagesPresenter(FindUsagesContext context) => _context = context; - public FindUsagesContext StartSearch(string title, bool supportsReferences, CancellationToken cancellationToken) - => _context; + public (FindUsagesContext, CancellationToken) StartSearch(string title, bool supportsReferences, CancellationToken cancellationToken) + => (_context, cancellationToken); public void ClearAll() { } - public FindUsagesContext StartSearchWithCustomColumns(string title, bool supportsReferences, bool includeContainingTypeAndMemberColumns, bool includeKindColumn, CancellationToken cancellationToken) - => _context; + public (FindUsagesContext, CancellationToken) StartSearchWithCustomColumns(string title, bool supportsReferences, bool includeContainingTypeAndMemberColumns, bool includeKindColumn, CancellationToken cancellationToken) + => (_context, cancellationToken); } [WpfFact, Trait(Traits.Feature, Traits.Features.FindReferences)] diff --git a/src/EditorFeatures/Test2/FindReferences/FindReferencesCommandHandlerTests.vb b/src/EditorFeatures/Test2/FindReferences/FindReferencesCommandHandlerTests.vb index 79ff246fef36e..1181f6dff4e14 100644 --- a/src/EditorFeatures/Test2/FindReferences/FindReferencesCommandHandlerTests.vb +++ b/src/EditorFeatures/Test2/FindReferences/FindReferencesCommandHandlerTests.vb @@ -73,12 +73,12 @@ class C Public Sub ClearAll() Implements IStreamingFindUsagesPresenter.ClearAll End Sub - Public Function StartSearch(title As String, supportsReferences As Boolean, cancellationToken As CancellationToken) As FindUsagesContext Implements IStreamingFindUsagesPresenter.StartSearch - Return _context + Public Function StartSearch(title As String, supportsReferences As Boolean, cancellationToken As CancellationToken) As (FindUsagesContext, CancellationToken) Implements IStreamingFindUsagesPresenter.StartSearch + Return (_context, cancellationToken) End Function - Public Function StartSearchWithCustomColumns(title As String, supportsReferences As Boolean, includeContainingTypeAndMemberColumns As Boolean, includeKindColumn As Boolean, cancellationToken As CancellationToken) As FindUsagesContext Implements IStreamingFindUsagesPresenter.StartSearchWithCustomColumns - Return _context + Public Function StartSearchWithCustomColumns(title As String, supportsReferences As Boolean, includeContainingTypeAndMemberColumns As Boolean, includeKindColumn As Boolean, cancellationToken As CancellationToken) As (FindUsagesContext, CancellationToken) Implements IStreamingFindUsagesPresenter.StartSearchWithCustomColumns + Return (_context, cancellationToken) End Function End Class End Class diff --git a/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.vb b/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.vb index a844959deb7a0..a8cc26e9efcf4 100644 --- a/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.vb +++ b/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.vb @@ -73,7 +73,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.FindReferences Dim findRefsService = startDocument.GetLanguageService(Of IFindUsagesService) Dim context = New TestContext() - Await findRefsService.FindReferencesAsync(startDocument, cursorPosition, context) + Await findRefsService.FindReferencesAsync(startDocument, cursorPosition, context, CancellationToken.None) Dim expectedDefinitions = workspace.Documents.Where(Function(d) d.AnnotatedSpans.ContainsKey(DefinitionKey) AndAlso d.AnnotatedSpans(DefinitionKey).Any()). @@ -231,7 +231,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.FindReferences Return definition.DisplayIfNoReferences End Function - Public Overrides Function OnDefinitionFoundAsync(definition As DefinitionItem) As ValueTask + Public Overrides Function OnDefinitionFoundAsync(definition As DefinitionItem, cancellationToken As CancellationToken) As ValueTask SyncLock gate Me.Definitions.Add(definition) End SyncLock @@ -239,7 +239,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.FindReferences Return Nothing End Function - Public Overrides Function OnReferenceFoundAsync(reference As SourceReferenceItem) As ValueTask + Public Overrides Function OnReferenceFoundAsync(reference As SourceReferenceItem, cancellationToken As CancellationToken) As ValueTask SyncLock gate References.Add(reference) End SyncLock diff --git a/src/EditorFeatures/Test2/GoToBase/GoToBaseTestsBase.vb b/src/EditorFeatures/Test2/GoToBase/GoToBaseTestsBase.vb index 60215d012da30..22d596ea3da32 100644 --- a/src/EditorFeatures/Test2/GoToBase/GoToBaseTestsBase.vb +++ b/src/EditorFeatures/Test2/GoToBase/GoToBaseTestsBase.vb @@ -2,6 +2,7 @@ ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. +Imports System.Threading Imports Microsoft.CodeAnalysis.Editor.FindUsages Imports Microsoft.CodeAnalysis.Editor.GoToBase Imports Microsoft.CodeAnalysis.Remote.Testing @@ -15,7 +16,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.GoToBase testHost:=TestHost.InProcess, Async Function(document As Document, position As Integer, context As SimpleFindUsagesContext) Dim gotoBaseService = document.GetLanguageService(Of IGoToBaseService) - Await gotoBaseService.FindBasesAsync(document, position, context) + Await gotoBaseService.FindBasesAsync(document, position, context, CancellationToken.None) End Function, shouldSucceed, metadataDefinitions) End Function diff --git a/src/EditorFeatures/Test2/GoToHelpers/GoToHelpers.vb b/src/EditorFeatures/Test2/GoToHelpers/GoToHelpers.vb index 90166dabc1ace..f1eca34f8ca03 100644 --- a/src/EditorFeatures/Test2/GoToHelpers/GoToHelpers.vb +++ b/src/EditorFeatures/Test2/GoToHelpers/GoToHelpers.vb @@ -24,7 +24,7 @@ Friend Class GoToHelpers Dim document = workspace.CurrentSolution.GetDocument(documentWithCursor.Id) - Dim context = New SimpleFindUsagesContext(CancellationToken.None) + Dim context = New SimpleFindUsagesContext() Await testingMethod(document, position, context) If Not shouldSucceed Then diff --git a/src/EditorFeatures/Test2/GoToImplementation/GoToImplementationTests.vb b/src/EditorFeatures/Test2/GoToImplementation/GoToImplementationTests.vb index 9e7dea3f36873..b54ca87c1d00e 100644 --- a/src/EditorFeatures/Test2/GoToImplementation/GoToImplementationTests.vb +++ b/src/EditorFeatures/Test2/GoToImplementation/GoToImplementationTests.vb @@ -4,6 +4,7 @@ Imports Microsoft.CodeAnalysis.Remote.Testing Imports Microsoft.CodeAnalysis.Editor.FindUsages +Imports System.Threading Namespace Microsoft.CodeAnalysis.Editor.UnitTests.GoToImplementation <[UseExportProvider]> @@ -15,7 +16,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.GoToImplementation host, Async Function(document As Document, position As Integer, context As SimpleFindUsagesContext) As Task Dim findUsagesService = document.GetLanguageService(Of IFindUsagesService) - Await findUsagesService.FindImplementationsAsync(document, position, context).ConfigureAwait(False) + Await findUsagesService.FindImplementationsAsync(document, position, context, CancellationToken.None).ConfigureAwait(False) End Function, shouldSucceed) End Function diff --git a/src/EditorFeatures/TestUtilities2/Utilities/GoToHelpers/MockNavigableItemsPresenter.vb b/src/EditorFeatures/TestUtilities2/Utilities/GoToHelpers/MockNavigableItemsPresenter.vb index 64e6eb4019f66..f2f023e7e79fc 100644 --- a/src/EditorFeatures/TestUtilities2/Utilities/GoToHelpers/MockNavigableItemsPresenter.vb +++ b/src/EditorFeatures/TestUtilities2/Utilities/GoToHelpers/MockNavigableItemsPresenter.vb @@ -11,7 +11,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Utilities.GoToHelpers Friend Class MockStreamingFindUsagesPresenter Implements IStreamingFindUsagesPresenter - Public ReadOnly Context As New SimpleFindUsagesContext(CancellationToken.None) + Public ReadOnly Context As New SimpleFindUsagesContext() Private ReadOnly _action As Action Public Sub New(action As Action) @@ -22,13 +22,13 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Utilities.GoToHelpers Throw New NotImplementedException() End Sub - Public Function StartSearch(title As String, alwaysShowDeclarations As Boolean, cancellationToken As CancellationToken) As FindUsagesContext Implements IStreamingFindUsagesPresenter.StartSearch + Public Function StartSearch(title As String, alwaysShowDeclarations As Boolean, cancellationToken As CancellationToken) As (FindUsagesContext, CancellationToken) Implements IStreamingFindUsagesPresenter.StartSearch _action() - Return Context + Return (Context, cancellationToken) End Function - Public Function StartSearchWithCustomColumns(title As String, supportsReferences As Boolean, includeContainingTypeAndMemberColumns As Boolean, includeKindColumn As Boolean, cancellationToken As CancellationToken) As FindUsagesContext Implements IStreamingFindUsagesPresenter.StartSearchWithCustomColumns - Return Context + Public Function StartSearchWithCustomColumns(title As String, supportsReferences As Boolean, includeContainingTypeAndMemberColumns As Boolean, includeKindColumn As Boolean, cancellationToken As CancellationToken) As (FindUsagesContext, CancellationToken) Implements IStreamingFindUsagesPresenter.StartSearchWithCustomColumns + Return (Context, cancellationToken) End Function End Class End Namespace diff --git a/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs b/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs index bed28625e0f5c..80ddbceb3bc97 100644 --- a/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs +++ b/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs @@ -220,10 +220,9 @@ private static async Task> FindChangeSignatureR documents: null, ReferenceFinders.DefaultReferenceFinders.Add(DelegateInvokeMethodReferenceFinder.DelegateInvokeMethod), streamingProgress, - FindReferencesSearchOptions.Default, - cancellationToken); + FindReferencesSearchOptions.Default); - await engine.FindReferencesAsync(symbol).ConfigureAwait(false); + await engine.FindReferencesAsync(symbol, cancellationToken).ConfigureAwait(false); return streamingProgress.GetReferencedSymbols(); } } diff --git a/src/Features/Core/Portable/FindUsages/IFindUsagesContext.cs b/src/Features/Core/Portable/FindUsages/IFindUsagesContext.cs index 2407498402437..8ed5a1b9d18af 100644 --- a/src/Features/Core/Portable/FindUsages/IFindUsagesContext.cs +++ b/src/Features/Core/Portable/FindUsages/IFindUsagesContext.cs @@ -11,19 +11,6 @@ namespace Microsoft.CodeAnalysis.FindUsages { internal interface IFindUsagesContext { - /// - /// acts as a , enabling it to determine - /// when a particular find operation should be cancelled. Once a client creates a - /// it should be considered the source of truth for cancellation. - /// - /// - /// The will generally wrap and represent the host UI component responsible for - /// displaying results to a user. As such, it may expose its own mechanism for cancellation a search (for - /// example, if the user closes the window, or starts another search within it). This property allows clients - /// to observe when that happens so they can cancel their own work. - /// - CancellationToken CancellationToken { get; } - /// /// Used for clients that are finding usages to push information about how far along they /// are in their search. @@ -33,17 +20,17 @@ internal interface IFindUsagesContext /// /// Report a message to be displayed to the user. /// - ValueTask ReportMessageAsync(string message); + ValueTask ReportMessageAsync(string message, CancellationToken cancellationToken); /// /// Set the title of the window that results are displayed in. /// - ValueTask SetSearchTitleAsync(string title); + ValueTask SetSearchTitleAsync(string title, CancellationToken cancellationToken); - ValueTask OnDefinitionFoundAsync(DefinitionItem definition); - ValueTask OnReferenceFoundAsync(SourceReferenceItem reference); + ValueTask OnDefinitionFoundAsync(DefinitionItem definition, CancellationToken cancellationToken); + ValueTask OnReferenceFoundAsync(SourceReferenceItem reference, CancellationToken cancellationToken); [Obsolete("Use ProgressTracker instead", error: false)] - ValueTask ReportProgressAsync(int current, int maximum); + ValueTask ReportProgressAsync(int current, int maximum, CancellationToken cancellationToken); } } diff --git a/src/Features/Core/Portable/FindUsages/IRemoteFindUsagesService.cs b/src/Features/Core/Portable/FindUsages/IRemoteFindUsagesService.cs index 44fef86da77f6..a2720611a4dbd 100644 --- a/src/Features/Core/Portable/FindUsages/IRemoteFindUsagesService.cs +++ b/src/Features/Core/Portable/FindUsages/IRemoteFindUsagesService.cs @@ -12,7 +12,6 @@ using Microsoft.CodeAnalysis.FindSymbols; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Remote; -using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Text; using Roslyn.Utilities; @@ -22,13 +21,13 @@ internal interface IRemoteFindUsagesService { internal interface ICallback { - ValueTask AddItemsAsync(RemoteServiceCallbackId callbackId, int count); - ValueTask ItemCompletedAsync(RemoteServiceCallbackId callbackId); - ValueTask ReportMessageAsync(RemoteServiceCallbackId callbackId, string message); - ValueTask ReportProgressAsync(RemoteServiceCallbackId callbackId, int current, int maximum); - ValueTask SetSearchTitleAsync(RemoteServiceCallbackId callbackId, string title); - ValueTask OnDefinitionFoundAsync(RemoteServiceCallbackId callbackId, SerializableDefinitionItem definition); - ValueTask OnReferenceFoundAsync(RemoteServiceCallbackId callbackId, SerializableSourceReferenceItem reference); + ValueTask AddItemsAsync(RemoteServiceCallbackId callbackId, int count, CancellationToken cancellationToken); + ValueTask ItemCompletedAsync(RemoteServiceCallbackId callbackId, CancellationToken cancellationToken); + ValueTask ReportMessageAsync(RemoteServiceCallbackId callbackId, string message, CancellationToken cancellationToken); + ValueTask ReportProgressAsync(RemoteServiceCallbackId callbackId, int current, int maximum, CancellationToken cancellationToken); + ValueTask SetSearchTitleAsync(RemoteServiceCallbackId callbackId, string title, CancellationToken cancellationToken); + ValueTask OnDefinitionFoundAsync(RemoteServiceCallbackId callbackId, SerializableDefinitionItem definition, CancellationToken cancellationToken); + ValueTask OnReferenceFoundAsync(RemoteServiceCallbackId callbackId, SerializableSourceReferenceItem reference, CancellationToken cancellationToken); } ValueTask FindReferencesAsync( @@ -57,27 +56,27 @@ public FindUsagesServerCallbackDispatcher() private new FindUsagesServerCallback GetCallback(RemoteServiceCallbackId callbackId) => (FindUsagesServerCallback)base.GetCallback(callbackId); - public ValueTask AddItemsAsync(RemoteServiceCallbackId callbackId, int count) - => GetCallback(callbackId).AddItemsAsync(count); + public ValueTask AddItemsAsync(RemoteServiceCallbackId callbackId, int count, CancellationToken cancellationToken) + => GetCallback(callbackId).AddItemsAsync(count, cancellationToken); - public ValueTask ItemCompletedAsync(RemoteServiceCallbackId callbackId) - => GetCallback(callbackId).ItemCompletedAsync(); + public ValueTask ItemCompletedAsync(RemoteServiceCallbackId callbackId, CancellationToken cancellationToken) + => GetCallback(callbackId).ItemCompletedAsync(cancellationToken); - public ValueTask OnDefinitionFoundAsync(RemoteServiceCallbackId callbackId, SerializableDefinitionItem definition) - => GetCallback(callbackId).OnDefinitionFoundAsync(definition); + public ValueTask OnDefinitionFoundAsync(RemoteServiceCallbackId callbackId, SerializableDefinitionItem definition, CancellationToken cancellationToken) + => GetCallback(callbackId).OnDefinitionFoundAsync(definition, cancellationToken); - public ValueTask OnReferenceFoundAsync(RemoteServiceCallbackId callbackId, SerializableSourceReferenceItem reference) - => GetCallback(callbackId).OnReferenceFoundAsync(reference); + public ValueTask OnReferenceFoundAsync(RemoteServiceCallbackId callbackId, SerializableSourceReferenceItem reference, CancellationToken cancellationToken) + => GetCallback(callbackId).OnReferenceFoundAsync(reference, cancellationToken); - public ValueTask ReportMessageAsync(RemoteServiceCallbackId callbackId, string message) - => GetCallback(callbackId).ReportMessageAsync(message); + public ValueTask ReportMessageAsync(RemoteServiceCallbackId callbackId, string message, CancellationToken cancellationToken) + => GetCallback(callbackId).ReportMessageAsync(message, cancellationToken); [Obsolete] - public ValueTask ReportProgressAsync(RemoteServiceCallbackId callbackId, int current, int maximum) - => GetCallback(callbackId).ReportProgressAsync(current, maximum); + public ValueTask ReportProgressAsync(RemoteServiceCallbackId callbackId, int current, int maximum, CancellationToken cancellationToken) + => GetCallback(callbackId).ReportProgressAsync(current, maximum, cancellationToken); - public ValueTask SetSearchTitleAsync(RemoteServiceCallbackId callbackId, string title) - => GetCallback(callbackId).SetSearchTitleAsync(title); + public ValueTask SetSearchTitleAsync(RemoteServiceCallbackId callbackId, string title, CancellationToken cancellationToken) + => GetCallback(callbackId).SetSearchTitleAsync(title, cancellationToken); } internal sealed class FindUsagesServerCallback @@ -92,54 +91,40 @@ public FindUsagesServerCallback(Solution solution, IFindUsagesContext context) _context = context; } - public ValueTask AddItemsAsync(int count) - => _context.ProgressTracker.AddItemsAsync(count); + public ValueTask AddItemsAsync(int count, CancellationToken cancellationToken) + => _context.ProgressTracker.AddItemsAsync(count, cancellationToken); - public ValueTask ItemCompletedAsync() - => _context.ProgressTracker.ItemCompletedAsync(); + public ValueTask ItemCompletedAsync(CancellationToken cancellationToken) + => _context.ProgressTracker.ItemCompletedAsync(cancellationToken); - public ValueTask ReportMessageAsync(string message) - => _context.ReportMessageAsync(message); + public ValueTask ReportMessageAsync(string message, CancellationToken cancellationToken) + => _context.ReportMessageAsync(message, cancellationToken); [Obsolete] - public ValueTask ReportProgressAsync(int current, int maximum) - => _context.ReportProgressAsync(current, maximum); + public ValueTask ReportProgressAsync(int current, int maximum, CancellationToken cancellationToken) + => _context.ReportProgressAsync(current, maximum, cancellationToken); - public ValueTask SetSearchTitleAsync(string title) - => _context.SetSearchTitleAsync(title); + public ValueTask SetSearchTitleAsync(string title, CancellationToken cancellationToken) + => _context.SetSearchTitleAsync(title, cancellationToken); - public async ValueTask OnDefinitionFoundAsync(SerializableDefinitionItem definition) + public async ValueTask OnDefinitionFoundAsync(SerializableDefinitionItem definition, CancellationToken cancellationToken) { - try - { - var id = definition.Id; - var rehydrated = await definition.RehydrateAsync(_solution, _context.CancellationToken).ConfigureAwait(false); - - lock (_idToDefinition) - { - _idToDefinition.Add(id, rehydrated); - } + var id = definition.Id; + var rehydrated = await definition.RehydrateAsync(_solution, cancellationToken).ConfigureAwait(false); - await _context.OnDefinitionFoundAsync(rehydrated).ConfigureAwait(false); - } - catch (OperationCanceledException oce) when (oce.CancellationToken == _context.CancellationToken) + lock (_idToDefinition) { - // Eat the cancellation exception since we're unsure if it's safe to propagate back to the remote side + _idToDefinition.Add(id, rehydrated); } + + await _context.OnDefinitionFoundAsync(rehydrated, cancellationToken).ConfigureAwait(false); } - public async ValueTask OnReferenceFoundAsync(SerializableSourceReferenceItem reference) + public async ValueTask OnReferenceFoundAsync(SerializableSourceReferenceItem reference, CancellationToken cancellationToken) { - try - { - var rehydrated = await reference.RehydrateAsync(_solution, GetDefinition(reference.DefinitionId), _context.CancellationToken).ConfigureAwait(false); + var rehydrated = await reference.RehydrateAsync(_solution, GetDefinition(reference.DefinitionId), cancellationToken).ConfigureAwait(false); - await _context.OnReferenceFoundAsync(rehydrated).ConfigureAwait(false); - } - catch (OperationCanceledException oce) when (oce.CancellationToken == _context.CancellationToken) - { - // Eat the cancellation exception since we're unsure if it's safe to propagate back to the remote side - } + await _context.OnReferenceFoundAsync(rehydrated, cancellationToken).ConfigureAwait(false); } private DefinitionItem GetDefinition(int definitionId) diff --git a/src/Features/Core/Portable/NavigateTo/NavigateToSearcher.cs b/src/Features/Core/Portable/NavigateTo/NavigateToSearcher.cs index 794a44e13f216..94dc92205aa47 100644 --- a/src/Features/Core/Portable/NavigateTo/NavigateToSearcher.cs +++ b/src/Features/Core/Portable/NavigateTo/NavigateToSearcher.cs @@ -49,7 +49,7 @@ private NavigateToSearcher( _searchPattern = searchPattern; _searchCurrentDocument = searchCurrentDocument; _kinds = kinds; - _progress = new StreamingProgressTracker((current, maximum) => + _progress = new StreamingProgressTracker((current, maximum, ct) => { callback.ReportProgress(current, maximum); return new ValueTask(); @@ -228,7 +228,7 @@ private ImmutableArray GetPriorityDocuments(Project project) private async Task<(int itemsReported, ImmutableArray<(Project project, NavigateToSearchLocation location)>)> ProcessProjectsAsync( ImmutableArray> orderedProjects, bool isFullyLoaded, CancellationToken cancellationToken) { - await _progress.AddItemsAsync(orderedProjects.Sum(p => p.Length)).ConfigureAwait(false); + await _progress.AddItemsAsync(orderedProjects.Sum(p => p.Length), cancellationToken).ConfigureAwait(false); using var _ = ArrayBuilder<(Project project, NavigateToSearchLocation location)>.GetInstance(out var result); @@ -249,7 +249,7 @@ private ImmutableArray GetPriorityDocuments(Project project) } finally { - await _progress.ItemCompletedAsync().ConfigureAwait(false); + await _progress.ItemCompletedAsync(cancellationToken).ConfigureAwait(false); } } diff --git a/src/Features/LanguageServer/Protocol/CustomProtocol/FindUsagesLSPContext.cs b/src/Features/LanguageServer/Protocol/CustomProtocol/FindUsagesLSPContext.cs index 736038559acf5..b607e5ca7927c 100644 --- a/src/Features/LanguageServer/Protocol/CustomProtocol/FindUsagesLSPContext.cs +++ b/src/Features/LanguageServer/Protocol/CustomProtocol/FindUsagesLSPContext.cs @@ -67,8 +67,6 @@ internal class FindUsagesLSPContext : FindUsagesContext // Unique identifier given to each definition and reference. private int _id = 0; - public override CancellationToken CancellationToken { get; } - public FindUsagesLSPContext( IProgress progress, Document document, @@ -82,17 +80,15 @@ public FindUsagesLSPContext( _metadataAsSourceFileService = metadataAsSourceFileService; _workQueue = new AsyncBatchingWorkQueue( TimeSpan.FromMilliseconds(500), ReportReferencesAsync, cancellationToken); - - CancellationToken = cancellationToken; } // After all definitions/references have been found, wait here until all results have been reported. - public override async ValueTask OnCompletedAsync() + public override async ValueTask OnCompletedAsync(CancellationToken cancellationToken) => await _workQueue.WaitUntilCurrentBatchCompletesAsync().ConfigureAwait(false); - public override async ValueTask OnDefinitionFoundAsync(DefinitionItem definition) + public override async ValueTask OnDefinitionFoundAsync(DefinitionItem definition, CancellationToken cancellationToken) { - using (await _semaphore.DisposableWaitAsync(CancellationToken).ConfigureAwait(false)) + using (await _semaphore.DisposableWaitAsync(cancellationToken).ConfigureAwait(false)) { if (_definitionToId.ContainsKey(definition)) { @@ -107,7 +103,7 @@ public override async ValueTask OnDefinitionFoundAsync(DefinitionItem definition var definitionItem = await GenerateVSReferenceItemAsync( _id, definitionId: _id, _document, _position, definition.SourceSpans.FirstOrDefault(), definition.DisplayableProperties, _metadataAsSourceFileService, definition.GetClassifiedText(), - definition.Tags.GetFirstGlyph(), symbolUsageInfo: null, isWrittenTo: false, CancellationToken).ConfigureAwait(false); + definition.Tags.GetFirstGlyph(), symbolUsageInfo: null, isWrittenTo: false, cancellationToken).ConfigureAwait(false); if (definitionItem != null) { @@ -125,9 +121,9 @@ public override async ValueTask OnDefinitionFoundAsync(DefinitionItem definition } } - public override async ValueTask OnReferenceFoundAsync(SourceReferenceItem reference) + public override async ValueTask OnReferenceFoundAsync(SourceReferenceItem reference, CancellationToken cancellationToken) { - using (await _semaphore.DisposableWaitAsync(CancellationToken).ConfigureAwait(false)) + using (await _semaphore.DisposableWaitAsync(cancellationToken).ConfigureAwait(false)) { // Each reference should be associated with a definition. If this somehow isn't the // case, we bail out early. @@ -152,7 +148,7 @@ public override async ValueTask OnReferenceFoundAsync(SourceReferenceItem refere var referenceItem = await GenerateVSReferenceItemAsync( _id, definitionId, _document, _position, reference.SourceSpan, reference.AdditionalProperties, _metadataAsSourceFileService, definitionText: null, - definitionGlyph: Glyph.None, reference.SymbolUsageInfo, reference.IsWrittenTo, CancellationToken).ConfigureAwait(false); + definitionGlyph: Glyph.None, reference.SymbolUsageInfo, reference.IsWrittenTo, cancellationToken).ConfigureAwait(false); if (referenceItem != null) { diff --git a/src/Features/LanguageServer/Protocol/Handler/References/FindAllReferencesHandler.cs b/src/Features/LanguageServer/Protocol/Handler/References/FindAllReferencesHandler.cs index c4e93f42cf263..ca9f430599179 100644 --- a/src/Features/LanguageServer/Protocol/Handler/References/FindAllReferencesHandler.cs +++ b/src/Features/LanguageServer/Protocol/Handler/References/FindAllReferencesHandler.cs @@ -57,8 +57,8 @@ public FindAllReferencesHandler(IMetadataAsSourceFileService metadataAsSourceFil progress, document, position, _metadataAsSourceFileService, cancellationToken); // Finds the references for the symbol at the specific position in the document, reporting them via streaming to the LSP client. - await findUsagesService.FindReferencesAsync(document, position, findUsagesContext).ConfigureAwait(false); - await findUsagesContext.OnCompletedAsync().ConfigureAwait(false); + await findUsagesService.FindReferencesAsync(document, position, findUsagesContext, cancellationToken).ConfigureAwait(false); + await findUsagesContext.OnCompletedAsync(cancellationToken).ConfigureAwait(false); return progress.GetValues(); } diff --git a/src/Features/LanguageServer/Protocol/Handler/References/FindImplementationsHandler.cs b/src/Features/LanguageServer/Protocol/Handler/References/FindImplementationsHandler.cs index 0384707de5624..339e5bad2bcce 100644 --- a/src/Features/LanguageServer/Protocol/Handler/References/FindImplementationsHandler.cs +++ b/src/Features/LanguageServer/Protocol/Handler/References/FindImplementationsHandler.cs @@ -42,9 +42,8 @@ public FindImplementationsHandler() var findUsagesService = document.Project.LanguageServices.GetRequiredService(); var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(false); - var findUsagesContext = new SimpleFindUsagesContext(cancellationToken); - - await FindImplementationsAsync(findUsagesService, document, position, findUsagesContext).ConfigureAwait(false); + var findUsagesContext = new SimpleFindUsagesContext(); + await FindImplementationsAsync(findUsagesService, document, position, findUsagesContext, cancellationToken).ConfigureAwait(false); foreach (var definition in findUsagesContext.GetDefinitions()) { @@ -65,7 +64,7 @@ public FindImplementationsHandler() return locations.ToArrayAndFree(); } - protected virtual Task FindImplementationsAsync(IFindUsagesService findUsagesService, Document document, int position, SimpleFindUsagesContext context) - => findUsagesService.FindImplementationsAsync(document, position, context); + protected virtual Task FindImplementationsAsync(IFindUsagesService findUsagesService, Document document, int position, SimpleFindUsagesContext context, CancellationToken cancellationToken) + => findUsagesService.FindImplementationsAsync(document, position, context, cancellationToken); } } diff --git a/src/Tools/ExternalAccess/Debugger/DebuggerFindReferencesService.cs b/src/Tools/ExternalAccess/Debugger/DebuggerFindReferencesService.cs index 5d93f8524a0a4..139e7e47ce0f6 100644 --- a/src/Tools/ExternalAccess/Debugger/DebuggerFindReferencesService.cs +++ b/src/Tools/ExternalAccess/Debugger/DebuggerFindReferencesService.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System; using System.Composition; using System.Threading; @@ -37,15 +35,16 @@ public async Task FindSymbolReferencesAsync(ISymbol symbol, Project project, Can // Let the presenter know we're starting a search. It will give us back // the context object that the FAR service will push results into. - var context = streamingPresenter.StartSearch(EditorFeaturesResources.Find_References, supportsReferences: true, cancellationToken); + var (context, combinedCancellationToken) = streamingPresenter.StartSearch(EditorFeaturesResources.Find_References, supportsReferences: true, cancellationToken); + cancellationToken = combinedCancellationToken; try { - await AbstractFindUsagesService.FindSymbolReferencesAsync(context, symbol, project).ConfigureAwait(false); + await AbstractFindUsagesService.FindSymbolReferencesAsync(context, symbol, project, cancellationToken).ConfigureAwait(false); } finally { - await context.OnCompletedAsync().ConfigureAwait(false); + await context.OnCompletedAsync(cancellationToken).ConfigureAwait(false); } } } diff --git a/src/Tools/ExternalAccess/FSharp/Internal/Editor/FindUsages/FSharpFindUsagesContext.cs b/src/Tools/ExternalAccess/FSharp/Internal/Editor/FindUsages/FSharpFindUsagesContext.cs index 21bc3c80e9ed4..4a173d7f633a4 100644 --- a/src/Tools/ExternalAccess/FSharp/Internal/Editor/FindUsages/FSharpFindUsagesContext.cs +++ b/src/Tools/ExternalAccess/FSharp/Internal/Editor/FindUsages/FSharpFindUsagesContext.cs @@ -14,39 +14,41 @@ namespace Microsoft.CodeAnalysis.ExternalAccess.FSharp.Internal.Editor.FindUsage internal class FSharpFindUsagesContext : IFSharpFindUsagesContext { private readonly IFindUsagesContext _context; + private readonly CancellationToken _cancellationToken; - public FSharpFindUsagesContext(IFindUsagesContext context) + public FSharpFindUsagesContext(IFindUsagesContext context, CancellationToken cancellationToken) { _context = context; + _cancellationToken = cancellationToken; } - public CancellationToken CancellationToken => _context.CancellationToken; + public CancellationToken CancellationToken => _cancellationToken; public Task OnDefinitionFoundAsync(FSharp.FindUsages.FSharpDefinitionItem definition) { - return _context.OnDefinitionFoundAsync(definition.RoslynDefinitionItem).AsTask(); + return _context.OnDefinitionFoundAsync(definition.RoslynDefinitionItem, _cancellationToken).AsTask(); } public Task OnReferenceFoundAsync(FSharp.FindUsages.FSharpSourceReferenceItem reference) { - return _context.OnReferenceFoundAsync(reference.RoslynSourceReferenceItem).AsTask(); + return _context.OnReferenceFoundAsync(reference.RoslynSourceReferenceItem, _cancellationToken).AsTask(); } public Task ReportMessageAsync(string message) { - return _context.ReportMessageAsync(message).AsTask(); + return _context.ReportMessageAsync(message, _cancellationToken).AsTask(); } public Task ReportProgressAsync(int current, int maximum) { #pragma warning disable CS0618 // Type or member is obsolete - return _context.ReportProgressAsync(current, maximum).AsTask(); + return _context.ReportProgressAsync(current, maximum, _cancellationToken).AsTask(); #pragma warning restore CS0618 // Type or member is obsolete } public Task SetSearchTitleAsync(string title) { - return _context.SetSearchTitleAsync(title).AsTask(); + return _context.SetSearchTitleAsync(title, _cancellationToken).AsTask(); } } } diff --git a/src/Tools/ExternalAccess/FSharp/Internal/Editor/FindUsages/FSharpFindUsagesService.cs b/src/Tools/ExternalAccess/FSharp/Internal/Editor/FindUsages/FSharpFindUsagesService.cs index 91396d44f17da..45750ab840013 100644 --- a/src/Tools/ExternalAccess/FSharp/Internal/Editor/FindUsages/FSharpFindUsagesService.cs +++ b/src/Tools/ExternalAccess/FSharp/Internal/Editor/FindUsages/FSharpFindUsagesService.cs @@ -6,6 +6,7 @@ using System; using System.Composition; +using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Editor.FindUsages; using Microsoft.CodeAnalysis.ExternalAccess.FSharp.Editor.FindUsages; @@ -27,14 +28,14 @@ public FSharpFindUsagesService(IFSharpFindUsagesService service) _service = service; } - public Task FindImplementationsAsync(Document document, int position, IFindUsagesContext context) + public Task FindImplementationsAsync(Document document, int position, IFindUsagesContext context, CancellationToken cancellationToken) { - return _service.FindImplementationsAsync(document, position, new FSharpFindUsagesContext(context)); + return _service.FindImplementationsAsync(document, position, new FSharpFindUsagesContext(context, cancellationToken)); } - public Task FindReferencesAsync(Document document, int position, IFindUsagesContext context) + public Task FindReferencesAsync(Document document, int position, IFindUsagesContext context, CancellationToken cancellationToken) { - return _service.FindReferencesAsync(document, position, new FSharpFindUsagesContext(context)); + return _service.FindReferencesAsync(document, position, new FSharpFindUsagesContext(context, cancellationToken)); } } } diff --git a/src/VisualStudio/Core/Def/Implementation/FindReferences/Contexts/AbstractTableDataSourceFindUsagesContext.cs b/src/VisualStudio/Core/Def/Implementation/FindReferences/Contexts/AbstractTableDataSourceFindUsagesContext.cs index 4dc76773b746b..b759009b8ba4e 100644 --- a/src/VisualStudio/Core/Def/Implementation/FindReferences/Contexts/AbstractTableDataSourceFindUsagesContext.cs +++ b/src/VisualStudio/Core/Def/Implementation/FindReferences/Contexts/AbstractTableDataSourceFindUsagesContext.cs @@ -29,7 +29,7 @@ internal partial class StreamingFindUsagesPresenter private abstract class AbstractTableDataSourceFindUsagesContext : FindUsagesContext, ITableDataSource, ITableEntriesSnapshotFactory { - private CancellationTokenSource? _cancellationTokenSource; + public CancellationTokenSource? CancellationTokenSource; private ITableDataSink _tableDataSink; @@ -85,8 +85,6 @@ private abstract class AbstractTableDataSourceFindUsagesContext : #endregion - public sealed override CancellationToken CancellationToken { get; } - protected AbstractTableDataSourceFindUsagesContext( StreamingFindUsagesPresenter presenter, IFindAllReferencesWindow findReferencesWindow, @@ -99,8 +97,7 @@ protected AbstractTableDataSourceFindUsagesContext( // Wrap the passed in CT with our own CTS that we can control cancellation over. This way either our // caller can cancel our work or we can cancel the work. - _cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); - CancellationToken = _cancellationTokenSource.Token; + this.CancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); Presenter = presenter; _findReferencesWindow = findReferencesWindow; @@ -134,7 +131,7 @@ protected AbstractTableDataSourceFindUsagesContext( _progressQueue = new AsyncBatchingWorkQueue<(int current, int maximum)>( TimeSpan.FromMilliseconds(250), this.UpdateTableProgressAsync, - this.CancellationToken); + this.CancellationTokenSource.Token); } private static ImmutableArray SelectCustomColumnsToInclude(ImmutableArray customColumns, bool includeContainingTypeAndMemberColumns, bool includeKindColumn) @@ -228,11 +225,11 @@ private void CancelSearch() Presenter.AssertIsForeground(); // Cancel any in flight find work that is going on. - if (_cancellationTokenSource != null) + if (this.CancellationTokenSource != null) { - _cancellationTokenSource.Cancel(); - _cancellationTokenSource.Dispose(); - _cancellationTokenSource = null; + this.CancellationTokenSource.Cancel(); + this.CancellationTokenSource.Dispose(); + this.CancellationTokenSource = null; } } @@ -289,45 +286,46 @@ public IDisposable Subscribe(ITableDataSink sink) #region FindUsagesContext overrides. - public sealed override ValueTask SetSearchTitleAsync(string title) + public sealed override ValueTask SetSearchTitleAsync(string title, CancellationToken cancellationToken) { // Note: IFindAllReferenceWindow.Title is safe to set from any thread. _findReferencesWindow.Title = title; return default; } - public sealed override async ValueTask OnCompletedAsync() + public sealed override async ValueTask OnCompletedAsync(CancellationToken cancellationToken) { - await OnCompletedAsyncWorkerAsync().ConfigureAwait(false); + await OnCompletedAsyncWorkerAsync(cancellationToken).ConfigureAwait(false); _tableDataSink.IsStable = true; } - protected abstract Task OnCompletedAsyncWorkerAsync(); + protected abstract Task OnCompletedAsyncWorkerAsync(CancellationToken cancellationToken); - public sealed override ValueTask OnDefinitionFoundAsync(DefinitionItem definition) + public sealed override ValueTask OnDefinitionFoundAsync(DefinitionItem definition, CancellationToken cancellationToken) { lock (Gate) { Definitions.Add(definition); } - return OnDefinitionFoundWorkerAsync(definition); + return OnDefinitionFoundWorkerAsync(definition, cancellationToken); } - protected abstract ValueTask OnDefinitionFoundWorkerAsync(DefinitionItem definition); + protected abstract ValueTask OnDefinitionFoundWorkerAsync(DefinitionItem definition, CancellationToken cancellationToken); protected async Task TryCreateDocumentSpanEntryAsync( RoslynDefinitionBucket definitionBucket, DocumentSpan documentSpan, HighlightSpanKind spanKind, SymbolUsageInfo symbolUsageInfo, - ImmutableDictionary additionalProperties) + ImmutableDictionary additionalProperties, + CancellationToken cancellationToken) { - var sourceText = await documentSpan.Document.GetTextAsync(CancellationToken).ConfigureAwait(false); - var (excerptResult, lineText) = await ExcerptAsync(sourceText, documentSpan).ConfigureAwait(false); + var sourceText = await documentSpan.Document.GetTextAsync(cancellationToken).ConfigureAwait(false); + var (excerptResult, lineText) = await ExcerptAsync(sourceText, documentSpan, cancellationToken).ConfigureAwait(false); - var mappedDocumentSpan = await AbstractDocumentSpanEntry.TryMapAndGetFirstAsync(documentSpan, sourceText, CancellationToken).ConfigureAwait(false); + var mappedDocumentSpan = await AbstractDocumentSpanEntry.TryMapAndGetFirstAsync(documentSpan, sourceText, cancellationToken).ConfigureAwait(false); if (mappedDocumentSpan == null) { // this will be removed from the result @@ -346,19 +344,20 @@ public sealed override ValueTask OnDefinitionFoundAsync(DefinitionItem definitio additionalProperties); } - private async Task<(ExcerptResult, SourceText)> ExcerptAsync(SourceText sourceText, DocumentSpan documentSpan) + private async Task<(ExcerptResult, SourceText)> ExcerptAsync( + SourceText sourceText, DocumentSpan documentSpan, CancellationToken cancellationToken) { var excerptService = documentSpan.Document.Services.GetService(); if (excerptService != null) { - var result = await excerptService.TryExcerptAsync(documentSpan.Document, documentSpan.SourceSpan, ExcerptMode.SingleLine, CancellationToken).ConfigureAwait(false); + var result = await excerptService.TryExcerptAsync(documentSpan.Document, documentSpan.SourceSpan, ExcerptMode.SingleLine, cancellationToken).ConfigureAwait(false); if (result != null) { return (result.Value, AbstractDocumentSpanEntry.GetLineContainingPosition(result.Value.Content, result.Value.MappedSpan.Start)); } } - var classificationResult = await ClassifiedSpansAndHighlightSpanFactory.ClassifyAsync(documentSpan, CancellationToken).ConfigureAwait(false); + var classificationResult = await ClassifiedSpansAndHighlightSpanFactory.ClassifyAsync(documentSpan, cancellationToken).ConfigureAwait(false); // need to fix the span issue tracking here - https://github.com/dotnet/roslyn/issues/31001 var excerptResult = new ExcerptResult( @@ -371,10 +370,10 @@ public sealed override ValueTask OnDefinitionFoundAsync(DefinitionItem definitio return (excerptResult, AbstractDocumentSpanEntry.GetLineContainingPosition(sourceText, documentSpan.SourceSpan.Start)); } - public sealed override ValueTask OnReferenceFoundAsync(SourceReferenceItem reference) - => OnReferenceFoundWorkerAsync(reference); + public sealed override ValueTask OnReferenceFoundAsync(SourceReferenceItem reference, CancellationToken cancellationToken) + => OnReferenceFoundWorkerAsync(reference, cancellationToken); - protected abstract ValueTask OnReferenceFoundWorkerAsync(SourceReferenceItem reference); + protected abstract ValueTask OnReferenceFoundWorkerAsync(SourceReferenceItem reference, CancellationToken cancellationToken); protected RoslynDefinitionBucket GetOrCreateDefinitionBucket(DefinitionItem definition, bool expandedByDefault) { @@ -390,10 +389,10 @@ protected RoslynDefinitionBucket GetOrCreateDefinitionBucket(DefinitionItem defi } } - public sealed override ValueTask ReportMessageAsync(string message) + public sealed override ValueTask ReportMessageAsync(string message, CancellationToken cancellationToken) => throw new InvalidOperationException("This should never be called in the streaming case."); - protected sealed override ValueTask ReportProgressAsync(int current, int maximum) + protected sealed override ValueTask ReportProgressAsync(int current, int maximum, CancellationToken cancellationToken) { _progressQueue.AddWork((current, maximum)); return default; diff --git a/src/VisualStudio/Core/Def/Implementation/FindReferences/Contexts/WithReferencesFindUsagesContext.cs b/src/VisualStudio/Core/Def/Implementation/FindReferences/Contexts/WithReferencesFindUsagesContext.cs index c8223b3778fe8..4ef1c8907417e 100644 --- a/src/VisualStudio/Core/Def/Implementation/FindReferences/Contexts/WithReferencesFindUsagesContext.cs +++ b/src/VisualStudio/Core/Def/Implementation/FindReferences/Contexts/WithReferencesFindUsagesContext.cs @@ -39,18 +39,18 @@ public WithReferencesFindUsagesContext( { } - protected override async ValueTask OnDefinitionFoundWorkerAsync(DefinitionItem definition) + protected override async ValueTask OnDefinitionFoundWorkerAsync(DefinitionItem definition, CancellationToken cancellationToken) { // If this is a definition we always want to show, then create entries for all the declaration locations // immediately. Otherwise, we'll create them on demand when we hear about references for this // definition. if (definition.DisplayIfNoReferences) - await AddDeclarationEntriesAsync(definition, expandedByDefault: true).ConfigureAwait(false); + await AddDeclarationEntriesAsync(definition, expandedByDefault: true, cancellationToken).ConfigureAwait(false); } - private async Task AddDeclarationEntriesAsync(DefinitionItem definition, bool expandedByDefault) + private async Task AddDeclarationEntriesAsync(DefinitionItem definition, bool expandedByDefault, CancellationToken cancellationToken) { - CancellationToken.ThrowIfCancellationRequested(); + cancellationToken.ThrowIfCancellationRequested(); // Don't do anything if we already have declaration entries for this definition // (i.e. another thread beat us to this). @@ -81,7 +81,8 @@ private async Task AddDeclarationEntriesAsync(DefinitionItem definition, bool ex continue; var definitionEntry = await TryCreateDocumentSpanEntryAsync( - definitionBucket, declarationLocation, HighlightSpanKind.Definition, SymbolUsageInfo.None, additionalProperties: definition.DisplayableProperties).ConfigureAwait(false); + definitionBucket, declarationLocation, HighlightSpanKind.Definition, SymbolUsageInfo.None, + additionalProperties: definition.DisplayableProperties, cancellationToken).ConfigureAwait(false); declarations.AddIfNotNull(definitionEntry); } @@ -115,7 +116,7 @@ private bool HasDeclarationEntries(DefinitionItem definition) } } - protected override ValueTask OnReferenceFoundWorkerAsync(SourceReferenceItem reference) + protected override ValueTask OnReferenceFoundWorkerAsync(SourceReferenceItem reference, CancellationToken cancellationToken) { // Normal references go into both sets of entries. We ensure an entry for the definition, and an entry // for the reference itself. @@ -125,9 +126,12 @@ protected override ValueTask OnReferenceFoundWorkerAsync(SourceReferenceItem ref bucket, reference.SourceSpan, reference.IsWrittenTo ? HighlightSpanKind.WrittenReference : HighlightSpanKind.Reference, reference.SymbolUsageInfo, - reference.AdditionalProperties), + reference.AdditionalProperties, + cancellationToken), addToEntriesWhenGroupingByDefinition: true, - addToEntriesWhenNotGroupingByDefinition: true); + addToEntriesWhenNotGroupingByDefinition: true, + expandedByDefault: true, + cancellationToken); } private async ValueTask OnEntryFoundAsync( @@ -135,16 +139,17 @@ private async ValueTask OnEntryFoundAsync( Func> createEntryAsync, bool addToEntriesWhenGroupingByDefinition, bool addToEntriesWhenNotGroupingByDefinition, - bool expandedByDefault = true) + bool expandedByDefault, + CancellationToken cancellationToken) { Debug.Assert(addToEntriesWhenGroupingByDefinition || addToEntriesWhenNotGroupingByDefinition); - CancellationToken.ThrowIfCancellationRequested(); + cancellationToken.ThrowIfCancellationRequested(); // OK, we got a *reference* to some definition item. This may have been a reference for some definition // that we haven't created any declaration entries for (i.e. because it had DisplayIfNoReferences = // false). Because we've now found a reference, we want to make sure all its declaration entries are // added. - await AddDeclarationEntriesAsync(definition, expandedByDefault).ConfigureAwait(false); + await AddDeclarationEntriesAsync(definition, expandedByDefault, cancellationToken).ConfigureAwait(false); // First find the bucket corresponding to our definition. var definitionBucket = GetOrCreateDefinitionBucket(definition, expandedByDefault); @@ -172,22 +177,22 @@ private async ValueTask OnEntryFoundAsync( NotifyChange(); } - protected override async Task OnCompletedAsyncWorkerAsync() + protected override async Task OnCompletedAsyncWorkerAsync(CancellationToken cancellationToken) { // Now that we know the search is over, create and display any error messages // for definitions that were not found. - await CreateMissingReferenceEntriesIfNecessaryAsync().ConfigureAwait(false); - await CreateNoResultsFoundEntryIfNecessaryAsync().ConfigureAwait(false); + await CreateMissingReferenceEntriesIfNecessaryAsync(cancellationToken).ConfigureAwait(false); + await CreateNoResultsFoundEntryIfNecessaryAsync(cancellationToken).ConfigureAwait(false); } - private async Task CreateMissingReferenceEntriesIfNecessaryAsync() + private async Task CreateMissingReferenceEntriesIfNecessaryAsync(CancellationToken cancellationToken) { - await CreateMissingReferenceEntriesIfNecessaryAsync(whenGroupingByDefinition: true).ConfigureAwait(false); - await CreateMissingReferenceEntriesIfNecessaryAsync(whenGroupingByDefinition: false).ConfigureAwait(false); + await CreateMissingReferenceEntriesIfNecessaryAsync(whenGroupingByDefinition: true, cancellationToken).ConfigureAwait(false); + await CreateMissingReferenceEntriesIfNecessaryAsync(whenGroupingByDefinition: false, cancellationToken).ConfigureAwait(false); } private async Task CreateMissingReferenceEntriesIfNecessaryAsync( - bool whenGroupingByDefinition) + bool whenGroupingByDefinition, CancellationToken cancellationToken) { // Go through and add dummy entries for any definitions that // that we didn't find any references for. @@ -200,7 +205,9 @@ private async Task CreateMissingReferenceEntriesIfNecessaryAsync( await OnEntryFoundAsync(definition, bucket => SimpleMessageEntry.CreateAsync(bucket, bucket, ServicesVSResources.External_reference_found)!, addToEntriesWhenGroupingByDefinition: whenGroupingByDefinition, - addToEntriesWhenNotGroupingByDefinition: !whenGroupingByDefinition).ConfigureAwait(false); + addToEntriesWhenNotGroupingByDefinition: !whenGroupingByDefinition, + expandedByDefault: true, + cancellationToken).ConfigureAwait(false); } else { @@ -215,7 +222,8 @@ await OnEntryFoundAsync(SymbolsWithoutReferencesDefinitionItem, string.Format(ServicesVSResources.No_references_found_to_0, definition.NameDisplayParts.JoinText()))!, addToEntriesWhenGroupingByDefinition: whenGroupingByDefinition, addToEntriesWhenNotGroupingByDefinition: !whenGroupingByDefinition, - expandedByDefault: false).ConfigureAwait(false); + expandedByDefault: false, + cancellationToken).ConfigureAwait(false); } } } @@ -258,7 +266,7 @@ private ImmutableArray GetDefinitionsToCreateMissingReferenceIte } } - private async Task CreateNoResultsFoundEntryIfNecessaryAsync() + private async Task CreateNoResultsFoundEntryIfNecessaryAsync(CancellationToken cancellationToken) { bool noDefinitions; lock (Gate) @@ -272,7 +280,9 @@ private async Task CreateNoResultsFoundEntryIfNecessaryAsync() await OnEntryFoundAsync(NoResultsDefinitionItem, bucket => SimpleMessageEntry.CreateAsync(bucket, null, ServicesVSResources.Search_found_no_results)!, addToEntriesWhenGroupingByDefinition: true, - addToEntriesWhenNotGroupingByDefinition: true).ConfigureAwait(false); + addToEntriesWhenNotGroupingByDefinition: true, + expandedByDefault: true, + cancellationToken).ConfigureAwait(false); } } diff --git a/src/VisualStudio/Core/Def/Implementation/FindReferences/Contexts/WithoutReferencesFindUsagesContext.cs b/src/VisualStudio/Core/Def/Implementation/FindReferences/Contexts/WithoutReferencesFindUsagesContext.cs index cadbe4c513b33..777c6bebfe26f 100644 --- a/src/VisualStudio/Core/Def/Implementation/FindReferences/Contexts/WithoutReferencesFindUsagesContext.cs +++ b/src/VisualStudio/Core/Def/Implementation/FindReferences/Contexts/WithoutReferencesFindUsagesContext.cs @@ -36,14 +36,14 @@ public WithoutReferencesFindUsagesContext( } // We should never be called in a context where we get references. - protected override ValueTask OnReferenceFoundWorkerAsync(SourceReferenceItem reference) + protected override ValueTask OnReferenceFoundWorkerAsync(SourceReferenceItem reference, CancellationToken cancellationToken) => throw new InvalidOperationException(); // Nothing to do on completion. - protected override Task OnCompletedAsyncWorkerAsync() + protected override Task OnCompletedAsyncWorkerAsync(CancellationToken cancellationToken) => Task.CompletedTask; - protected override async ValueTask OnDefinitionFoundWorkerAsync(DefinitionItem definition) + protected override async ValueTask OnDefinitionFoundWorkerAsync(DefinitionItem definition, CancellationToken cancellationToken) { var definitionBucket = GetOrCreateDefinitionBucket(definition, expandedByDefault: true); @@ -55,7 +55,7 @@ protected override async ValueTask OnDefinitionFoundWorkerAsync(DefinitionItem d // definition as what to show. That way we show enough information for things // methods. i.e. we'll show "void TypeName.MethodName(args...)" allowing // the user to see the type the method was created in. - var entry = await TryCreateEntryAsync(definitionBucket, definition).ConfigureAwait(false); + var entry = await TryCreateEntryAsync(definitionBucket, definition, cancellationToken).ConfigureAwait(false); entries.AddIfNotNull(entry); } else if (definition.SourceSpans.Length == 0) @@ -77,8 +77,8 @@ protected override async ValueTask OnDefinitionFoundWorkerAsync(DefinitionItem d sourceSpan, HighlightSpanKind.Definition, symbolUsageInfo: SymbolUsageInfo.None, - additionalProperties: definition.DisplayableProperties) - .ConfigureAwait(false); + additionalProperties: definition.DisplayableProperties, + cancellationToken).ConfigureAwait(false); entries.AddIfNotNull(entry); } } @@ -96,14 +96,14 @@ protected override async ValueTask OnDefinitionFoundWorkerAsync(DefinitionItem d } private async Task TryCreateEntryAsync( - RoslynDefinitionBucket definitionBucket, DefinitionItem definition) + RoslynDefinitionBucket definitionBucket, DefinitionItem definition, CancellationToken cancellationToken) { var documentSpan = definition.SourceSpans[0]; var (guid, projectName, _) = GetGuidAndProjectInfo(documentSpan.Document); - var sourceText = await documentSpan.Document.GetTextAsync(CancellationToken).ConfigureAwait(false); + var sourceText = await documentSpan.Document.GetTextAsync(cancellationToken).ConfigureAwait(false); var lineText = AbstractDocumentSpanEntry.GetLineContainingPosition(sourceText, documentSpan.SourceSpan.Start); - var mappedDocumentSpan = await AbstractDocumentSpanEntry.TryMapAndGetFirstAsync(documentSpan, sourceText, CancellationToken).ConfigureAwait(false); + var mappedDocumentSpan = await AbstractDocumentSpanEntry.TryMapAndGetFirstAsync(documentSpan, sourceText, cancellationToken).ConfigureAwait(false); if (mappedDocumentSpan == null) { // this will be removed from the result diff --git a/src/VisualStudio/Core/Def/Implementation/FindReferences/StreamingFindUsagesPresenter.cs b/src/VisualStudio/Core/Def/Implementation/FindReferences/StreamingFindUsagesPresenter.cs index 78ac1d6adacc2..2ca4a1e1b77a5 100644 --- a/src/VisualStudio/Core/Def/Implementation/FindReferences/StreamingFindUsagesPresenter.cs +++ b/src/VisualStudio/Core/Def/Implementation/FindReferences/StreamingFindUsagesPresenter.cs @@ -137,7 +137,7 @@ public void ClearAll() /// /// /// - public FindUsagesContext StartSearch(string title, bool supportsReferences, CancellationToken cancellationToken) + public (FindUsagesContext context, CancellationToken cancellationToken) StartSearch(string title, bool supportsReferences, CancellationToken cancellationToken) { this.AssertIsForeground(); var context = StartSearchWorker(title, supportsReferences, includeContainingTypeAndMemberColumns: false, includeKindColumn: false, cancellationToken); @@ -147,13 +147,13 @@ public FindUsagesContext StartSearch(string title, bool supportsReferences, Canc // no longer being displayed, VS will dispose it and it will remove itself from // this set. _currentContexts.Add(context); - return context; + return (context, context.CancellationTokenSource!.Token); } /// /// Start a search that may include Containing Type, Containing Member, or Kind information about the reference /// - public FindUsagesContext StartSearchWithCustomColumns( + public (FindUsagesContext context, CancellationToken cancellationToken) StartSearchWithCustomColumns( string title, bool supportsReferences, bool includeContainingTypeAndMemberColumns, bool includeKindColumn, CancellationToken cancellationToken) { this.AssertIsForeground(); @@ -164,7 +164,7 @@ public FindUsagesContext StartSearchWithCustomColumns( // no longer being displayed, VS will dispose it and it will remove itself from // this set. _currentContexts.Add(context); - return context; + return (context, context.CancellationTokenSource!.Token); } private AbstractTableDataSourceFindUsagesContext StartSearchWorker( diff --git a/src/VisualStudio/Core/Def/Implementation/Library/ObjectBrowser/AbstractObjectBrowserLibraryManager.cs b/src/VisualStudio/Core/Def/Implementation/Library/ObjectBrowser/AbstractObjectBrowserLibraryManager.cs index 55957c105f082..2e3206698e2d2 100644 --- a/src/VisualStudio/Core/Def/Implementation/Library/ObjectBrowser/AbstractObjectBrowserLibraryManager.cs +++ b/src/VisualStudio/Core/Def/Implementation/Library/ObjectBrowser/AbstractObjectBrowserLibraryManager.cs @@ -512,7 +512,8 @@ private async Task FindReferencesAsync( { // Let the presented know we're starting a search. It will give us back the context object that the FAR // service will push results into. - var context = presenter.StartSearch(EditorFeaturesResources.Find_References, supportsReferences: true, cancellationToken); + var (context, combinedCancellationToken) = presenter.StartSearch(EditorFeaturesResources.Find_References, supportsReferences: true, cancellationToken); + cancellationToken = combinedCancellationToken; try { @@ -521,12 +522,12 @@ private async Task FindReferencesAsync( // thread. await Task.Run(async () => { - await FindReferencesAsync(symbolListItem, project, context).ConfigureAwait(false); + await FindReferencesAsync(symbolListItem, project, context, cancellationToken).ConfigureAwait(false); }, cancellationToken).ConfigureAwait(false); } finally { - await context.OnCompletedAsync().ConfigureAwait(false); + await context.OnCompletedAsync(cancellationToken).ConfigureAwait(false); } } catch (OperationCanceledException) @@ -537,12 +538,14 @@ await Task.Run(async () => } } - private static async Task FindReferencesAsync(SymbolListItem symbolListItem, Project project, CodeAnalysis.FindUsages.FindUsagesContext context) + private static async Task FindReferencesAsync( + SymbolListItem symbolListItem, Project project, + CodeAnalysis.FindUsages.FindUsagesContext context, CancellationToken cancellationToken) { - var compilation = await project.GetCompilationAsync(context.CancellationToken).ConfigureAwait(false); + var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); var symbol = symbolListItem.ResolveSymbol(compilation); if (symbol != null) - await AbstractFindUsagesService.FindSymbolReferencesAsync(context, symbol, project).ConfigureAwait(false); + await AbstractFindUsagesService.FindSymbolReferencesAsync(context, symbol, project, cancellationToken).ConfigureAwait(false); } } } diff --git a/src/VisualStudio/Core/Test/Venus/DocumentService_IntegrationTests.vb b/src/VisualStudio/Core/Test/Venus/DocumentService_IntegrationTests.vb index 1da2f3c125d4a..aec61a680953a 100644 --- a/src/VisualStudio/Core/Test/Venus/DocumentService_IntegrationTests.vb +++ b/src/VisualStudio/Core/Test/Venus/DocumentService_IntegrationTests.vb @@ -67,7 +67,8 @@ class {|Definition:C1|} Using workspace = TestWorkspace.Create(input, composition:=composition, documentServiceProvider:=TestDocumentServiceProvider.Instance) Dim presenter = New StreamingFindUsagesPresenter(workspace, workspace.ExportProvider.AsExportProvider()) - Dim context = presenter.StartSearch("test", supportsReferences:=True, CancellationToken.None) + Dim tuple = presenter.StartSearch("test", supportsReferences:=True, CancellationToken.None) + Dim context = tuple.context Dim cursorDocument = workspace.Documents.First(Function(d) d.CursorPosition.HasValue) Dim cursorPosition = cursorDocument.CursorPosition.Value @@ -76,7 +77,7 @@ class {|Definition:C1|} Assert.NotNull(startDocument) Dim findRefsService = startDocument.GetLanguageService(Of IFindUsagesService) - Await findRefsService.FindReferencesAsync(startDocument, cursorPosition, context) + Await findRefsService.FindReferencesAsync(startDocument, cursorPosition, context, CancellationToken.None) Dim definitionDocument = workspace.Documents.First(Function(d) d.AnnotatedSpans.ContainsKey("Definition")) Dim definitionText = Await workspace.CurrentSolution.GetDocument(definitionDocument.Id).GetTextAsync() diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindLiterals/FindLiteralsSearchEngine.cs b/src/Workspaces/Core/Portable/FindSymbols/FindLiterals/FindLiteralsSearchEngine.cs index 86eae129a52ca..e306f901565b7 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindLiterals/FindLiteralsSearchEngine.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindLiterals/FindLiteralsSearchEngine.cs @@ -29,7 +29,6 @@ private enum SearchKind private readonly Solution _solution; private readonly IStreamingFindLiteralReferencesProgress _progress; private readonly IStreamingProgressTracker _progressTracker; - private readonly CancellationToken _cancellationToken; private readonly object _value; private readonly string _stringValue; @@ -38,14 +37,12 @@ private enum SearchKind public FindLiteralsSearchEngine( Solution solution, - IStreamingFindLiteralReferencesProgress progress, object value, - CancellationToken cancellationToken) + IStreamingFindLiteralReferencesProgress progress, object value) { _solution = solution; _progress = progress; _progressTracker = progress.ProgressTracker; _value = value; - _cancellationToken = cancellationToken; switch (value) { @@ -75,89 +72,90 @@ public FindLiteralsSearchEngine( } } - public async Task FindReferencesAsync() + public async Task FindReferencesAsync(CancellationToken cancellationToken) { - await using var _ = await _progressTracker.AddSingleItemAsync().ConfigureAwait(false); + await using var _ = await _progressTracker.AddSingleItemAsync(cancellationToken).ConfigureAwait(false); if (_searchKind != SearchKind.None) { - await FindReferencesWorkerAsync().ConfigureAwait(false); + await FindReferencesWorkerAsync(cancellationToken).ConfigureAwait(false); } } - private async Task FindReferencesWorkerAsync() + private async Task FindReferencesWorkerAsync(CancellationToken cancellationToken) { var count = _solution.Projects.SelectMany(p => p.DocumentIds).Count(); - await _progressTracker.AddItemsAsync(count).ConfigureAwait(false); + await _progressTracker.AddItemsAsync(count, cancellationToken).ConfigureAwait(false); foreach (var project in _solution.Projects) { - _cancellationToken.ThrowIfCancellationRequested(); + cancellationToken.ThrowIfCancellationRequested(); var documentTasks = new List(); - foreach (var document in await project.GetAllRegularAndSourceGeneratedDocumentsAsync(_cancellationToken).ConfigureAwait(false)) + foreach (var document in await project.GetAllRegularAndSourceGeneratedDocumentsAsync(cancellationToken).ConfigureAwait(false)) { - documentTasks.Add(ProcessDocumentAsync(document)); + documentTasks.Add(ProcessDocumentAsync(document, cancellationToken)); } await Task.WhenAll(documentTasks).ConfigureAwait(false); } } - private async Task ProcessDocumentAsync(Document document) + private async Task ProcessDocumentAsync(Document document, CancellationToken cancellationToken) { try { - await ProcessDocumentWorkerAsync(document).ConfigureAwait(false); + await ProcessDocumentWorkerAsync(document, cancellationToken).ConfigureAwait(false); } finally { - await _progressTracker.ItemCompletedAsync().ConfigureAwait(false); + await _progressTracker.ItemCompletedAsync(cancellationToken).ConfigureAwait(false); } } - private async Task ProcessDocumentWorkerAsync(Document document) + private async Task ProcessDocumentWorkerAsync(Document document, CancellationToken cancellationToken) { var index = await SyntaxTreeIndex.GetIndexAsync( - document, _cancellationToken).ConfigureAwait(false); + document, cancellationToken).ConfigureAwait(false); if (_searchKind == SearchKind.StringLiterals) { if (index.ProbablyContainsStringValue(_stringValue)) { - await SearchDocumentAsync(document).ConfigureAwait(false); + await SearchDocumentAsync(document, cancellationToken).ConfigureAwait(false); } } else if (index.ProbablyContainsInt64Value(_longValue)) { - await SearchDocumentAsync(document).ConfigureAwait(false); + await SearchDocumentAsync(document, cancellationToken).ConfigureAwait(false); } } - private async Task SearchDocumentAsync(Document document) + private async Task SearchDocumentAsync(Document document, CancellationToken cancellationToken) { - _cancellationToken.ThrowIfCancellationRequested(); + cancellationToken.ThrowIfCancellationRequested(); var syntaxFacts = document.GetLanguageService(); - var root = await document.GetSyntaxRootAsync(_cancellationToken).ConfigureAwait(false); + var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var matches = ArrayBuilder.GetInstance(); - ProcessNode(syntaxFacts, root, matches); + ProcessNode(syntaxFacts, root, matches, cancellationToken); foreach (var token in matches) { - await _progress.OnReferenceFoundAsync(document, token.Span).ConfigureAwait(false); + await _progress.OnReferenceFoundAsync(document, token.Span, cancellationToken).ConfigureAwait(false); } } private void ProcessNode( - ISyntaxFactsService syntaxFacts, SyntaxNode node, ArrayBuilder matches) + ISyntaxFactsService syntaxFacts, SyntaxNode node, + ArrayBuilder matches, CancellationToken cancellationToken) { - _cancellationToken.ThrowIfCancellationRequested(); + cancellationToken.ThrowIfCancellationRequested(); foreach (var child in node.ChildNodesAndTokens()) { if (child.IsNode) { - ProcessNode(syntaxFacts, child.AsNode(), matches); + ProcessNode(syntaxFacts, child.AsNode(), matches, cancellationToken); } else { diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine.cs index 819023d8c780f..69f4306df840d 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine.cs @@ -2,7 +2,6 @@ // 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.Diagnostics; @@ -26,7 +25,6 @@ internal partial class FindReferencesSearchEngine private readonly ImmutableArray _finders; private readonly IStreamingProgressTracker _progressTracker; private readonly IStreamingFindReferencesProgress _progress; - private readonly CancellationToken _cancellationToken; private readonly FindReferencesSearchOptions _options; /// @@ -41,14 +39,12 @@ public FindReferencesSearchEngine( IImmutableSet? documents, ImmutableArray finders, IStreamingFindReferencesProgress progress, - FindReferencesSearchOptions options, - CancellationToken cancellationToken) + FindReferencesSearchOptions options) { _documents = documents; _solution = solution; _finders = finders; _progress = progress; - _cancellationToken = cancellationToken; _options = options; _progressTracker = progress.ProgressTracker; @@ -60,31 +56,32 @@ public FindReferencesSearchEngine( _scheduler = _options.Explicit ? TaskScheduler.Default : s_exclusiveScheduler; } - public async Task FindReferencesAsync(ISymbol symbol) + public async Task FindReferencesAsync(ISymbol symbol, CancellationToken cancellationToken) { - await _progress.OnStartedAsync().ConfigureAwait(false); + await _progress.OnStartedAsync(cancellationToken).ConfigureAwait(false); try { - await using var _ = await _progressTracker.AddSingleItemAsync().ConfigureAwait(false); + await using var _ = await _progressTracker.AddSingleItemAsync(cancellationToken).ConfigureAwait(false); // For the starting symbol, always cascade up and down the inheritance hierarchy. - var symbols = await DetermineAllSymbolsAsync(symbol, FindReferencesCascadeDirection.UpAndDown).ConfigureAwait(false); + var symbols = await DetermineAllSymbolsAsync( + symbol, FindReferencesCascadeDirection.UpAndDown, cancellationToken).ConfigureAwait(false); - var projectMap = await CreateProjectMapAsync(symbols).ConfigureAwait(false); - var projectToDocumentMap = await CreateProjectToDocumentMapAsync(projectMap).ConfigureAwait(false); + var projectMap = await CreateProjectMapAsync(symbols, cancellationToken).ConfigureAwait(false); + var projectToDocumentMap = await CreateProjectToDocumentMapAsync(projectMap, cancellationToken).ConfigureAwait(false); ValidateProjectToDocumentMap(projectToDocumentMap); - await ProcessAsync(projectToDocumentMap).ConfigureAwait(false); + await ProcessAsync(projectToDocumentMap, cancellationToken).ConfigureAwait(false); } finally { - await _progress.OnCompletedAsync().ConfigureAwait(false); + await _progress.OnCompletedAsync(cancellationToken).ConfigureAwait(false); } } - private async Task ProcessAsync(ProjectToDocumentMap projectToDocumentMap) + private async Task ProcessAsync(ProjectToDocumentMap projectToDocumentMap, CancellationToken cancellationToken) { - using (Logger.LogBlock(FunctionId.FindReference_ProcessAsync, _cancellationToken)) + using (Logger.LogBlock(FunctionId.FindReference_ProcessAsync, cancellationToken)) { // quick exit if (projectToDocumentMap.Count == 0) @@ -96,12 +93,12 @@ private async Task ProcessAsync(ProjectToDocumentMap projectToDocumentMap) // We'll mark the item as completed in "ProcessDocumentAsync". var totalFindCount = projectToDocumentMap.Sum( kvp1 => kvp1.Value.Sum(kvp2 => kvp2.Value.Count)); - await _progressTracker.AddItemsAsync(totalFindCount).ConfigureAwait(false); + await _progressTracker.AddItemsAsync(totalFindCount, cancellationToken).ConfigureAwait(false); using var _ = ArrayBuilder.GetInstance(out var tasks); foreach (var (project, documentMap) in projectToDocumentMap) - tasks.Add(Task.Factory.StartNew(() => ProcessProjectAsync(project, documentMap), _cancellationToken, TaskCreationOptions.None, _scheduler).Unwrap()); + tasks.Add(Task.Factory.StartNew(() => ProcessProjectAsync(project, documentMap, cancellationToken), cancellationToken, TaskCreationOptions.None, _scheduler).Unwrap()); await Task.WhenAll(tasks).ConfigureAwait(false); } @@ -125,7 +122,7 @@ private static void ValidateProjectToDocumentMap( } } - private ValueTask HandleLocationAsync(SymbolGroup group, ISymbol symbol, ReferenceLocation location) - => _progress.OnReferenceFoundAsync(group, symbol, location); + private ValueTask HandleLocationAsync(SymbolGroup group, ISymbol symbol, ReferenceLocation location, CancellationToken cancellationToken) + => _progress.OnReferenceFoundAsync(group, symbol, location, cancellationToken); } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_DocumentProcessing.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_DocumentProcessing.cs index fe5a3e7ed4d4c..9ea4179095976 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_DocumentProcessing.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_DocumentProcessing.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.FindSymbols.Finders; using Microsoft.CodeAnalysis.Internal.Log; @@ -15,26 +16,27 @@ internal partial class FindReferencesSearchEngine { private async Task ProcessDocumentQueueAsync( Document document, - HashSet<(SymbolGroup group, ISymbol symbol, IReferenceFinder finder)> documentQueue) + HashSet<(SymbolGroup group, ISymbol symbol, IReferenceFinder finder)> documentQueue, + CancellationToken cancellationToken) { - await _progress.OnFindInDocumentStartedAsync(document).ConfigureAwait(false); + await _progress.OnFindInDocumentStartedAsync(document, cancellationToken).ConfigureAwait(false); SemanticModel? model = null; try { - model = await document.GetRequiredSemanticModelAsync(_cancellationToken).ConfigureAwait(false); + model = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); // start cache for this semantic model FindReferenceCache.Start(model); foreach (var (group, symbol, finder) in documentQueue) - await ProcessDocumentAsync(document, model, group, symbol, finder).ConfigureAwait(false); + await ProcessDocumentAsync(document, model, group, symbol, finder, cancellationToken).ConfigureAwait(false); } finally { FindReferenceCache.Stop(model); - await _progress.OnFindInDocumentCompletedAsync(document).ConfigureAwait(false); + await _progress.OnFindInDocumentCompletedAsync(document, cancellationToken).ConfigureAwait(false); } } @@ -48,22 +50,23 @@ private async Task ProcessDocumentAsync( SemanticModel semanticModel, SymbolGroup group, ISymbol symbol, - IReferenceFinder finder) + IReferenceFinder finder, + CancellationToken cancellationToken) { - using (Logger.LogBlock(FunctionId.FindReference_ProcessDocumentAsync, s_logDocument, document, symbol, _cancellationToken)) + using (Logger.LogBlock(FunctionId.FindReference_ProcessDocumentAsync, s_logDocument, document, symbol, cancellationToken)) { try { var references = await finder.FindReferencesInDocumentAsync( - symbol, document, semanticModel, _options, _cancellationToken).ConfigureAwait(false); + symbol, document, semanticModel, _options, cancellationToken).ConfigureAwait(false); foreach (var (_, location) in references) { - await HandleLocationAsync(group, symbol, location).ConfigureAwait(false); + await HandleLocationAsync(group, symbol, location, cancellationToken).ConfigureAwait(false); } } finally { - await _progressTracker.ItemCompletedAsync().ConfigureAwait(false); + await _progressTracker.ItemCompletedAsync(cancellationToken).ConfigureAwait(false); } } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_MapCreation.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_MapCreation.cs index 804ddbe60269d..040416bba3553 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_MapCreation.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_MapCreation.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; +using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.FindSymbols.Finders; @@ -24,9 +25,9 @@ internal partial class FindReferencesSearchEngine { private static readonly Func s_createDocumentMap = _ => new DocumentMap(); - private async Task CreateProjectToDocumentMapAsync(ProjectMap projectMap) + private async Task CreateProjectToDocumentMapAsync(ProjectMap projectMap, CancellationToken cancellationToken) { - using (Logger.LogBlock(FunctionId.FindReference_CreateDocumentMapAsync, _cancellationToken)) + using (Logger.LogBlock(FunctionId.FindReference_CreateDocumentMapAsync, cancellationToken)) { using var _ = ArrayBuilder, SymbolGroup, ISymbol, IReferenceFinder)>>.GetInstance(out var tasks); @@ -35,7 +36,7 @@ private async Task CreateProjectToDocumentMapAsync(Project foreach (var (group, symbol, finder) in projectQueue) { tasks.Add(Task.Factory.StartNew(() => - DetermineDocumentsToSearchAsync(project, group, symbol, finder), _cancellationToken, TaskCreationOptions.None, _scheduler).Unwrap()); + DetermineDocumentsToSearchAsync(project, group, symbol, finder, cancellationToken), cancellationToken, TaskCreationOptions.None, _scheduler).Unwrap()); } } @@ -63,18 +64,18 @@ private async Task CreateProjectToDocumentMapAsync(Project } private async Task<(ImmutableArray, SymbolGroup, ISymbol, IReferenceFinder)> DetermineDocumentsToSearchAsync( - Project project, SymbolGroup group, ISymbol symbol, IReferenceFinder finder) + Project project, SymbolGroup group, ISymbol symbol, IReferenceFinder finder, CancellationToken cancellationToken) { var documents = await finder.DetermineDocumentsToSearchAsync( - symbol, project, _documents, _options, _cancellationToken).ConfigureAwait(false); + symbol, project, _documents, _options, cancellationToken).ConfigureAwait(false); var finalDocs = documents.WhereNotNull().Distinct().Where( d => _documents == null || _documents.Contains(d)).ToImmutableArray(); return (finalDocs, group, symbol, finder); } - private async Task CreateProjectMapAsync(ConcurrentSet symbolGroups) + private async Task CreateProjectMapAsync(ConcurrentSet symbolGroups, CancellationToken cancellationToken) { - using (Logger.LogBlock(FunctionId.FindReference_CreateProjectMapAsync, _cancellationToken)) + using (Logger.LogBlock(FunctionId.FindReference_CreateProjectMapAsync, cancellationToken)) { var projectMap = new ProjectMap(); @@ -85,9 +86,9 @@ private async Task CreateProjectMapAsync(ConcurrentSet { foreach (var finder in _finders) { - _cancellationToken.ThrowIfCancellationRequested(); + cancellationToken.ThrowIfCancellationRequested(); - var projects = await finder.DetermineProjectsToSearchAsync(symbol, _solution, scope, _cancellationToken).ConfigureAwait(false); + var projects = await finder.DetermineProjectsToSearchAsync(symbol, _solution, scope, cancellationToken).ConfigureAwait(false); foreach (var project in projects.Distinct().WhereNotNull()) { if (scope == null || scope.Contains(project)) @@ -103,39 +104,40 @@ private async Task CreateProjectMapAsync(ConcurrentSet } private async Task> DetermineAllSymbolsAsync( - ISymbol symbol, FindReferencesCascadeDirection cascadeDirection) + ISymbol symbol, FindReferencesCascadeDirection cascadeDirection, CancellationToken cancellationToken) { - using (Logger.LogBlock(FunctionId.FindReference_DetermineAllSymbolsAsync, _cancellationToken)) + using (Logger.LogBlock(FunctionId.FindReference_DetermineAllSymbolsAsync, cancellationToken)) { var result = new ConcurrentSet(); - await DetermineAllSymbolsCoreAsync(symbol, cascadeDirection, result).ConfigureAwait(false); + await DetermineAllSymbolsCoreAsync(symbol, cascadeDirection, result, cancellationToken).ConfigureAwait(false); return result; } } private async Task DetermineAllSymbolsCoreAsync( - ISymbol symbol, FindReferencesCascadeDirection cascadeDirection, ConcurrentSet result) + ISymbol symbol, FindReferencesCascadeDirection cascadeDirection, + ConcurrentSet result, CancellationToken cancellationToken) { - _cancellationToken.ThrowIfCancellationRequested(); + cancellationToken.ThrowIfCancellationRequested(); var searchSymbol = MapToAppropriateSymbol(symbol); // 2) Try to map this back to source symbol if this was a metadata symbol. - var sourceSymbol = await SymbolFinder.FindSourceDefinitionAsync(searchSymbol, _solution, _cancellationToken).ConfigureAwait(false); + var sourceSymbol = await SymbolFinder.FindSourceDefinitionAsync(searchSymbol, _solution, cancellationToken).ConfigureAwait(false); if (sourceSymbol != null) searchSymbol = sourceSymbol; Contract.ThrowIfNull(searchSymbol); - var group = await DetermineSymbolGroupAsync(searchSymbol).ConfigureAwait(false); + var group = await DetermineSymbolGroupAsync(searchSymbol, cancellationToken).ConfigureAwait(false); if (result.Add(group)) { - await _progress.OnDefinitionFoundAsync(group).ConfigureAwait(false); + await _progress.OnDefinitionFoundAsync(group, cancellationToken).ConfigureAwait(false); // get project to search var projects = GetProjectScope(); - _cancellationToken.ThrowIfCancellationRequested(); + cancellationToken.ThrowIfCancellationRequested(); using var _ = ArrayBuilder.GetInstance(out var finderTasks); foreach (var f in _finders) @@ -145,48 +147,49 @@ private async Task DetermineAllSymbolsCoreAsync( using var _ = ArrayBuilder.GetInstance(out var symbolTasks); var symbols = await f.DetermineCascadedSymbolsAsync( - searchSymbol, _solution, projects, _options, cascadeDirection, _cancellationToken).ConfigureAwait(false); - AddSymbolTasks(result, symbols, symbolTasks); + searchSymbol, _solution, projects, _options, cascadeDirection, cancellationToken).ConfigureAwait(false); + AddSymbolTasks(result, symbols, symbolTasks, cancellationToken); // Defer to the language to see if it wants to cascade here in some special way. var symbolProject = _solution.GetProject(searchSymbol.ContainingAssembly); if (symbolProject?.LanguageServices.GetService() is { } service) { symbols = await service.DetermineCascadedSymbolsAsync( - searchSymbol, symbolProject, cascadeDirection, _cancellationToken).ConfigureAwait(false); - AddSymbolTasks(result, symbols, symbolTasks); + searchSymbol, symbolProject, cascadeDirection, cancellationToken).ConfigureAwait(false); + AddSymbolTasks(result, symbols, symbolTasks, cancellationToken); } - _cancellationToken.ThrowIfCancellationRequested(); + cancellationToken.ThrowIfCancellationRequested(); await Task.WhenAll(symbolTasks).ConfigureAwait(false); - }, _cancellationToken, TaskCreationOptions.None, _scheduler).Unwrap()); + }, cancellationToken, TaskCreationOptions.None, _scheduler).Unwrap()); } await Task.WhenAll(finderTasks).ConfigureAwait(false); } } - private async Task DetermineSymbolGroupAsync(ISymbol searchSymbol) + private async Task DetermineSymbolGroupAsync(ISymbol searchSymbol, CancellationToken cancellationToken) { if (!_options.Cascade) return new SymbolGroup(ImmutableArray.Create(searchSymbol)); return new SymbolGroup( - await SymbolFinder.FindLinkedSymbolsAsync(searchSymbol, _solution, _cancellationToken).ConfigureAwait(false)); + await SymbolFinder.FindLinkedSymbolsAsync(searchSymbol, _solution, cancellationToken).ConfigureAwait(false)); } private void AddSymbolTasks( ConcurrentSet result, ImmutableArray<(ISymbol symbol, FindReferencesCascadeDirection cascadeDirection)> symbols, - ArrayBuilder symbolTasks) + ArrayBuilder symbolTasks, + CancellationToken cancellationToken) { if (!symbols.IsDefault) { foreach (var (symbol, cascadeDirection) in symbols) { Contract.ThrowIfNull(symbol); - _cancellationToken.ThrowIfCancellationRequested(); + cancellationToken.ThrowIfCancellationRequested(); // If we're cascading unidirectionally, then keep going in the direction this symbol was found in. // Otherwise, if we're not unidirectional, then continue to cascade in both directions with this @@ -195,7 +198,7 @@ private void AddSymbolTasks( ? cascadeDirection : FindReferencesCascadeDirection.UpAndDown; symbolTasks.Add(Task.Factory.StartNew( - () => DetermineAllSymbolsCoreAsync(symbol, finalDirection, result), _cancellationToken, TaskCreationOptions.None, _scheduler).Unwrap()); + () => DetermineAllSymbolsCoreAsync(symbol, finalDirection, result, cancellationToken), cancellationToken, TaskCreationOptions.None, _scheduler).Unwrap()); } } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_ProjectProcessing.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_ProjectProcessing.cs index 097eff45212f5..c1db21f5f435a 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_ProjectProcessing.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_ProjectProcessing.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.FindSymbols.Finders; using Microsoft.CodeAnalysis.Internal.Log; @@ -17,20 +18,21 @@ internal partial class FindReferencesSearchEngine { private async Task ProcessProjectAsync( Project project, - DocumentMap documentMap) + DocumentMap documentMap, + CancellationToken cancellationToken) { - using (Logger.LogBlock(FunctionId.FindReference_ProcessProjectAsync, project.Name, _cancellationToken)) + using (Logger.LogBlock(FunctionId.FindReference_ProcessProjectAsync, project.Name, cancellationToken)) { if (project.SupportsCompilation) { // make sure we hold onto compilation while we search documents belong to this project - var compilation = await project.GetCompilationAsync(_cancellationToken).ConfigureAwait(false); + var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); var documentTasks = new List(); foreach (var (document, documentQueue) in documentMap) { if (document.Project == project) - documentTasks.Add(Task.Factory.StartNew(() => ProcessDocumentQueueAsync(document, documentQueue), _cancellationToken, TaskCreationOptions.None, _scheduler).Unwrap()); + documentTasks.Add(Task.Factory.StartNew(() => ProcessDocumentQueueAsync(document, documentQueue, cancellationToken), cancellationToken, TaskCreationOptions.None, _scheduler).Unwrap()); } await Task.WhenAll(documentTasks).ConfigureAwait(false); diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/NoOpStreamingFindReferencesProgress.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/NoOpStreamingFindReferencesProgress.cs index 00d1374a82c96..9dfc71ad26461 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/NoOpStreamingFindReferencesProgress.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/NoOpStreamingFindReferencesProgress.cs @@ -4,6 +4,7 @@ #nullable disable +using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Shared.Utilities; @@ -28,17 +29,17 @@ private NoOpStreamingFindReferencesProgress() public static Task ReportProgressAsync(int current, int maximum) => Task.CompletedTask; #pragma warning restore IDE0060 // Remove unused parameter - public ValueTask OnCompletedAsync() => default; - public ValueTask OnStartedAsync() => default; - public ValueTask OnDefinitionFoundAsync(SymbolGroup group) => default; - public ValueTask OnReferenceFoundAsync(SymbolGroup group, ISymbol symbol, ReferenceLocation location) => default; - public ValueTask OnFindInDocumentStartedAsync(Document document) => default; - public ValueTask OnFindInDocumentCompletedAsync(Document document) => default; + public ValueTask OnCompletedAsync(CancellationToken cancellationToken) => default; + public ValueTask OnStartedAsync(CancellationToken cancellationToken) => default; + public ValueTask OnDefinitionFoundAsync(SymbolGroup group, CancellationToken cancellationToken) => default; + public ValueTask OnReferenceFoundAsync(SymbolGroup group, ISymbol symbol, ReferenceLocation location, CancellationToken cancellationToken) => default; + public ValueTask OnFindInDocumentStartedAsync(Document document, CancellationToken cancellationToken) => default; + public ValueTask OnFindInDocumentCompletedAsync(Document document, CancellationToken cancellationToken) => default; private class NoOpProgressTracker : IStreamingProgressTracker { - public ValueTask AddItemsAsync(int count) => default; - public ValueTask ItemCompletedAsync() => default; + public ValueTask AddItemsAsync(int count, CancellationToken cancellationToken) => default; + public ValueTask ItemCompletedAsync(CancellationToken cancellationToken) => default; } } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/StreamingFindReferencesProgress.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/StreamingFindReferencesProgress.cs index c311db326485b..0dc8f2679485c 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/StreamingFindReferencesProgress.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/StreamingFindReferencesProgress.cs @@ -4,6 +4,7 @@ #nullable disable +using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Shared.Utilities; @@ -22,32 +23,32 @@ internal class StreamingFindReferencesProgressAdapter : IStreamingFindReferences public StreamingFindReferencesProgressAdapter(IFindReferencesProgress progress) { _progress = progress; - ProgressTracker = new StreamingProgressTracker((current, max) => + ProgressTracker = new StreamingProgressTracker((current, max, ct) => { _progress.ReportProgress(current, max); return default; }); } - public ValueTask OnCompletedAsync() + public ValueTask OnCompletedAsync(CancellationToken cancellationToken) { _progress.OnCompleted(); return default; } - public ValueTask OnFindInDocumentCompletedAsync(Document document) + public ValueTask OnFindInDocumentCompletedAsync(Document document, CancellationToken cancellationToken) { _progress.OnFindInDocumentCompleted(document); return default; } - public ValueTask OnFindInDocumentStartedAsync(Document document) + public ValueTask OnFindInDocumentStartedAsync(Document document, CancellationToken cancellationToken) { _progress.OnFindInDocumentStarted(document); return default; } - public ValueTask OnDefinitionFoundAsync(SymbolGroup group) + public ValueTask OnDefinitionFoundAsync(SymbolGroup group, CancellationToken cancellationToken) { foreach (var symbol in group.Symbols) _progress.OnDefinitionFound(symbol); @@ -55,13 +56,13 @@ public ValueTask OnDefinitionFoundAsync(SymbolGroup group) return default; } - public ValueTask OnReferenceFoundAsync(SymbolGroup group, ISymbol symbol, ReferenceLocation location) + public ValueTask OnReferenceFoundAsync(SymbolGroup group, ISymbol symbol, ReferenceLocation location, CancellationToken cancellationToken) { _progress.OnReferenceFound(symbol, location); return default; } - public ValueTask OnStartedAsync() + public ValueTask OnStartedAsync(CancellationToken cancellationToken) { _progress.OnStarted(); return default; diff --git a/src/Workspaces/Core/Portable/FindSymbols/IRemoteSymbolFinderService.cs b/src/Workspaces/Core/Portable/FindSymbols/IRemoteSymbolFinderService.cs index c09fc4c08c20b..0fbb148cf1944 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/IRemoteSymbolFinderService.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/IRemoteSymbolFinderService.cs @@ -17,18 +17,18 @@ internal interface IRemoteSymbolFinderService { internal interface ICallback { - ValueTask AddReferenceItemsAsync(RemoteServiceCallbackId callbackId, int count); - ValueTask ReferenceItemCompletedAsync(RemoteServiceCallbackId callbackId); - ValueTask OnStartedAsync(RemoteServiceCallbackId callbackId); - ValueTask OnCompletedAsync(RemoteServiceCallbackId callbackId); - ValueTask OnFindInDocumentStartedAsync(RemoteServiceCallbackId callbackId, DocumentId documentId); - ValueTask OnFindInDocumentCompletedAsync(RemoteServiceCallbackId callbackId, DocumentId documentId); - ValueTask OnDefinitionFoundAsync(RemoteServiceCallbackId callbackId, SerializableSymbolGroup group); - ValueTask OnReferenceFoundAsync(RemoteServiceCallbackId callbackId, SerializableSymbolGroup group, SerializableSymbolAndProjectId definition, SerializableReferenceLocation reference); - - ValueTask AddLiteralItemsAsync(RemoteServiceCallbackId callbackId, int count); - ValueTask LiteralItemCompletedAsync(RemoteServiceCallbackId callbackId); - ValueTask OnLiteralReferenceFoundAsync(RemoteServiceCallbackId callbackId, DocumentId documentId, TextSpan span); + ValueTask AddReferenceItemsAsync(RemoteServiceCallbackId callbackId, int count, CancellationToken cancellationToken); + ValueTask ReferenceItemCompletedAsync(RemoteServiceCallbackId callbackId, CancellationToken cancellationToken); + ValueTask OnStartedAsync(RemoteServiceCallbackId callbackId, CancellationToken cancellationToken); + ValueTask OnCompletedAsync(RemoteServiceCallbackId callbackId, CancellationToken cancellationToken); + ValueTask OnFindInDocumentStartedAsync(RemoteServiceCallbackId callbackId, DocumentId documentId, CancellationToken cancellationToken); + ValueTask OnFindInDocumentCompletedAsync(RemoteServiceCallbackId callbackId, DocumentId documentId, CancellationToken cancellationToken); + ValueTask OnDefinitionFoundAsync(RemoteServiceCallbackId callbackId, SerializableSymbolGroup group, CancellationToken cancellationToken); + ValueTask OnReferenceFoundAsync(RemoteServiceCallbackId callbackId, SerializableSymbolGroup group, SerializableSymbolAndProjectId definition, SerializableReferenceLocation reference, CancellationToken cancellationToken); + + ValueTask AddLiteralItemsAsync(RemoteServiceCallbackId callbackId, int count, CancellationToken cancellationToken); + ValueTask LiteralItemCompletedAsync(RemoteServiceCallbackId callbackId, CancellationToken cancellationToken); + ValueTask OnLiteralReferenceFoundAsync(RemoteServiceCallbackId callbackId, DocumentId documentId, TextSpan span, CancellationToken cancellationToken); } ValueTask FindReferencesAsync(PinnedSolutionInfo solutionInfo, RemoteServiceCallbackId callbackId, SerializableSymbolAndProjectId symbolAndProjectIdArg, ImmutableArray documentArgs, diff --git a/src/Workspaces/Core/Portable/FindSymbols/IStreamingFindReferencesProgress.cs b/src/Workspaces/Core/Portable/FindSymbols/IStreamingFindReferencesProgress.cs index 5c7da911bedc0..28486ff5a73fc 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/IStreamingFindReferencesProgress.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/IStreamingFindReferencesProgress.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Immutable; using System.Linq; +using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Shared.Utilities; using Microsoft.CodeAnalysis.Text; @@ -68,20 +69,20 @@ internal interface IStreamingFindReferencesProgress { IStreamingProgressTracker ProgressTracker { get; } - ValueTask OnStartedAsync(); - ValueTask OnCompletedAsync(); + ValueTask OnStartedAsync(CancellationToken cancellationToken); + ValueTask OnCompletedAsync(CancellationToken cancellationToken); - ValueTask OnFindInDocumentStartedAsync(Document document); - ValueTask OnFindInDocumentCompletedAsync(Document document); + ValueTask OnFindInDocumentStartedAsync(Document document, CancellationToken cancellationToken); + ValueTask OnFindInDocumentCompletedAsync(Document document, CancellationToken cancellationToken); - ValueTask OnDefinitionFoundAsync(SymbolGroup group); - ValueTask OnReferenceFoundAsync(SymbolGroup group, ISymbol symbol, ReferenceLocation location); + ValueTask OnDefinitionFoundAsync(SymbolGroup group, CancellationToken cancellationToken); + ValueTask OnReferenceFoundAsync(SymbolGroup group, ISymbol symbol, ReferenceLocation location, CancellationToken cancellationToken); } internal interface IStreamingFindLiteralReferencesProgress { IStreamingProgressTracker ProgressTracker { get; } - ValueTask OnReferenceFoundAsync(Document document, TextSpan span); + ValueTask OnReferenceFoundAsync(Document document, TextSpan span, CancellationToken cancellationToken); } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/StreamingProgressCollector.cs b/src/Workspaces/Core/Portable/FindSymbols/StreamingProgressCollector.cs index 87c7f1a426535..fcc4e5d2c12f7 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/StreamingProgressCollector.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/StreamingProgressCollector.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Collections.Immutable; +using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Shared.Utilities; @@ -53,13 +54,13 @@ public ImmutableArray GetReferencedSymbols() } } - public ValueTask OnStartedAsync() => _underlyingProgress.OnStartedAsync(); - public ValueTask OnCompletedAsync() => _underlyingProgress.OnCompletedAsync(); + public ValueTask OnStartedAsync(CancellationToken cancellationToken) => _underlyingProgress.OnStartedAsync(cancellationToken); + public ValueTask OnCompletedAsync(CancellationToken cancellationToken) => _underlyingProgress.OnCompletedAsync(cancellationToken); - public ValueTask OnFindInDocumentCompletedAsync(Document document) => _underlyingProgress.OnFindInDocumentCompletedAsync(document); - public ValueTask OnFindInDocumentStartedAsync(Document document) => _underlyingProgress.OnFindInDocumentStartedAsync(document); + public ValueTask OnFindInDocumentCompletedAsync(Document document, CancellationToken cancellationToken) => _underlyingProgress.OnFindInDocumentCompletedAsync(document, cancellationToken); + public ValueTask OnFindInDocumentStartedAsync(Document document, CancellationToken cancellationToken) => _underlyingProgress.OnFindInDocumentStartedAsync(document, cancellationToken); - public ValueTask OnDefinitionFoundAsync(SymbolGroup group) + public ValueTask OnDefinitionFoundAsync(SymbolGroup group, CancellationToken cancellationToken) { lock (_gate) { @@ -67,17 +68,17 @@ public ValueTask OnDefinitionFoundAsync(SymbolGroup group) _symbolToLocations[definition] = new List(); } - return _underlyingProgress.OnDefinitionFoundAsync(group); + return _underlyingProgress.OnDefinitionFoundAsync(group, cancellationToken); } - public ValueTask OnReferenceFoundAsync(SymbolGroup group, ISymbol definition, ReferenceLocation location) + public ValueTask OnReferenceFoundAsync(SymbolGroup group, ISymbol definition, ReferenceLocation location, CancellationToken cancellationToken) { lock (_gate) { _symbolToLocations[definition].Add(location); } - return _underlyingProgress.OnReferenceFoundAsync(group, definition, location); + return _underlyingProgress.OnReferenceFoundAsync(group, definition, location, cancellationToken); } } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.CallbackDispatcher.cs b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.CallbackDispatcher.cs index 42c8c28691b7f..ef2f07cb0041d 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.CallbackDispatcher.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.CallbackDispatcher.cs @@ -4,6 +4,7 @@ using System; using System.Composition; +using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Remote; @@ -30,40 +31,40 @@ private FindReferencesServerCallback GetFindReferencesCallback(RemoteServiceCall // references - public ValueTask AddReferenceItemsAsync(RemoteServiceCallbackId callbackId, int count) - => GetFindReferencesCallback(callbackId).AddItemsAsync(count); + public ValueTask AddReferenceItemsAsync(RemoteServiceCallbackId callbackId, int count, CancellationToken cancellationToken) + => GetFindReferencesCallback(callbackId).AddItemsAsync(count, cancellationToken); - public ValueTask ReferenceItemCompletedAsync(RemoteServiceCallbackId callbackId) - => GetFindReferencesCallback(callbackId).ItemCompletedAsync(); + public ValueTask ReferenceItemCompletedAsync(RemoteServiceCallbackId callbackId, CancellationToken cancellationToken) + => GetFindReferencesCallback(callbackId).ItemCompletedAsync(cancellationToken); - public ValueTask OnCompletedAsync(RemoteServiceCallbackId callbackId) - => GetFindReferencesCallback(callbackId).OnCompletedAsync(); + public ValueTask OnCompletedAsync(RemoteServiceCallbackId callbackId, CancellationToken cancellationToken) + => GetFindReferencesCallback(callbackId).OnCompletedAsync(cancellationToken); - public ValueTask OnDefinitionFoundAsync(RemoteServiceCallbackId callbackId, SerializableSymbolGroup symbolGroup) - => GetFindReferencesCallback(callbackId).OnDefinitionFoundAsync(symbolGroup); + public ValueTask OnDefinitionFoundAsync(RemoteServiceCallbackId callbackId, SerializableSymbolGroup symbolGroup, CancellationToken cancellationToken) + => GetFindReferencesCallback(callbackId).OnDefinitionFoundAsync(symbolGroup, cancellationToken); - public ValueTask OnFindInDocumentCompletedAsync(RemoteServiceCallbackId callbackId, DocumentId documentId) - => GetFindReferencesCallback(callbackId).OnFindInDocumentCompletedAsync(documentId); + public ValueTask OnFindInDocumentCompletedAsync(RemoteServiceCallbackId callbackId, DocumentId documentId, CancellationToken cancellationToken) + => GetFindReferencesCallback(callbackId).OnFindInDocumentCompletedAsync(documentId, cancellationToken); - public ValueTask OnFindInDocumentStartedAsync(RemoteServiceCallbackId callbackId, DocumentId documentId) - => GetFindReferencesCallback(callbackId).OnFindInDocumentStartedAsync(documentId); + public ValueTask OnFindInDocumentStartedAsync(RemoteServiceCallbackId callbackId, DocumentId documentId, CancellationToken cancellationToken) + => GetFindReferencesCallback(callbackId).OnFindInDocumentStartedAsync(documentId, cancellationToken); - public ValueTask OnReferenceFoundAsync(RemoteServiceCallbackId callbackId, SerializableSymbolGroup symbolGroup, SerializableSymbolAndProjectId definition, SerializableReferenceLocation reference) - => GetFindReferencesCallback(callbackId).OnReferenceFoundAsync(symbolGroup, definition, reference); + public ValueTask OnReferenceFoundAsync(RemoteServiceCallbackId callbackId, SerializableSymbolGroup symbolGroup, SerializableSymbolAndProjectId definition, SerializableReferenceLocation reference, CancellationToken cancellationToken) + => GetFindReferencesCallback(callbackId).OnReferenceFoundAsync(symbolGroup, definition, reference, cancellationToken); - public ValueTask OnStartedAsync(RemoteServiceCallbackId callbackId) - => GetFindReferencesCallback(callbackId).OnStartedAsync(); + public ValueTask OnStartedAsync(RemoteServiceCallbackId callbackId, CancellationToken cancellationToken) + => GetFindReferencesCallback(callbackId).OnStartedAsync(cancellationToken); // literals - public ValueTask AddLiteralItemsAsync(RemoteServiceCallbackId callbackId, int count) - => GetFindLiteralsCallback(callbackId).AddItemsAsync(count); + public ValueTask AddLiteralItemsAsync(RemoteServiceCallbackId callbackId, int count, CancellationToken cancellationToken) + => GetFindLiteralsCallback(callbackId).AddItemsAsync(count, cancellationToken); - public ValueTask LiteralItemCompletedAsync(RemoteServiceCallbackId callbackId) - => GetFindLiteralsCallback(callbackId).ItemCompletedAsync(); + public ValueTask LiteralItemCompletedAsync(RemoteServiceCallbackId callbackId, CancellationToken cancellationToken) + => GetFindLiteralsCallback(callbackId).ItemCompletedAsync(cancellationToken); - public ValueTask OnLiteralReferenceFoundAsync(RemoteServiceCallbackId callbackId, DocumentId documentId, TextSpan span) - => GetFindLiteralsCallback(callbackId).OnLiteralReferenceFoundAsync(documentId, span); + public ValueTask OnLiteralReferenceFoundAsync(RemoteServiceCallbackId callbackId, DocumentId documentId, TextSpan span, CancellationToken cancellationToken) + => GetFindLiteralsCallback(callbackId).OnLiteralReferenceFoundAsync(documentId, span, cancellationToken); } } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.FindLiteralsServerCallback.cs b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.FindLiteralsServerCallback.cs index cfe0c50ef33d1..53115374d148a 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.FindLiteralsServerCallback.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.FindLiteralsServerCallback.cs @@ -2,9 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - +using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Text; namespace Microsoft.CodeAnalysis.FindSymbols @@ -24,16 +24,16 @@ public FindLiteralsServerCallback( _progress = progress; } - public ValueTask AddItemsAsync(int count) - => _progress.ProgressTracker.AddItemsAsync(count); + public ValueTask AddItemsAsync(int count, CancellationToken cancellationToken) + => _progress.ProgressTracker.AddItemsAsync(count, cancellationToken); - public ValueTask ItemCompletedAsync() - => _progress.ProgressTracker.ItemCompletedAsync(); + public ValueTask ItemCompletedAsync(CancellationToken cancellationToken) + => _progress.ProgressTracker.ItemCompletedAsync(cancellationToken); - public async ValueTask OnLiteralReferenceFoundAsync(DocumentId documentId, TextSpan span) + public async ValueTask OnLiteralReferenceFoundAsync(DocumentId documentId, TextSpan span, CancellationToken cancellationToken) { - var document = _solution.GetDocument(documentId); - await _progress.OnReferenceFoundAsync(document, span).ConfigureAwait(false); + var document = _solution.GetRequiredDocument(documentId); + await _progress.OnReferenceFoundAsync(document, span, cancellationToken).ConfigureAwait(false); } } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.FindReferencesServerCallback.cs b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.FindReferencesServerCallback.cs index d19ca96433e90..77d5c5640eb39 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.FindReferencesServerCallback.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.FindReferencesServerCallback.cs @@ -24,7 +24,6 @@ internal sealed class FindReferencesServerCallback { private readonly Solution _solution; private readonly IStreamingFindReferencesProgress _progress; - private readonly CancellationToken _cancellationToken; private readonly object _gate = new(); private readonly Dictionary _groupMap = new(); @@ -32,39 +31,37 @@ internal sealed class FindReferencesServerCallback public FindReferencesServerCallback( Solution solution, - IStreamingFindReferencesProgress progress, - CancellationToken cancellationToken) + IStreamingFindReferencesProgress progress) { _solution = solution; _progress = progress; - _cancellationToken = cancellationToken; } - public ValueTask AddItemsAsync(int count) - => _progress.ProgressTracker.AddItemsAsync(count); + public ValueTask AddItemsAsync(int count, CancellationToken cancellationToken) + => _progress.ProgressTracker.AddItemsAsync(count, cancellationToken); - public ValueTask ItemCompletedAsync() - => _progress.ProgressTracker.ItemCompletedAsync(); + public ValueTask ItemCompletedAsync(CancellationToken cancellationToken) + => _progress.ProgressTracker.ItemCompletedAsync(cancellationToken); - public ValueTask OnStartedAsync() - => _progress.OnStartedAsync(); + public ValueTask OnStartedAsync(CancellationToken cancellationToken) + => _progress.OnStartedAsync(cancellationToken); - public ValueTask OnCompletedAsync() - => _progress.OnCompletedAsync(); + public ValueTask OnCompletedAsync(CancellationToken cancellationToken) + => _progress.OnCompletedAsync(cancellationToken); - public ValueTask OnFindInDocumentStartedAsync(DocumentId documentId) + public ValueTask OnFindInDocumentStartedAsync(DocumentId documentId, CancellationToken cancellationToken) { var document = _solution.GetDocument(documentId); - return _progress.OnFindInDocumentStartedAsync(document); + return _progress.OnFindInDocumentStartedAsync(document, cancellationToken); } - public ValueTask OnFindInDocumentCompletedAsync(DocumentId documentId) + public ValueTask OnFindInDocumentCompletedAsync(DocumentId documentId, CancellationToken cancellationToken) { var document = _solution.GetDocument(documentId); - return _progress.OnFindInDocumentCompletedAsync(document); + return _progress.OnFindInDocumentCompletedAsync(document, cancellationToken); } - public async ValueTask OnDefinitionFoundAsync(SerializableSymbolGroup dehydrated) + public async ValueTask OnDefinitionFoundAsync(SerializableSymbolGroup dehydrated, CancellationToken cancellationToken) { Contract.ThrowIfTrue(dehydrated.Symbols.Count == 0); @@ -72,7 +69,7 @@ public async ValueTask OnDefinitionFoundAsync(SerializableSymbolGroup dehydrated foreach (var symbolAndProjectId in dehydrated.Symbols) { - var symbol = await symbolAndProjectId.TryRehydrateAsync(_solution, _cancellationToken).ConfigureAwait(false); + var symbol = await symbolAndProjectId.TryRehydrateAsync(_solution, cancellationToken).ConfigureAwait(false); if (symbol == null) return; @@ -87,13 +84,14 @@ public async ValueTask OnDefinitionFoundAsync(SerializableSymbolGroup dehydrated _definitionMap[pair.Key] = pair.Value; } - await _progress.OnDefinitionFoundAsync(symbolGroup).ConfigureAwait(false); + await _progress.OnDefinitionFoundAsync(symbolGroup, cancellationToken).ConfigureAwait(false); } public async ValueTask OnReferenceFoundAsync( SerializableSymbolGroup serializableSymbolGroup, SerializableSymbolAndProjectId serializableSymbol, - SerializableReferenceLocation reference) + SerializableReferenceLocation reference, + CancellationToken cancellationToken) { SymbolGroup symbolGroup; ISymbol symbol; @@ -114,9 +112,9 @@ public async ValueTask OnReferenceFoundAsync( } var referenceLocation = await reference.RehydrateAsync( - _solution, _cancellationToken).ConfigureAwait(false); + _solution, cancellationToken).ConfigureAwait(false); - await _progress.OnReferenceFoundAsync(symbolGroup, symbol, referenceLocation).ConfigureAwait(false); + await _progress.OnReferenceFoundAsync(symbolGroup, symbol, referenceLocation, cancellationToken).ConfigureAwait(false); } } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_FindLiteralReferences.cs b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_FindLiteralReferences.cs index 736db99013304..23e1b777576a2 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_FindLiteralReferences.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_FindLiteralReferences.cs @@ -49,9 +49,8 @@ internal static Task FindLiteralReferencesInCurrentProcessAsync( IStreamingFindLiteralReferencesProgress progress, CancellationToken cancellationToken) { - var engine = new FindLiteralsSearchEngine( - solution, progress, value, cancellationToken); - return engine.FindReferencesAsync(); + var engine = new FindLiteralsSearchEngine(solution, progress, value); + return engine.FindReferencesAsync(cancellationToken); } } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_FindReferences_Current.cs b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_FindReferences_Current.cs index 43aa74f5307cf..40a26d14658a4 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_FindReferences_Current.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_FindReferences_Current.cs @@ -39,7 +39,7 @@ internal static async Task FindReferencesAsync( // Create a callback that we can pass to the server process to hear about the // results as it finds them. When we hear about results we'll forward them to // the 'progress' parameter which will then update the UI. - var serverCallback = new FindReferencesServerCallback(solution, progress, cancellationToken); + var serverCallback = new FindReferencesServerCallback(solution, progress); var documentIds = documents?.SelectAsArray(d => d.Id) ?? default; await client.TryInvokeAsync( @@ -70,8 +70,8 @@ internal static Task FindReferencesInCurrentProcessAsync( var finders = ReferenceFinders.DefaultReferenceFinders; progress ??= NoOpStreamingFindReferencesProgress.Instance; var engine = new FindReferencesSearchEngine( - solution, documents, finders, progress, options, cancellationToken); - return engine.FindReferencesAsync(symbol); + solution, documents, finders, progress, options); + return engine.FindReferencesAsync(symbol, cancellationToken); } } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_FindRenamableReferences.cs b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_FindRenamableReferences.cs index 757510178b6b6..058cdb47c58c5 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_FindRenamableReferences.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_FindRenamableReferences.cs @@ -26,10 +26,9 @@ internal static async Task> FindRenamableRefere documents: null, ReferenceFinders.DefaultRenameReferenceFinders, streamingProgress, - FindReferencesSearchOptions.Default, - cancellationToken); + FindReferencesSearchOptions.Default); - await engine.FindReferencesAsync(symbol).ConfigureAwait(false); + await engine.FindReferencesAsync(symbol, cancellationToken).ConfigureAwait(false); return streamingProgress.GetReferencedSymbols(); } } diff --git a/src/Workspaces/Core/Portable/Shared/Utilities/IStreamingProgressTracker.cs b/src/Workspaces/Core/Portable/Shared/Utilities/IStreamingProgressTracker.cs index 5707e5766bdd0..37e8cdd01a120 100644 --- a/src/Workspaces/Core/Portable/Shared/Utilities/IStreamingProgressTracker.cs +++ b/src/Workspaces/Core/Portable/Shared/Utilities/IStreamingProgressTracker.cs @@ -2,15 +2,14 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - +using System.Threading; using System.Threading.Tasks; namespace Microsoft.CodeAnalysis.Shared.Utilities { internal interface IStreamingProgressTracker { - ValueTask AddItemsAsync(int count); - ValueTask ItemCompletedAsync(); + ValueTask AddItemsAsync(int count, CancellationToken cancellationToken); + ValueTask ItemCompletedAsync(CancellationToken cancellationToken); } } diff --git a/src/Workspaces/Core/Portable/Shared/Utilities/IStreamingProgressTrackerExtensions.cs b/src/Workspaces/Core/Portable/Shared/Utilities/IStreamingProgressTrackerExtensions.cs index 9dd492de7766d..e57a545b167e3 100644 --- a/src/Workspaces/Core/Portable/Shared/Utilities/IStreamingProgressTrackerExtensions.cs +++ b/src/Workspaces/Core/Portable/Shared/Utilities/IStreamingProgressTrackerExtensions.cs @@ -2,9 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System; +using System.Threading; using System.Threading.Tasks; namespace Microsoft.CodeAnalysis.Shared.Utilities @@ -16,21 +15,25 @@ internal static class IStreamingProgressTrackerExtensions /// cref="IStreamingProgressTracker.ItemCompletedAsync"/> on when it is disposed. /// - public static async Task AddSingleItemAsync(this IStreamingProgressTracker progressTracker) + public static async Task AddSingleItemAsync(this IStreamingProgressTracker progressTracker, CancellationToken cancellationToken) { - await progressTracker.AddItemsAsync(1).ConfigureAwait(false); - return new StreamingProgressDisposer(progressTracker); + await progressTracker.AddItemsAsync(1, cancellationToken).ConfigureAwait(false); + return new StreamingProgressDisposer(progressTracker, cancellationToken); } private class StreamingProgressDisposer : IAsyncDisposable { private readonly IStreamingProgressTracker _progressTracker; + private readonly CancellationToken _cancellationToken; - public StreamingProgressDisposer(IStreamingProgressTracker progressTracker) - => _progressTracker = progressTracker; + public StreamingProgressDisposer(IStreamingProgressTracker progressTracker, CancellationToken cancellationToken) + { + _progressTracker = progressTracker; + _cancellationToken = cancellationToken; + } public async ValueTask DisposeAsync() - => await _progressTracker.ItemCompletedAsync().ConfigureAwait(false); + => await _progressTracker.ItemCompletedAsync(_cancellationToken).ConfigureAwait(false); } } } diff --git a/src/Workspaces/Core/Portable/Shared/Utilities/StreamingProgressTracker.cs b/src/Workspaces/Core/Portable/Shared/Utilities/StreamingProgressTracker.cs index 77de02c4e0601..59c57795661c2 100644 --- a/src/Workspaces/Core/Portable/Shared/Utilities/StreamingProgressTracker.cs +++ b/src/Workspaces/Core/Portable/Shared/Utilities/StreamingProgressTracker.cs @@ -16,31 +16,31 @@ internal sealed class StreamingProgressTracker : IStreamingProgressTracker private int _completedItems; private int _totalItems; - private readonly Func? _updateAction; + private readonly Func? _updateAction; - public StreamingProgressTracker(Func? updateAction = null) + public StreamingProgressTracker(Func? updateAction = null) => _updateAction = updateAction; - public ValueTask AddItemsAsync(int count) + public ValueTask AddItemsAsync(int count, CancellationToken cancellationToken) { Interlocked.Add(ref _totalItems, count); - return UpdateAsync(); + return UpdateAsync(cancellationToken); } - public ValueTask ItemCompletedAsync() + public ValueTask ItemCompletedAsync(CancellationToken cancellationToken) { Interlocked.Increment(ref _completedItems); - return UpdateAsync(); + return UpdateAsync(cancellationToken); } - private ValueTask UpdateAsync() + private ValueTask UpdateAsync(CancellationToken cancellationToken) { if (_updateAction == null) { return default; } - return _updateAction(_completedItems, _totalItems); + return _updateAction(_completedItems, _totalItems, cancellationToken); } } } diff --git a/src/Workspaces/CoreTestUtilities/Fakes/StubStreamingFindUsagesPresenter.cs b/src/Workspaces/CoreTestUtilities/Fakes/StubStreamingFindUsagesPresenter.cs index bb43955a7ce8e..64e402bd26e88 100644 --- a/src/Workspaces/CoreTestUtilities/Fakes/StubStreamingFindUsagesPresenter.cs +++ b/src/Workspaces/CoreTestUtilities/Fakes/StubStreamingFindUsagesPresenter.cs @@ -27,10 +27,10 @@ public virtual void ClearAll() { } - public virtual FindUsagesContext StartSearch(string title, bool supportsReferences, CancellationToken cancellationToken) - => new SimpleFindUsagesContext(cancellationToken); + public virtual (FindUsagesContext, CancellationToken) StartSearch(string title, bool supportsReferences, CancellationToken cancellationToken) + => (new SimpleFindUsagesContext(), cancellationToken); - public virtual FindUsagesContext StartSearchWithCustomColumns(string title, bool supportsReferences, bool includeContainingTypeAndMemberColumns, bool includeKindColumn, CancellationToken cancellationToken) - => new SimpleFindUsagesContext(cancellationToken); + public virtual (FindUsagesContext, CancellationToken) StartSearchWithCustomColumns(string title, bool supportsReferences, bool includeContainingTypeAndMemberColumns, bool includeKindColumn, CancellationToken cancellationToken) + => (new SimpleFindUsagesContext(), cancellationToken); } } diff --git a/src/Workspaces/Remote/ServiceHub/Services/FindUsages/RemoteFindUsagesService.cs b/src/Workspaces/Remote/ServiceHub/Services/FindUsages/RemoteFindUsagesService.cs index df48f54df8abd..acab82a5dd4f7 100644 --- a/src/Workspaces/Remote/ServiceHub/Services/FindUsages/RemoteFindUsagesService.cs +++ b/src/Workspaces/Remote/ServiceHub/Services/FindUsages/RemoteFindUsagesService.cs @@ -49,9 +49,9 @@ public ValueTask FindReferencesAsync( if (symbol == null) return; - var context = new RemoteFindUsageContext(_callback, callbackId, cancellationToken); + var context = new RemoteFindUsageContext(_callback, callbackId); await AbstractFindUsagesService.FindReferencesAsync( - context, symbol, project, options).ConfigureAwait(false); + context, symbol, project, options, cancellationToken).ConfigureAwait(false); }, cancellationToken); } @@ -71,9 +71,9 @@ public ValueTask FindImplementationsAsync( if (symbol == null) return; - var context = new RemoteFindUsageContext(_callback, callbackId, cancellationToken); + var context = new RemoteFindUsageContext(_callback, callbackId); await AbstractFindUsagesService.FindImplementationsAsync( - symbol, project, context).ConfigureAwait(false); + symbol, project, context, cancellationToken).ConfigureAwait(false); }, cancellationToken); } @@ -83,22 +83,19 @@ private sealed class RemoteFindUsageContext : IFindUsagesContext, IStreamingProg private readonly RemoteServiceCallbackId _callbackId; private readonly Dictionary _definitionItemToId = new(); - public CancellationToken CancellationToken { get; } - - public RemoteFindUsageContext(RemoteCallback callback, RemoteServiceCallbackId callbackId, CancellationToken cancellationToken) + public RemoteFindUsageContext(RemoteCallback callback, RemoteServiceCallbackId callbackId) { _callback = callback; _callbackId = callbackId; - CancellationToken = cancellationToken; } #region IStreamingProgressTracker - public ValueTask AddItemsAsync(int count) - => _callback.InvokeAsync((callback, cancellationToken) => callback.AddItemsAsync(_callbackId, count), CancellationToken); + public ValueTask AddItemsAsync(int count, CancellationToken cancellationToken) + => _callback.InvokeAsync((callback, cancellationToken) => callback.AddItemsAsync(_callbackId, count, cancellationToken), cancellationToken); - public ValueTask ItemCompletedAsync() - => _callback.InvokeAsync((callback, cancellationToken) => callback.ItemCompletedAsync(_callbackId), CancellationToken); + public ValueTask ItemCompletedAsync(CancellationToken cancellationToken) + => _callback.InvokeAsync((callback, cancellationToken) => callback.ItemCompletedAsync(_callbackId, cancellationToken), cancellationToken); #endregion @@ -106,21 +103,21 @@ public ValueTask ItemCompletedAsync() public IStreamingProgressTracker ProgressTracker => this; - public ValueTask ReportMessageAsync(string message) - => _callback.InvokeAsync((callback, cancellationToken) => callback.ReportMessageAsync(_callbackId, message), CancellationToken); + public ValueTask ReportMessageAsync(string message, CancellationToken cancellationToken) + => _callback.InvokeAsync((callback, cancellationToken) => callback.ReportMessageAsync(_callbackId, message, cancellationToken), cancellationToken); [Obsolete] - public ValueTask ReportProgressAsync(int current, int maximum) - => _callback.InvokeAsync((callback, cancellationToken) => callback.ReportProgressAsync(_callbackId, current, maximum), CancellationToken); + public ValueTask ReportProgressAsync(int current, int maximum, CancellationToken cancellationToken) + => _callback.InvokeAsync((callback, cancellationToken) => callback.ReportProgressAsync(_callbackId, current, maximum, cancellationToken), cancellationToken); - public ValueTask SetSearchTitleAsync(string title) - => _callback.InvokeAsync((callback, cancellationToken) => callback.SetSearchTitleAsync(_callbackId, title), CancellationToken); + public ValueTask SetSearchTitleAsync(string title, CancellationToken cancellationToken) + => _callback.InvokeAsync((callback, cancellationToken) => callback.SetSearchTitleAsync(_callbackId, title, cancellationToken), cancellationToken); - public ValueTask OnDefinitionFoundAsync(DefinitionItem definition) + public ValueTask OnDefinitionFoundAsync(DefinitionItem definition, CancellationToken cancellationToken) { var id = GetOrAddDefinitionItemId(definition); var dehydratedDefinition = SerializableDefinitionItem.Dehydrate(id, definition); - return _callback.InvokeAsync((callback, cancellationToken) => callback.OnDefinitionFoundAsync(_callbackId, dehydratedDefinition), CancellationToken); + return _callback.InvokeAsync((callback, cancellationToken) => callback.OnDefinitionFoundAsync(_callbackId, dehydratedDefinition, cancellationToken), cancellationToken); } private int GetOrAddDefinitionItemId(DefinitionItem item) @@ -137,11 +134,11 @@ private int GetOrAddDefinitionItemId(DefinitionItem item) } } - public ValueTask OnReferenceFoundAsync(SourceReferenceItem reference) + public ValueTask OnReferenceFoundAsync(SourceReferenceItem reference, CancellationToken cancellationToken) { var definitionItem = GetOrAddDefinitionItemId(reference.Definition); var dehydratedReference = SerializableSourceReferenceItem.Dehydrate(definitionItem, reference); - return _callback.InvokeAsync((callback, cancellationToken) => callback.OnReferenceFoundAsync(_callbackId, dehydratedReference), CancellationToken); + return _callback.InvokeAsync((callback, cancellationToken) => callback.OnReferenceFoundAsync(_callbackId, dehydratedReference, cancellationToken), cancellationToken); } #endregion diff --git a/src/Workspaces/Remote/ServiceHub/Services/SymbolFinder/RemoteSymbolFinderService.cs b/src/Workspaces/Remote/ServiceHub/Services/SymbolFinder/RemoteSymbolFinderService.cs index 83208f13592f1..d1fe987bbfb55 100644 --- a/src/Workspaces/Remote/ServiceHub/Services/SymbolFinder/RemoteSymbolFinderService.cs +++ b/src/Workspaces/Remote/ServiceHub/Services/SymbolFinder/RemoteSymbolFinderService.cs @@ -48,12 +48,12 @@ public ValueTask FindReferencesAsync( var symbol = await symbolAndProjectIdArg.TryRehydrateAsync( solution, cancellationToken).ConfigureAwait(false); - var progressCallback = new FindReferencesProgressCallback(solution, _callback, callbackId, cancellationToken); + var progressCallback = new FindReferencesProgressCallback(solution, _callback, callbackId); if (symbol == null) { - await progressCallback.OnStartedAsync().ConfigureAwait(false); - await progressCallback.OnCompletedAsync().ConfigureAwait(false); + await progressCallback.OnStartedAsync(cancellationToken).ConfigureAwait(false); + await progressCallback.OnCompletedAsync(cancellationToken).ConfigureAwait(false); return; } @@ -77,7 +77,7 @@ public ValueTask FindLiteralReferencesAsync(PinnedSolutionInfo solutionInfo, Rem var convertedType = System.Convert.ChangeType(value, typeCode); var solution = await GetSolutionAsync(solutionInfo, cancellationToken).ConfigureAwait(false); - var progressCallback = new FindLiteralReferencesProgressCallback(_callback, callbackId, cancellationToken); + var progressCallback = new FindLiteralReferencesProgressCallback(_callback, callbackId); await SymbolFinder.FindLiteralReferencesInCurrentProcessAsync( convertedType, solution, progressCallback, cancellationToken).ConfigureAwait(false); }, cancellationToken); @@ -185,26 +185,24 @@ private sealed class FindLiteralReferencesProgressCallback : IStreamingFindLiter { private readonly RemoteCallback _callback; private readonly RemoteServiceCallbackId _callbackId; - private readonly CancellationToken _cancellationToken; public IStreamingProgressTracker ProgressTracker { get; } - public FindLiteralReferencesProgressCallback(RemoteCallback callback, RemoteServiceCallbackId callbackId, CancellationToken cancellationToken) + public FindLiteralReferencesProgressCallback(RemoteCallback callback, RemoteServiceCallbackId callbackId) { _callback = callback; _callbackId = callbackId; - _cancellationToken = cancellationToken; ProgressTracker = this; } - public ValueTask OnReferenceFoundAsync(Document document, TextSpan span) - => _callback.InvokeAsync((callback, cancellationToken) => callback.OnLiteralReferenceFoundAsync(_callbackId, document.Id, span), _cancellationToken); + 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) - => _callback.InvokeAsync((callback, cancellationToken) => callback.AddLiteralItemsAsync(_callbackId, count), _cancellationToken); + public ValueTask AddItemsAsync(int count, CancellationToken cancellationToken) + => _callback.InvokeAsync((callback, cancellationToken) => callback.AddLiteralItemsAsync(_callbackId, count, cancellationToken), cancellationToken); - public ValueTask ItemCompletedAsync() - => _callback.InvokeAsync((callback, cancellationToken) => callback.LiteralItemCompletedAsync(_callbackId), _cancellationToken); + public ValueTask ItemCompletedAsync(CancellationToken cancellationToken) + => _callback.InvokeAsync((callback, cancellationToken) => callback.LiteralItemCompletedAsync(_callbackId, cancellationToken), cancellationToken); } private sealed class FindReferencesProgressCallback : IStreamingFindReferencesProgress, IStreamingProgressTracker @@ -212,53 +210,52 @@ private sealed class FindReferencesProgressCallback : IStreamingFindReferencesPr private readonly Solution _solution; private readonly RemoteCallback _callback; private readonly RemoteServiceCallbackId _callbackId; - private readonly CancellationToken _cancellationToken; public IStreamingProgressTracker ProgressTracker { get; } - public FindReferencesProgressCallback(Solution solution, RemoteCallback callback, RemoteServiceCallbackId callbackId, CancellationToken cancellationToken) + public FindReferencesProgressCallback(Solution solution, RemoteCallback callback, RemoteServiceCallbackId callbackId) { _solution = solution; _callback = callback; _callbackId = callbackId; - _cancellationToken = cancellationToken; ProgressTracker = this; } - public ValueTask OnStartedAsync() - => _callback.InvokeAsync((callback, cancellationToken) => callback.OnStartedAsync(_callbackId), _cancellationToken); + public ValueTask OnStartedAsync(CancellationToken cancellationToken) + => _callback.InvokeAsync((callback, cancellationToken) => callback.OnStartedAsync(_callbackId, cancellationToken), cancellationToken); - public ValueTask OnCompletedAsync() - => _callback.InvokeAsync((callback, cancellationToken) => callback.OnCompletedAsync(_callbackId), _cancellationToken); + public ValueTask OnCompletedAsync(CancellationToken cancellationToken) + => _callback.InvokeAsync((callback, cancellationToken) => callback.OnCompletedAsync(_callbackId, cancellationToken), cancellationToken); - public ValueTask OnFindInDocumentStartedAsync(Document document) - => _callback.InvokeAsync((callback, cancellationToken) => callback.OnFindInDocumentStartedAsync(_callbackId, document.Id), _cancellationToken); + public ValueTask OnFindInDocumentStartedAsync(Document document, CancellationToken cancellationToken) + => _callback.InvokeAsync((callback, cancellationToken) => callback.OnFindInDocumentStartedAsync(_callbackId, document.Id, cancellationToken), cancellationToken); - public ValueTask OnFindInDocumentCompletedAsync(Document document) - => _callback.InvokeAsync((callback, cancellationToken) => callback.OnFindInDocumentCompletedAsync(_callbackId, document.Id), _cancellationToken); + public ValueTask OnFindInDocumentCompletedAsync(Document document, CancellationToken cancellationToken) + => _callback.InvokeAsync((callback, cancellationToken) => callback.OnFindInDocumentCompletedAsync(_callbackId, document.Id, cancellationToken), cancellationToken); - public ValueTask OnDefinitionFoundAsync(SymbolGroup group) + public ValueTask OnDefinitionFoundAsync(SymbolGroup group, CancellationToken cancellationToken) { - var dehydratedGroup = SerializableSymbolGroup.Dehydrate(_solution, group, _cancellationToken); + var dehydratedGroup = SerializableSymbolGroup.Dehydrate(_solution, group, cancellationToken); return _callback.InvokeAsync( - (callback, cancellationToken) => callback.OnDefinitionFoundAsync(_callbackId, dehydratedGroup), _cancellationToken); + (callback, cancellationToken) => callback.OnDefinitionFoundAsync(_callbackId, dehydratedGroup, cancellationToken), cancellationToken); } - public ValueTask OnReferenceFoundAsync(SymbolGroup group, ISymbol definition, ReferenceLocation reference) + public ValueTask OnReferenceFoundAsync(SymbolGroup group, ISymbol definition, ReferenceLocation reference, CancellationToken cancellationToken) { - var dehydratedGroup = SerializableSymbolGroup.Dehydrate(_solution, group, _cancellationToken); - var dehydratedDefinition = SerializableSymbolAndProjectId.Dehydrate(_solution, definition, _cancellationToken); - var dehydratedReference = SerializableReferenceLocation.Dehydrate(reference, _cancellationToken); + var dehydratedGroup = SerializableSymbolGroup.Dehydrate(_solution, group, cancellationToken); + var dehydratedDefinition = SerializableSymbolAndProjectId.Dehydrate(_solution, definition, cancellationToken); + var dehydratedReference = SerializableReferenceLocation.Dehydrate(reference, cancellationToken); return _callback.InvokeAsync( - (callback, cancellationToken) => callback.OnReferenceFoundAsync(_callbackId, dehydratedGroup, dehydratedDefinition, dehydratedReference), _cancellationToken); + (callback, cancellationToken) => callback.OnReferenceFoundAsync( + _callbackId, dehydratedGroup, dehydratedDefinition, dehydratedReference, cancellationToken), cancellationToken); } - public ValueTask AddItemsAsync(int count) - => _callback.InvokeAsync((callback, cancellationToken) => callback.AddReferenceItemsAsync(_callbackId, count), _cancellationToken); + public ValueTask AddItemsAsync(int count, CancellationToken cancellationToken) + => _callback.InvokeAsync((callback, cancellationToken) => callback.AddReferenceItemsAsync(_callbackId, count, cancellationToken), cancellationToken); - public ValueTask ItemCompletedAsync() - => _callback.InvokeAsync((callback, cancellationToken) => callback.ReferenceItemCompletedAsync(_callbackId), _cancellationToken); + public ValueTask ItemCompletedAsync(CancellationToken cancellationToken) + => _callback.InvokeAsync((callback, cancellationToken) => callback.ReferenceItemCompletedAsync(_callbackId, cancellationToken), cancellationToken); } } }