private async void StreamingFindReferences( Document document, int caretPosition, IFindUsagesService findUsagesService, IStreamingFindUsagesPresenter presenter) { try { using (var token = _asyncListener.BeginAsyncOperation(nameof(StreamingFindReferences))) { // 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); using (Logger.LogBlock( FunctionId.CommandHandler_FindAllReference, KeyValueLogMessage.Create(LogType.UserAction, m => m["type"] = "streaming"), context.CancellationToken)) { await findUsagesService.FindReferencesAsync(document, caretPosition, context).ConfigureAwait(false); // Note: we don't need to put this in a finally. The only time we might not hit // this is if cancellation or another error gets thrown. In the former case, // 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); } } } catch (OperationCanceledException) { } catch (Exception e) when(FatalError.ReportWithoutCrash(e)) { } }
public InheritanceMargin( IThreadingContext threadingContext, IStreamingFindUsagesPresenter streamingFindUsagesPresenter, ClassificationTypeMap classificationTypeMap, IClassificationFormatMap classificationFormatMap, IUIThreadOperationExecutor operationExecutor, InheritanceMarginTag tag, IWpfTextView textView) { _threadingContext = threadingContext; _streamingFindUsagesPresenter = streamingFindUsagesPresenter; _workspace = tag.Workspace; _operationExecutor = operationExecutor; _textView = textView; InitializeComponent(); var viewModel = InheritanceMarginViewModel.Create(classificationTypeMap, classificationFormatMap, tag, textView.ZoomLevel); DataContext = viewModel; ContextMenu.DataContext = viewModel; ToolTip = new ToolTip { Content = viewModel.ToolTipTextBlock, Style = (Style)FindResource("ToolTipStyle") }; }
private static void NavigateToQuickInfoTarget( string navigationTarget, Document document, IThreadingContext threadingContext, IStreamingFindUsagesPresenter streamingPresenter) { SymbolKeyResolution resolvedSymbolKey; try { resolvedSymbolKey = SymbolKey.ResolveString(navigationTarget, document.Project.GetRequiredCompilationAsync(CancellationToken.None).WaitAndGetResult(CancellationToken.None), cancellationToken: CancellationToken.None); } catch { // Ignore symbol resolution failures. It likely is just a badly formed URI. return; } if (resolvedSymbolKey.GetAnySymbol() is { } symbol) { GoToDefinitionHelpers.TryGoToDefinition(symbol, document.Project.Solution, threadingContext, streamingPresenter, CancellationToken.None); return; } }
private async Task StreamingFindReferencesAsync( Document document, int caretPosition, IStreamingFindUsagesPresenter presenter) { try { // first, let's see if we even have a comment, otherwise there's no use in starting a search var relevantSymbol = await FindUsagesHelpers.GetRelevantSymbolAndProjectAtPositionAsync(document, caretPosition, new CancellationToken()).ConfigureAwait(false); var symbol = relevantSymbol?.symbol; if (symbol == null) return; // would be useful if we could notify the user why we didn't do anything // maybe using something like an info bar? var findUsagesService = document.GetLanguageService<IFindUsagesService>(); using var token = _asyncListener.BeginAsyncOperation(nameof(StreamingFindReferencesAsync)); var (context, cancellationToken) = presenter.StartSearch(EditorFeaturesResources.Find_References, supportsReferences: true); using (Logger.LogBlock( FunctionId.CommandHandler_FindAllReference, KeyValueLogMessage.Create(LogType.UserAction, m => m["type"] = "streaming"), cancellationToken)) { var symbolsToLookup = new List<ISymbol>(); foreach (var curSymbol in symbol.ContainingType.GetMembers() .Where(m => m.Kind == symbol.Kind && m.Name == symbol.Name)) { if (!document.Project.TryGetCompilation(out var compilation)) { // TODO: should we do anything more here? continue; } foreach (var sym in SymbolFinder.FindSimilarSymbols(curSymbol, compilation, cancellationToken)) { // assumption here is, that FindSimilarSymbols returns symbols inside same project var symbolsToAdd = await GatherSymbolsAsync(sym, document.Project.Solution, cancellationToken).ConfigureAwait(false); symbolsToLookup.AddRange(symbolsToAdd); } } foreach (var candidate in symbolsToLookup) { await AbstractFindUsagesService.FindSymbolReferencesAsync(context, candidate, document.Project, cancellationToken).ConfigureAwait(false); } // Note: we don't need to put this in a finally. The only time we might not hit // this is if cancellation or another error gets thrown. In the former case, // 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(cancellationToken).ConfigureAwait(false); } } catch (OperationCanceledException) { } catch (Exception e) when (FatalError.ReportAndCatch(e)) { } }
private static void NavigateToQuickInfoTarget(string navigationTarget, Document document, IStreamingFindUsagesPresenter streamingPresenter) { var navigateToLinkService = document.Project.Solution.Workspace.Services.GetRequiredService <INavigateToLinkService>(); if (Uri.TryCreate(navigationTarget, UriKind.Absolute, out var absoluteUri)) { navigateToLinkService.TryNavigateToLinkAsync(absoluteUri, CancellationToken.None); return; } SymbolKeyResolution resolvedSymbolKey; try { resolvedSymbolKey = SymbolKey.ResolveString(navigationTarget, document.Project.GetCompilationAsync(CancellationToken.None).WaitAndGetResult(CancellationToken.None), cancellationToken: CancellationToken.None); } catch { // Ignore symbol resolution failures. It likely is just a badly formed URI. return; } if (resolvedSymbolKey.GetAnySymbol() is { } symbol) { GoToDefinitionHelpers.TryGoToDefinition(symbol, document.Project, streamingPresenter, CancellationToken.None); return; } }
public CSharpGoToDefinitionService( IThreadingContext threadingContext, IStreamingFindUsagesPresenter streamingPresenter) : base(threadingContext, streamingPresenter) { }
public VBLspGotoDefinitionService(IStreamingFindUsagesPresenter streamingPresenter, VisualBasicLspClientServiceFactory vbLspClientServiceFactory, RemoteLanguageServiceWorkspace remoteWorkspace, IThreadingContext threadingContext) : base(streamingPresenter, vbLspClientServiceFactory, remoteWorkspace, threadingContext) { }
public CSharpLspGotoDefinitionService(IStreamingFindUsagesPresenter streamingPresenter, CSharpLspClientServiceFactory csharpLspClientServiceFactory, RemoteLanguageServiceWorkspace remoteWorkspace, IThreadingContext threadingContext) : base(streamingPresenter, csharpLspClientServiceFactory, remoteWorkspace, threadingContext) { }
public static async Task <bool> TryNavigateToOrPresentItemsAsync( this IStreamingFindUsagesPresenter presenter, IThreadingContext threadingContext, Workspace workspace, string title, ImmutableArray <DefinitionItem> items, CancellationToken cancellationToken) { // Can only navigate or present items on UI thread. await threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); // Ignore any definitions that we can't navigate to. var definitions = items.WhereAsArray(d => d.CanNavigateTo(workspace, cancellationToken)); // See if there's a third party external item we can navigate to. If so, defer // to that item and finish. var externalItems = definitions.WhereAsArray(d => d.IsExternal); foreach (var item in externalItems) { // If we're directly going to a location we need to activate the preview so // that focus follows to the new cursor position. This behavior is expected // because we are only going to navigate once successfully if (item.TryNavigateTo(workspace, showInPreviewTab: true, activateTab: true, cancellationToken)) { return(true); } } var nonExternalItems = definitions.WhereAsArray(d => !d.IsExternal); if (nonExternalItems.Length == 0) { return(false); } if (nonExternalItems.Length == 1 && nonExternalItems[0].SourceSpans.Length <= 1) { // There was only one location to navigate to. Just directly go to that location. If we're directly // going to a location we need to activate the preview so that focus follows to the new cursor position. return(nonExternalItems[0].TryNavigateTo(workspace, showInPreviewTab: true, activateTab: true, cancellationToken)); } if (presenter != null) { // 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. var context = presenter.StartSearch(title, supportsReferences: false); foreach (var definition in nonExternalItems) { await context.OnDefinitionFoundAsync(definition).ConfigureAwait(false); } // Note: we don't need to put this in a finally. The only time we might not hit // this is if cancellation or another error gets thrown. In the former case, // 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 code in this particular context. await context.OnCompletedAsync().ConfigureAwait(false); } return(true); }
public TypeScriptLspGotoDefinitionService(IStreamingFindUsagesPresenter streamingPresenter, TypeScriptLspClientServiceFactory typeScriptLspClientServiceFactory, RemoteLanguageServiceWorkspace remoteWorkspace, IThreadingContext threadingContext) : base(streamingPresenter, typeScriptLspClientServiceFactory, remoteWorkspace, threadingContext) { }
private async Task FindExtensionMethodsAsync( Document document, int caretPosition, IStreamingFindUsagesPresenter presenter, CancellationToken cancellationToken ) { try { using var token = _asyncListener.BeginAsyncOperation( nameof(FindExtensionMethodsAsync) ); var context = presenter.StartSearch( EditorFeaturesResources.Navigating, supportsReferences: true, cancellationToken ); using ( Logger.LogBlock( FunctionId.CommandHandler_FindAllReference, KeyValueLogMessage.Create(LogType.UserAction, m => m["type"] = "streaming"), context.CancellationToken ) ) { #pragma warning disable CA2007 // Consider calling ConfigureAwait on the awaited task var candidateSymbolProjectPair = await FindUsagesHelpers.GetRelevantSymbolAndProjectAtPositionAsync( document, caretPosition, context.CancellationToken ); #pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task var symbol = candidateSymbolProjectPair?.symbol as INamedTypeSymbol; // if we didn't get the right symbol, just abort if (symbol == null) { await context.OnCompletedAsync().ConfigureAwait(false); return; } Compilation compilation; if (!document.Project.TryGetCompilation(out compilation)) { await context.OnCompletedAsync().ConfigureAwait(false); return; } var solution = document.Project.Solution; foreach ( var type in compilation.Assembly.GlobalNamespace.GetAllTypes( context.CancellationToken ) ) { if (!type.MightContainExtensionMethods) { continue; } foreach ( var extMethod in type.GetMembers() .OfType <IMethodSymbol>() .Where(method => method.IsExtensionMethod) ) { if (context.CancellationToken.IsCancellationRequested) { break; } var reducedMethod = extMethod.ReduceExtensionMethod(symbol); if (reducedMethod != null) { var loc = extMethod.Locations.First(); var sourceDefinition = await SymbolFinder .FindSourceDefinitionAsync( reducedMethod, solution, context.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 definitionItem = reducedMethod.ToNonClassifiedDefinitionItem(solution, true); #pragma warning disable CA2007 // Consider calling ConfigureAwait on the awaited task await context.OnDefinitionFoundAsync(definitionItem); #pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task } } } } await context.OnCompletedAsync().ConfigureAwait(false); } } catch (OperationCanceledException) { } catch (Exception e) when(FatalError.ReportAndCatch(e)) { } }
public StackTraceExplorerTab(IThreadingContext threadingContext, VisualStudioWorkspace workspace, IClassificationFormatMap formatMap, ClassificationTypeMap typeMap, IStreamingFindUsagesPresenter streamingFindUsagesPresenter, int nameIndex) { NameIndex = nameIndex; _stackExplorerVM = new StackTraceExplorerViewModel(threadingContext, workspace, typeMap, formatMap, streamingFindUsagesPresenter); Content = new StackTraceExplorer(_stackExplorerVM); CloseClick = new DelegateCommand(_ => { OnClosed?.Invoke(this, null); }); }
public CSharpGoToDefinitionService(IStreamingFindUsagesPresenter streamingPresenter) : base(streamingPresenter) { }
private async Task StreamingFindBaseSymbolsAsync( Document document, int caretPosition, IStreamingFindUsagesPresenter presenter, CancellationToken cancellationToken ) { try { using var token = _asyncListener.BeginAsyncOperation( nameof(StreamingFindBaseSymbolsAsync) ); var context = presenter.StartSearch( EditorFeaturesResources.Navigating, supportsReferences: true, cancellationToken ); using ( Logger.LogBlock( FunctionId.CommandHandler_FindAllReference, KeyValueLogMessage.Create(LogType.UserAction, m => m["type"] = "streaming"), context.CancellationToken ) ) { try { #pragma warning disable CA2007 // Consider calling ConfigureAwait on the awaited task var relevantSymbol = await FindUsagesHelpers.GetRelevantSymbolAndProjectAtPositionAsync( document, caretPosition, context.CancellationToken ); #pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task var overriddenSymbol = relevantSymbol?.symbol.GetOverriddenMember(); while (overriddenSymbol != null) { if (context.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); #pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task // try getting the next one overriddenSymbol = overriddenSymbol.GetOverriddenMember(); } } finally { await context.OnCompletedAsync().ConfigureAwait(false); } } } catch (OperationCanceledException) { } catch (Exception e) when(FatalError.ReportAndCatch(e)) { } }
protected AbstractGoToDefinitionService(IStreamingFindUsagesPresenter streamingPresenter) { _streamingPresenter = streamingPresenter; }
public static async Task <bool> TryNavigateToOrPresentItemsAsync( this IStreamingFindUsagesPresenter presenter, IThreadingContext threadingContext, Workspace workspace, string title, ImmutableArray <DefinitionItem> items, CancellationToken cancellationToken) { // Can only navigate or present items on UI thread. await threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); // Ignore any definitions that we can't navigate to. var definitions = items.WhereAsArray(d => d.CanNavigateTo(workspace, cancellationToken)); // See if there's a third party external item we can navigate to. If so, defer // to that item and finish. var externalItems = definitions.WhereAsArray(d => d.IsExternal); foreach (var item in externalItems) { // If we're directly going to a location we need to activate the preview so // that focus follows to the new cursor position. This behavior is expected // because we are only going to navigate once successfully if (item.TryNavigateTo(workspace, showInPreviewTab: true, activateTab: true, cancellationToken)) { return(true); } } var nonExternalItems = definitions.WhereAsArray(d => !d.IsExternal); if (nonExternalItems.Length == 0) { return(false); } if (nonExternalItems.Length == 1 && nonExternalItems[0].SourceSpans.Length <= 1) { // There was only one location to navigate to. Just directly go to that location. If we're directly // going to a location we need to activate the preview so that focus follows to the new cursor position. return(nonExternalItems[0].TryNavigateTo(workspace, showInPreviewTab: true, activateTab: true, cancellationToken)); } if (presenter != null) { // 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); try { foreach (var definition in nonExternalItems) { await context.OnDefinitionFoundAsync(definition).ConfigureAwait(false); } } finally { await context.OnCompletedAsync().ConfigureAwait(false); } } return(true); }
public VSTypeScriptStreamingFindUsagesPresenterAccessor(IStreamingFindUsagesPresenter underlyingObject) => _underlyingObject = underlyingObject;
public StackTraceExplorerRootViewModel(IThreadingContext threadingContext, VisualStudioWorkspace workspace, IClassificationFormatMap formatMap, ClassificationTypeMap typeMap, IStreamingFindUsagesPresenter streamingFindUsagesPresenter) { _threadingContext = threadingContext; _workspace = workspace; _formatMap = formatMap; _typeMap = typeMap; _streamingFindUsagesPresenter = streamingFindUsagesPresenter; }
private async Task FindImplementingMembersAsync( Document document, int caretPosition, IStreamingFindUsagesPresenter presenter, CancellationToken cancellationToken ) { try { using var token = _asyncListener.BeginAsyncOperation( nameof(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 ); using ( Logger.LogBlock( FunctionId.CommandHandler_FindAllReference, KeyValueLogMessage.Create(LogType.UserAction, m => m["type"] = "streaming"), context.CancellationToken ) ) { try { #pragma warning disable CA2007 // Consider calling ConfigureAwait on the awaited task var relevantSymbol = await FindUsagesHelpers.GetRelevantSymbolAndProjectAtPositionAsync( document, caretPosition, context.CancellationToken ); #pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task var interfaceSymbol = relevantSymbol?.symbol as INamedTypeSymbol; if ( interfaceSymbol == null || interfaceSymbol.TypeKind != TypeKind.Interface ) { //looks like it's not a relevant symbol return; } // we now need to find the class that implements this particular interface, at the // caret position, or somewhere around it SyntaxNode nodeRoot; if (!document.TryGetSyntaxRoot(out nodeRoot)) { return; } #pragma warning disable CA2007 // Consider calling ConfigureAwait on the awaited task var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken); #pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task var documentToken = nodeRoot.FindToken(caretPosition); if (!documentToken.Span.IntersectsWith(caretPosition)) { return; // looks like it's not relevant } // the parents should bring us to the class definition var parentTypeNode = documentToken.Parent?.Parent?.Parent?.Parent; #pragma warning disable CA2007 // Consider calling ConfigureAwait on the awaited task var compilation = await document.Project.GetCompilationAsync( cancellationToken ); #pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task // let's finally get our implementing type var namedTypeSymbol = compilation .GetSemanticModel(syntaxTree) .GetDeclaredSymbol( parentTypeNode, cancellationToken: cancellationToken ) as INamedTypeSymbol; // unless something went wrong, and we got an empty symbol, if (namedTypeSymbol == null) { return; } // 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 ); #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 ); #pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task } } finally { await context.OnCompletedAsync().ConfigureAwait(false); } } } catch (OperationCanceledException) { } catch (Exception e) when(FatalError.ReportAndCatch(e)) { } }
public GoToImplementationCommandHandler(IStreamingFindUsagesPresenter streamingPresenter) { _streamingPresenter = streamingPresenter; }
public GoToBaseCommandHandler( IThreadingContext threadingContext, IStreamingFindUsagesPresenter streamingPresenter) : base(threadingContext, streamingPresenter) { }
private async Task FindMemberOverloadsAsync( Document document, int caretPosition, IStreamingFindUsagesPresenter presenter, CancellationToken cancellationToken ) { try { using var token = _asyncListener.BeginAsyncOperation( nameof(FindMemberOverloadsAsync) ); var context = presenter.StartSearch( EditorFeaturesResources.Navigating, supportsReferences: true, cancellationToken ); using ( Logger.LogBlock( FunctionId.CommandHandler_FindAllReference, KeyValueLogMessage.Create(LogType.UserAction, m => m["type"] = "streaming"), context.CancellationToken ) ) { try { #pragma warning disable CA2007 // Consider calling ConfigureAwait on the awaited task var candidateSymbolProjectPair = await FindUsagesHelpers.GetRelevantSymbolAndProjectAtPositionAsync( document, caretPosition, context.CancellationToken ); #pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task // we need to get the containing type (i.e. class) var symbol = candidateSymbolProjectPair?.symbol; // if we didn't get any symbol, that's it if (symbol == null || symbol.ContainingType == null) { return; } foreach ( var curSymbol in symbol.ContainingType .GetMembers() .Where(m => m.Kind == symbol.Kind && m.Name == symbol.Name) ) { var definitionItem = curSymbol.ToNonClassifiedDefinitionItem( document.Project.Solution, true ); #pragma warning disable CA2007 // Consider calling ConfigureAwait on the awaited task await context.OnDefinitionFoundAsync(definitionItem); #pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task } } finally { await context.OnCompletedAsync().ConfigureAwait(false); } } } catch (OperationCanceledException) { } catch (Exception e) when(FatalError.ReportAndCatch(e)) { } }