Пример #1
0
        private async Task <bool> NavigateThroughInterfaceImplementationsAsync(Document currentDocument, ISymbol selectedSymbol, SnapshotPoint currentPosition)
        {
            if (_interfaceNavigationState != null)
            {
                // check if count is greater than 2
                if (_interfaceNavigationState.SymbolsToVisit.Count() > 1)
                {
                    // check if user didn't move elsewhere
                    if (selectedSymbol.ToString() == _interfaceNavigationState.SymbolsToVisit.First().ToString())
                    {
                        _interfaceNavigationState.SymbolsToVisit.RemoveAt(0);
                        return(TryGoToDefinition(currentDocument.Project, _interfaceNavigationState.SymbolsToVisit.First()));
                    }
                    else
                    {
                        _interfaceNavigationState = null;
                    }
                }
                else if (_interfaceNavigationState.SymbolsToVisit.Count() == 1)
                {
                    if (selectedSymbol.ToString() == _interfaceNavigationState.SymbolsToVisit.First().ToString())
                    {
                        return(await GotoPositionAsync(currentDocument, _interfaceNavigationState.NavigateToPositionAtTheEnd));
                    }
                }
            }

            return(false);
        }
Пример #2
0
        public async Task <bool> GoToImplementationAsync()
        {
            var wpfTextView = await GetWpfTextViewAsync();

            var currentPosition = wpfTextView.Caret.Position.BufferPosition;

            var document = currentPosition.Snapshot.GetOpenDocumentInCurrentContextWithChanges();

            if (document == null)
            {
                // no document found => we can't help
                return(false);
            }

            var semanticModel = await document.GetSemanticModelAsync();

            // find symbol at caret position
            var selectedSymbol = await SymbolFinder.FindSymbolAtPositionAsync(semanticModel, currentPosition.Position, document.Project.Solution.Workspace);

            if (selectedSymbol == null)
            {
                // no symbol selected => we can't help
                return(false);
            }

            if (await NavigateThroughInterfaceImplementationsAsync(document, selectedSymbol, currentPosition))
            {
                return(true);
            }

            _interfaceNavigationState = null;

            // search implementation only if method or property symbol
            if (selectedSymbol is IMethodSymbol || selectedSymbol is IPropertySymbol)
            {
                try
                {
                    // prio 1: we're assuming it's an interface method/property => find implementations
                    var implSymbols = await SymbolFinder.FindImplementationsAsync(selectedSymbol, document.Project.Solution);

                    if (implSymbols.Any())
                    {
                        var symbolsToVisit = new List <ISymbol>();
                        symbolsToVisit.Add(selectedSymbol);
                        symbolsToVisit.AddRange(implSymbols);
                        _interfaceNavigationState = new NavigationState
                        {
                            SymbolsToVisit             = symbolsToVisit,
                            NavigateToPositionAtTheEnd = currentPosition
                        };
                        return(await TryGoToDefinitionOrNavigateBackwardAsync(document, selectedSymbol, currentPosition));
                    }

                    // prio 2: we assume that it is an implementation of an interface method/property
                    // we will jump betweem each implementation
                    var interfaceSymbols = await SymbolFinder.FindImplementedInterfaceMembersAsync(selectedSymbol, document.Project.Solution);

                    if (interfaceSymbols.Count() > 0)
                    {
                        var implInterfaceSymbols = new List <ISymbol>();
                        foreach (var interfaceSymbol in interfaceSymbols)
                        {
                            implInterfaceSymbols.AddRange(await SymbolFinder.FindImplementationsAsync(interfaceSymbol, document.Project.Solution));
                        }

                        if (implInterfaceSymbols.Any())
                        {
                            NavigateTo(implInterfaceSymbols, document.Project, selectedSymbol);
                            return(true);
                        }
                    }

                    // prio 3: we assume override or abstract
                    var overrideSymbols = await SymbolFinder.FindOverridesAsync(selectedSymbol, document.Project.Solution);

                    if (overrideSymbols.Any())
                    {
                        NavigateTo(overrideSymbols, document.Project, selectedSymbol);
                        return(true);
                    }
                }
                catch (System.Exception ex)
                {
                    ShowMessageBox($"{ex.Message}:\n{ex.StackTrace}");
                }
            }

            // default behaviour: Go to definition as F12 or NavigateBackward Ctrl + -
            return(await TryGoToDefinitionOrNavigateBackwardAsync(document, selectedSymbol, currentPosition));
        }