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;
                }
            }
        }
コード例 #2
0
        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, _externalDefinitionProviders, _navigableItemPresenters, cancellationToken))
                {
                    message = null;
                    return true;
                }
                else
                {
                    message = EditorFeaturesResources.CannotNavigateToTheSymbol;
                    return false;
                }
            }
        }
コード例 #3
0
        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;
            }
        }
        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;
            }
        }