private bool TryPresentInFindUsagesPresenter( SymbolMappingResult mapping, List <ISymbol> implementations, CancellationToken cancellationToken, out string message) { message = null; var presenter = GetFindUsagesPresenter(); if (presenter == null) { return(false); } var definitionItems = implementations.Select(s => s.ToDefinitionItem(mapping.Solution)).ToImmutableArrayOrEmpty(); var context = presenter.StartSearch(EditorFeaturesResources.Go_To_Implementation); try { foreach (var item in definitionItems) { context.OnDefinitionFoundAsync(item).Wait(cancellationToken); } } finally { context.OnCompletedAsync().Wait(cancellationToken); } return(true); }
private bool TryGoToImplementations(SymbolMappingResult mapping, IList <ISymbol> implementations, CancellationToken cancellationToken, out string message) { if (implementations.Count == 0) { message = EditorFeaturesResources.SymbolHasNoImplementations; return(false); } else if (implementations.Count == 1) { GoToDefinition.GoToDefinitionHelpers.TryGoToDefinition(implementations.Single(), mapping.Project, _navigableItemPresenters, cancellationToken); message = null; return(true); } else { // We have multiple symbols, so we'll build a list of all preferred locations for all the symbols var navigableItems = implementations.SelectMany( implementation => CreateItemsForImplementation(implementation, mapping.Solution)); var presenter = _navigableItemPresenters.First(); presenter.Value.DisplayResult(NavigableItemFactory.GetSymbolDisplayString(mapping.Project, mapping.Symbol), navigableItems); message = null; return(true); } }
private bool TryPresentInNavigableItemsPresenter( SymbolMappingResult mapping, List <ISymbol> implementations, out string message) { // We have multiple symbols, so we'll build a list of all preferred locations for all the symbols var navigableItems = implementations.SelectMany( implementation => CreateItemsForImplementation(implementation, mapping.Solution)); var presenter = _navigableItemPresenters.First(); var taggedParts = NavigableItemFactory.GetSymbolDisplayTaggedParts(mapping.Project, mapping.Symbol); presenter.Value.DisplayResult(taggedParts.JoinText(), navigableItems); message = null; return(true); }
private bool TryGoToImplementationOnMappedSymbol(SymbolMappingResult mapping, CancellationToken cancellationToken, out string message) { if (mapping.Symbol.IsInterfaceType() || mapping.Symbol.IsImplementableMember()) { var implementations = SymbolFinder.FindImplementationsAsync(mapping.Symbol, mapping.Solution, cancellationToken: cancellationToken) .WaitAndGetResult(cancellationToken) .Where(s => s.Locations.Any(l => l.IsInSource)) .ToList(); return(TryGoToImplementations(mapping, implementations, cancellationToken, out message)); } else if (mapping.Symbol.IsOverridable()) { var overrides = SymbolFinder.FindOverridesAsync(mapping.Symbol, mapping.Solution, cancellationToken: cancellationToken) .WaitAndGetResult(cancellationToken) .ToList(); // If the original symbol isn't abstract, then it's an implementation too if (!mapping.Symbol.IsAbstract) { overrides.Add(mapping.Symbol); } return(TryGoToImplementations(mapping, overrides, cancellationToken, out message)); } else { // This is something boring like a regular method or type, so we'll just go there directly if (GoToDefinition.GoToDefinitionHelpers.TryGoToDefinition(mapping.Symbol, mapping.Project, _navigableItemPresenters, cancellationToken)) { message = null; return(true); } else { message = EditorFeaturesResources.CannotNavigateToTheSymbol; return(false); } } }
private bool TryGoToImplementationOnMappedSymbol(SymbolMappingResult mapping, CancellationToken cancellationToken, out string message) { if (mapping.Symbol.IsInterfaceType() || mapping.Symbol.IsImplementableMember()) { var implementations = SymbolFinder.FindImplementationsAsync(mapping.Symbol, mapping.Solution, cancellationToken: cancellationToken) .WaitAndGetResult(cancellationToken); // It's important we use a HashSet here -- we may have cases in an inheritence hierarchy where more than one method // in an overrides chain implements the same interface method, and we want to duplicate those. The easiest way to do it // is to just use a HashSet. var implementationsAndOverrides = new HashSet <ISymbol>(); foreach (var implementation in implementations) { implementationsAndOverrides.Add(implementation); // FindImplementationsAsync will only return the base virtual/abstract method, not that method and the overrides // of the method. We should also include those. if (implementation.IsOverridable()) { implementationsAndOverrides.AddRange( SymbolFinder.FindOverridesAsync(implementation, mapping.Solution, cancellationToken: cancellationToken).WaitAndGetResult(cancellationToken)); } } return(TryGoToImplementations(implementationsAndOverrides, mapping, cancellationToken, out message)); } else if ((mapping.Symbol as INamedTypeSymbol)?.TypeKind == TypeKind.Class) { var implementations = SymbolFinder.FindDerivedClassesAsync((INamedTypeSymbol)mapping.Symbol, mapping.Solution, cancellationToken: cancellationToken) .WaitAndGetResult(cancellationToken) .Concat(mapping.Symbol); return(TryGoToImplementations(implementations, mapping, cancellationToken, out message)); } else if (mapping.Symbol.IsOverridable()) { var implementations = SymbolFinder.FindOverridesAsync(mapping.Symbol, mapping.Solution, cancellationToken: cancellationToken) .WaitAndGetResult(cancellationToken) .Concat(mapping.Symbol); return(TryGoToImplementations(implementations, mapping, cancellationToken, out message)); } else { // This is something boring like a regular method or type, so we'll just go there directly if (GoToDefinition.GoToDefinitionHelpers.TryGoToDefinition( mapping.Symbol, mapping.Project, _navigableItemPresenters, _streamingPresenters, cancellationToken)) { message = null; return(true); } message = EditorFeaturesResources.Cannot_navigate_to_the_symbol_under_the_caret; return(false); } }
private bool TryGoToImplementations(IEnumerable <ISymbol> candidateImplementations, SymbolMappingResult mapping, CancellationToken cancellationToken, out string message) { var implementations = candidateImplementations .Where(s => !s.IsAbstract && s.Locations.Any(l => l.IsInSource)) .ToList(); if (implementations.Count == 0) { message = EditorFeaturesResources.The_symbol_has_no_implementations; return(false); } else if (implementations.Count == 1) { GoToDefinition.GoToDefinitionHelpers.TryGoToDefinition( implementations.Single(), mapping.Project, _navigableItemPresenters, _streamingPresenters, cancellationToken); message = null; return(true); } else { return(TryPresentInFindUsagesPresenter(mapping, implementations, cancellationToken, out message) || TryPresentInNavigableItemsPresenter(mapping, implementations, out message)); } }
private bool TryGoToImplementations(IEnumerable <ISymbol> candidateImplementations, SymbolMappingResult mapping, CancellationToken cancellationToken, out string message) { var implementations = candidateImplementations .Where(s => !s.IsAbstract && s.Locations.Any(l => l.IsInSource)) .ToList(); if (implementations.Count == 0) { message = EditorFeaturesResources.SymbolHasNoImplementations; return(false); } else if (implementations.Count == 1) { GoToDefinition.GoToDefinitionHelpers.TryGoToDefinition(implementations.Single(), mapping.Project, _externalDefinitionProviders, _navigableItemPresenters, cancellationToken); message = null; return(true); } else { // We have multiple symbols, so we'll build a list of all preferred locations for all the symbols var navigableItems = implementations.SelectMany( implementation => CreateItemsForImplementation(implementation, mapping.Solution)); var presenter = _navigableItemPresenters.First(); presenter.Value.DisplayResult(NavigableItemFactory.GetSymbolDisplayString(mapping.Project, mapping.Symbol), navigableItems); message = null; return(true); } }