protected async override void Run()
        {
            var doc = IdeApp.Workbench.ActiveDocument;

            if (doc == null || doc.FileName == FilePath.Null)
            {
                return;
            }

            var metadata = Counters.CreateNavigateToMetadata("MemberOverloads");

            using (var timer = Counters.NavigateTo.BeginTiming(metadata)) {
                var info = await RefactoringSymbolInfo.GetSymbolInfoAsync(doc, doc.Editor);

                var sym = info.Symbol ?? info.DeclaredSymbol;
                if (sym == null)
                {
                    metadata.SetUserFault();
                    return;
                }

                using (var source = new CancellationTokenSource()) {
                    try {
                        FindOverloads(sym, source);
                        metadata.SetResult(true);
                    } finally {
                        metadata.UpdateUserCancellation(source.Token);
                    }
                }
            }
        }
Exemple #2
0
        protected async override Task <UsageData> ResolveAsync(CancellationToken token)
        {
            var doc = IdeApp.Workbench.ActiveDocument;

            if (doc == null || doc.FileName == FilePath.Null)
            {
                return(new UsageData());
            }
            var analysisDocument = doc.AnalysisDocument;

            if (analysisDocument == null)
            {
                return(new UsageData());
            }

            var symbolInfo = await RefactoringSymbolInfo.GetSymbolInfoAsync(doc, doc.Editor.CaretOffset, token);

            if (symbolInfo.Symbol == null && symbolInfo.DeclaredSymbol == null)
            {
                return(new UsageData());
            }
            if (symbolInfo.Symbol != null && !symbolInfo.Node.IsKind(SyntaxKind.IdentifierName))
            {
                return(new UsageData());
            }
            return(new UsageData {
                Document = analysisDocument,
                SymbolInfo = symbolInfo
            });
        }
Exemple #3
0
        Task FindImplementingSymbols(Compilation compilation, RefactoringSymbolInfo info, CancellationTokenSource cancellationTokenSource)
        {
            var interfaceType = info.Symbol as ITypeSymbol;

            if (interfaceType == null)
            {
                return(Task.FromResult(0));
            }

            return(Task.Run(delegate {
                var searchMonitor = IdeApp.Workbench.ProgressMonitors.GetSearchProgressMonitor(true, true);
                using (var monitor = searchMonitor.WithCancellationSource(cancellationTokenSource)) {
                    var parentTypeNode = info.Node?.Parent?.Parent?.Parent;
                    if (parentTypeNode == null)
                    {
                        return;
                    }
                    var implementingType = info.Model.GetDeclaredSymbol(parentTypeNode) as INamedTypeSymbol;
                    if (implementingType == null)
                    {
                        return;
                    }
                    foreach (var interfaceMember in interfaceType.GetMembers())
                    {
                        if (monitor.CancellationToken.IsCancellationRequested)
                        {
                            return;
                        }
                        var impl = implementingType.FindImplementationForInterfaceMember(interfaceMember);
                        if (impl == null)
                        {
                            continue;
                        }
                        var loc = impl.Locations.First();
                        searchMonitor.ReportResult(new MemberReference(impl, loc.SourceTree.FilePath, loc.SourceSpan.Start, loc.SourceSpan.Length));
                    }
                    foreach (var iFace in interfaceType.AllInterfaces)
                    {
                        foreach (var interfaceMember in iFace.GetMembers())
                        {
                            if (monitor.CancellationToken.IsCancellationRequested)
                            {
                                return;
                            }

                            var impl = implementingType.FindImplementationForInterfaceMember(interfaceMember);
                            if (impl == null)
                            {
                                continue;
                            }
                            var loc = impl.Locations.First();
                            searchMonitor.ReportResult(new MemberReference(impl, loc.SourceTree.FilePath, loc.SourceSpan.Start, loc.SourceSpan.Length));
                        }
                    }
                }
            }));
        }
Exemple #4
0
        internal static async Task <ISymbol> GetSymbolAtCaret(Ide.Gui.Document doc)
        {
            if (doc == null)
            {
                return(null);
            }
            var info = await RefactoringSymbolInfo.GetSymbolInfoAsync(doc, doc.Editor);

            return(info.Symbol ?? info.DeclaredSymbol);
        }
        internal static async Task <ISymbol> GetSymbolAtCaret(Ide.Gui.Document doc, CancellationToken cancelToken = default)
        {
            if (doc == null || doc.Editor == null)
            {
                return(null);
            }
            var info = await RefactoringSymbolInfo.GetSymbolInfoAsync(doc.DocumentContext, doc.Editor, cancelToken);

            return(info.Symbol ?? info.DeclaredSymbol);
        }
Exemple #6
0
 public static void JumpToDeclaration(MonoDevelop.Ide.Gui.Document doc, RefactoringSymbolInfo info)
 {
     if (info.Symbol != null)
     {
         RefactoringService.RoslynJumpToDeclaration(info.Symbol, doc.Project);
     }
     if (info.CandidateSymbols.Length > 0)
     {
         RefactoringService.RoslynJumpToDeclaration(info.CandidateSymbols[0], doc.Project);
     }
 }
        internal void Run(TextEditor editor, DocumentContext ctx)
        {
            var info = RefactoringSymbolInfo.GetSymbolInfoAsync(ctx, editor.CaretOffset).Result;
            var sym  = info.DeclaredSymbol ?? info.Symbol;

            if (!CanRename(sym))
            {
                return;
            }
            new RenameRefactoring().Rename(sym);
        }
Exemple #8
0
        internal static async System.Threading.Tasks.Task <INamedTypeSymbol> GetNamedTypeAtCaret(Ide.Gui.Document doc)
        {
            if (doc == null)
            {
                return(null);
            }
            var info = await RefactoringSymbolInfo.GetSymbolInfoAsync(doc, doc.Editor);

            var sym = info.Symbol ?? info.DeclaredSymbol;

            return(sym as INamedTypeSymbol);
        }
Exemple #9
0
        internal static async System.Threading.Tasks.Task <INamedTypeSymbol> GetNamedTypeAtCaret(Ide.Gui.Document doc, CancellationToken cancellationToken = default)
        {
            if (doc == null || doc.Editor == null)
            {
                return(null);
            }
            var info = await RefactoringSymbolInfo.GetSymbolInfoAsync(doc.DocumentContext, doc.Editor, cancellationToken);

            var sym = info.Symbol ?? info.DeclaredSymbol;

            return(sym as INamedTypeSymbol);
        }
        public async void Update(CommandInfo info)
        {
            var doc = IdeApp.Workbench.ActiveDocument;

            if (doc == null || doc.FileName == FilePath.Null || doc.ParsedDocument == null)
            {
                info.Enabled = false;
                return;
            }
            var rinfo = await RefactoringSymbolInfo.GetSymbolInfoAsync(doc, doc.Editor.CaretOffset);

            info.Enabled = rinfo.DeclaredSymbol != null;
        }
        public async static Task Run(MonoDevelop.Ide.Gui.Document doc)
        {
            if (!doc.Editor.IsSomethingSelected)
            {
                return;
            }
            var ad = doc.AnalysisDocument;

            if (ad == null || !await IsValid(doc))
            {
                return;
            }
            try {
                var selectionRange = doc.Editor.SelectionRange;
                var token          = default(CancellationToken);
                var selection      = new CSharpSelectionValidator(await SemanticDocument.CreateAsync(ad, token).ConfigureAwait(false), new TextSpan(selectionRange.Offset, selectionRange.Length), doc.GetOptionSet());
                var result         = await selection.GetValidSelectionAsync(token).ConfigureAwait(false);

                if (!result.ContainsValidContext)
                {
                    return;
                }
                var extractor        = new CSharpMethodExtractor((CSharpSelectionResult)result);
                var extractionResult = await extractor.ExtractMethodAsync(token).ConfigureAwait(false);

                var changes = await extractionResult.Document.GetTextChangesAsync(ad, token);

                using (var undo = doc.Editor.OpenUndoGroup()) {
                    foreach (var change in changes.OrderByDescending(ts => ts.Span.Start))
                    {
                        doc.Editor.ReplaceText(change.Span.Start, change.Span.Length, change.NewText);
                    }
                    // hack to remove the redundant private modifier.
                    if (doc.Editor.GetTextAt(extractionResult.MethodDeclarationNode.SpanStart, "private ".Length) == "private ")
                    {
                        doc.Editor.RemoveText(extractionResult.MethodDeclarationNode.SpanStart, "private ".Length);
                    }
                }
                await doc.UpdateParseDocument();

                var info = RefactoringSymbolInfo.GetSymbolInfoAsync(doc, extractionResult.InvocationNameToken.Span.Start).Result;
                var sym  = info.DeclaredSymbol ?? info.Symbol;
                if (sym != null)
                {
                    await new MonoDevelop.Refactoring.Rename.RenameRefactoring().Rename(sym);
                }
            }
            catch (Exception e) {
                LoggingService.LogError("Error while extracting method", e);
            }
        }
        public async void Run(object data)
        {
            var doc = IdeApp.Workbench.ActiveDocument;

            if (doc == null || doc.FileName == FilePath.Null)
            {
                return;
            }
            var info = await RefactoringSymbolInfo.GetSymbolInfoAsync(doc, doc.Editor.CaretOffset);

            if (info.DeclaredSymbol != null)
            {
                FindDerivedSymbols(info.DeclaredSymbol);
            }
        }
        internal async Task Run(TextEditor editor, DocumentContext ctx)
        {
            var cts           = new CancellationTokenSource();
            var getSymbolTask = RefactoringSymbolInfo.GetSymbolInfoAsync(ctx, editor, cts.Token);
            var message       = GettextCatalog.GetString("Resolving symbol…");
            var info          = await MessageService.ExecuteTaskAndShowWaitDialog(getSymbolTask, message, cts);

            var sym = info.DeclaredSymbol ?? info.Symbol;

            if (!CanRename(sym))
            {
                return;
            }
            await new RenameRefactoring().Rename(sym);
        }
Exemple #14
0
        static async Task <RefactoringSymbolInfo> GetNamedTypeAtCaret(Ide.Gui.Document doc)
        {
            if (doc == null)
            {
                return(null);
            }
            var info = await RefactoringSymbolInfo.GetSymbolInfoAsync(doc, doc.Editor);

            if (info.Node?.Parent.IsKind(SyntaxKind.SimpleBaseType) != true)
            {
                return(null);
            }

            return(info);
        }
Exemple #15
0
        protected override async void Update(CommandInfo info)
        {
            var doc = IdeApp.Workbench.ActiveDocument;

            if (doc == null)
            {
                info.Enabled = false;
                return;
            }
            var symInfo = await RefactoringSymbolInfo.GetSymbolInfoAsync(doc, doc.Editor);

            var sym = symInfo.Symbol ?? symInfo.DeclaredSymbol;

            info.Enabled = sym != null && (sym.IsKind(SymbolKind.Method) || sym.IsKind(SymbolKind.Property) && ((IPropertySymbol)sym).IsIndexer);
            info.Bypass  = !info.Enabled;
        }
        protected override async Task UpdateAsync(CommandInfo info, CancellationToken cancelToken)
        {
            var doc = IdeApp.Workbench.ActiveDocument;

            if (doc == null || doc.Editor == null)
            {
                info.Enabled = false;
                return;
            }
            var symInfo = await RefactoringSymbolInfo.GetSymbolInfoAsync(doc.DocumentContext, doc.Editor, cancelToken);

            var sym = symInfo.Symbol ?? symInfo.DeclaredSymbol;

            info.Enabled = sym != null && (sym.IsKind(SymbolKind.Method) || sym.IsKind(SymbolKind.Property) && ((IPropertySymbol)sym).IsIndexer);
            info.Bypass  = !info.Enabled;
        }
Exemple #17
0
        public void Run(object data)
        {
            var doc = IdeApp.Workbench.ActiveDocument;

            if (doc == null || doc.FileName == FilePath.Null)
            {
                return;
            }

            var info = RefactoringSymbolInfo.GetSymbolInfoAsync(doc, doc.Editor.CaretOffset).Result;
            var sym  = info.Symbol ?? info.DeclaredSymbol;

            if (sym != null)
            {
                FindRefs(sym);
            }
        }
Exemple #18
0
        protected async override void Run()
        {
            var doc = IdeApp.Workbench.ActiveDocument;

            if (doc == null || doc.FileName == FilePath.Null)
            {
                return;
            }
            var info = await RefactoringSymbolInfo.GetSymbolInfoAsync(doc, doc.Editor);

            var sym = info.Symbol ?? info.DeclaredSymbol;

            if (sym != null)
            {
                FindOverloads(sym);
            }
        }
Exemple #19
0
        public void Run(object data)
        {
            var doc = IdeApp.Workbench.ActiveDocument;

            if (doc == null || doc.FileName == FilePath.Null)
            {
                return;
            }

            var info          = RefactoringSymbolInfo.GetSymbolInfoAsync(doc, doc.Editor.CaretOffset).Result;
            var sym           = info.Symbol ?? info.DeclaredSymbol;
            var semanticModel = doc.ParsedDocument.GetAst <SemanticModel> ();

            if (sym != null)
            {
                FindRefs(sym, semanticModel.Compilation);
            }
        }
Exemple #20
0
        static bool TryGetInterfaceType(RefactoringSymbolInfo sym, out ITypeSymbol interfaceType, out INamedTypeSymbol implementingType)
        {
            interfaceType    = null;
            implementingType = null;
            if (sym == null)
            {
                return(false);
            }
            interfaceType = sym.Symbol as ITypeSymbol;
            var parentTypeNode = sym.Node?.Parent?.Parent?.Parent;

            if (parentTypeNode == null || interfaceType.TypeKind != TypeKind.Interface)
            {
                return(false);
            }
            implementingType = sym.Model.GetDeclaredSymbol(parentTypeNode) as INamedTypeSymbol;
            return(implementingType != null);
        }
        public void UpdateCommandInfo(CommandInfo ci)
        {
            var doc = IdeApp.Workbench.ActiveDocument;

            if (doc == null || doc.FileName == FilePath.Null)
            {
                return;
            }
            if (doc.ParsedDocument == null || doc.ParsedDocument.GetAst <SemanticModel> () == null)
            {
                ci.Enabled = false;
            }
            var info = RefactoringSymbolInfo.GetSymbolInfoAsync(doc, doc.Editor.CaretOffset).Result;
            var sym  = info.DeclaredSymbol ?? info.Symbol;

            if (!CanRename(sym))
            {
                ci.Bypass = true;
            }
        }
Exemple #22
0
        public void Run(object data)
        {
            var doc = IdeApp.Workbench.ActiveDocument;

            if (doc == null || doc.FileName == FilePath.Null)
            {
                return;
            }

            var info = RefactoringSymbolInfo.GetSymbolInfoAsync(doc, doc.Editor).Result;
            var sym  = info.Symbol ?? info.DeclaredSymbol;

            if (sym != null)
            {
                if (sym.Kind == SymbolKind.Local || sym.Kind == SymbolKind.Parameter || sym.Kind == SymbolKind.TypeParameter)
                {
                    FindRefs(new [] { SymbolAndProjectId.Create(sym, doc.AnalysisDocument.Project.Id) }, doc.AnalysisDocument.Project.Solution).Ignore();
                }
                else
                {
                    RefactoringService.FindReferencesAsync(FilterSymbolForFindReferences(sym).GetDocumentationCommentId()).Ignore();
                }
            }
        }
        public void Run(object data)
        {
            var doc = IdeApp.Workbench.ActiveDocument;

            if (doc == null || doc.FileName == FilePath.Null)
            {
                return;
            }

            var info = RefactoringSymbolInfo.GetSymbolInfoAsync(doc, doc.Editor).Result;
            var sym  = info.Symbol ?? info.DeclaredSymbol;

            if (sym != null)
            {
                if (sym.Kind == SymbolKind.Local || sym.Kind == SymbolKind.Parameter || sym.Kind == SymbolKind.TypeParameter)
                {
                    FindReferencesHandler.FindRefs(sym);
                }
                else
                {
                    RefactoringService.FindAllReferencesAsync(FindReferencesHandler.FilterSymbolForFindReferences(sym).GetDocumentationCommentId());
                }
            }
        }
Exemple #24
0
        protected override async Task UpdateAsync(CommandArrayInfo ainfo, CancellationToken cancelToken)
        {
            if (!TryGetDocument(out var analysisDocument, out var doc))
            {
                return;
            }
            var semanticModel = await analysisDocument.GetSemanticModelAsync(cancelToken);

            if (semanticModel == null)
            {
                return;
            }
            var info = await RefactoringSymbolInfo.GetSymbolInfoAsync(doc.DocumentContext, doc.Editor, cancelToken);

            var ext = doc.GetContent <CodeActionEditorExtension> ();

            bool canRename = RenameHandler.CanRename(info.Symbol ?? info.DeclaredSymbol);

            if (canRename)
            {
                ainfo.Add(IdeApp.CommandService.GetCommandInfo(MonoDevelop.Ide.Commands.EditCommands.Rename), new Action(async delegate {
                    await new MonoDevelop.Refactoring.Rename.RenameRefactoring().Rename(info.Symbol ?? info.DeclaredSymbol);
                }));
            }

            bool isSortAndRemoveUsingsSupported = RemoveAndSortUsingsHandler.IsSortAndRemoveImportsSupported(analysisDocument, doc.GetContent <Microsoft.VisualStudio.Text.ITextBuffer>());

            if (isSortAndRemoveUsingsSupported)
            {
                var sortAndRemoveImportsInfo = IdeApp.CommandService.GetCommandInfo(Commands.SortAndRemoveImports);
                sortAndRemoveImportsInfo.Enabled = true;
                ainfo.Add(sortAndRemoveImportsInfo, new Action(async delegate {
                    await RemoveAndSortUsingsHandler.SortAndRemoveUnusedImports(analysisDocument, cancelToken);
                }));
            }

            var gotoDeclarationSymbol = info.Symbol;

            if (gotoDeclarationSymbol == null && info.DeclaredSymbol != null && info.DeclaredSymbol.Locations.Length > 1)
            {
                gotoDeclarationSymbol = info.DeclaredSymbol;
            }
            if (IdeApp.ProjectOperations.CanJumpToDeclaration(gotoDeclarationSymbol) || gotoDeclarationSymbol == null && IdeApp.ProjectOperations.CanJumpToDeclaration(info.CandidateSymbols.FirstOrDefault()))
            {
                var type = (gotoDeclarationSymbol ?? info.CandidateSymbols.FirstOrDefault()) as INamedTypeSymbol;
                if (type != null && type.Locations.Length > 1)
                {
                    var declSet = new CommandInfoSet();
                    declSet.Text = GettextCatalog.GetString("_Go to Declaration");
                    foreach (var part in type.Locations)
                    {
                        var loc = part.GetLineSpan();
                        declSet.CommandInfos.Add(string.Format(GettextCatalog.GetString("{0}, Line {1}"), FormatFileName(part.SourceTree.FilePath), loc.StartLinePosition.Line + 1), new Action(() => IdeApp.ProjectOperations.JumpTo(type, part, doc.Owner)));
                    }
                    ainfo.Add(declSet);
                }
                else
                {
                    ainfo.Add(IdeApp.CommandService.GetCommandInfo(RefactoryCommands.GotoDeclaration), new Action(() => GotoDeclarationHandler.Run(doc)));
                }
            }


            if (info.DeclaredSymbol != null && GotoBaseDeclarationHandler.CanGotoBase(info.DeclaredSymbol))
            {
                ainfo.Add(GotoBaseDeclarationHandler.GetDescription(info.DeclaredSymbol), new Action(() => GotoBaseDeclarationHandler.GotoBase(doc, info.DeclaredSymbol).Ignore()));
            }

            var sym = info.Symbol ?? info.DeclaredSymbol;

            if (doc.DocumentContext.HasProject && sym != null)
            {
                ainfo.Add(IdeApp.CommandService.GetCommandInfo(RefactoryCommands.FindReferences), new System.Action(() => {
                    if (sym.Kind == SymbolKind.Local || sym.Kind == SymbolKind.Parameter || sym.Kind == SymbolKind.TypeParameter)
                    {
                        FindReferencesHandler.FindRefs(new [] { SymbolAndProjectId.Create(sym, analysisDocument.Project.Id) }, analysisDocument.Project.Solution).Ignore();
                    }
                    else
                    {
                        RefactoringService.FindReferencesAsync(FindReferencesHandler.FilterSymbolForFindReferences(sym).GetDocumentationCommentId()).Ignore();
                    }
                }));
                try {
                    if (Microsoft.CodeAnalysis.FindSymbols.SymbolFinder.FindSimilarSymbols(sym, semanticModel.Compilation).Count() > 1)
                    {
                        ainfo.Add(IdeApp.CommandService.GetCommandInfo(RefactoryCommands.FindAllReferences), new System.Action(() => RefactoringService.FindAllReferencesAsync(FindReferencesHandler.FilterSymbolForFindReferences(sym).GetDocumentationCommentId())));
                    }
                } catch (Exception) {
                    // silently ignore roslyn bug.
                }
            }
        }
Exemple #25
0
        protected override void Update(CommandArrayInfo ainfo)
        {
            var doc = IdeApp.Workbench.ActiveDocument;

            if (doc == null || doc.FileName == FilePath.Null || doc.ParsedDocument == null)
            {
                return;
            }
            var semanticModel = doc.ParsedDocument.GetAst <SemanticModel> ();

            if (semanticModel == null)
            {
                return;
            }
            var task = RefactoringSymbolInfo.GetSymbolInfoAsync(doc, doc.Editor);

            if (!task.Wait(2000))
            {
                return;
            }
            var  info  = task.Result;
            bool added = false;

            var ext = doc.GetContent <CodeActionEditorExtension> ();

            //if (ext != null) {
            //	var fixMenu = CreateFixMenu (doc.Editor, doc, semanticModel, ext.GetCurrentFixes ());
            //	if (fixMenu.CommandInfos.Count > 0) {
            //		ainfo.Add (fixMenu, null);
            //		added = true;
            //	}
            //}
            var ciset = new CommandInfoSet();

            ciset.Text = GettextCatalog.GetString("Refactor");

            bool canRename = RenameHandler.CanRename(info.Symbol ?? info.DeclaredSymbol);

            if (canRename)
            {
                ciset.CommandInfos.Add(IdeApp.CommandService.GetCommandInfo(MonoDevelop.Ide.Commands.EditCommands.Rename), new Action(async delegate {
                    await new MonoDevelop.Refactoring.Rename.RenameRefactoring().Rename(info.Symbol ?? info.DeclaredSymbol);
                }));
                added = true;
            }
            bool first = true;

            //if (ext != null) {
            //	foreach (var fix in ext.GetCurrentFixes ().CodeRefactoringActions) {
            //		if (added & first && ciset.CommandInfos.Count > 0)
            //			ciset.CommandInfos.AddSeparator ();
            //		var info2 = new CommandInfo (fix.CodeAction.Title);
            //		ciset.CommandInfos.Add (info2, new Action (async () => await new CodeActionEditorExtension.ContextActionRunner (fix.CodeAction, doc.Editor, doc).Run ()));
            //		added = true;
            //		first = false;
            //	}
            //}

            if (ciset.CommandInfos.Count > 0)
            {
                ainfo.Add(ciset, null);
                added = true;
            }

            var gotoDeclarationSymbol = info.Symbol;

            if (gotoDeclarationSymbol == null && info.DeclaredSymbol != null && info.DeclaredSymbol.Locations.Length > 1)
            {
                gotoDeclarationSymbol = info.DeclaredSymbol;
            }
            if (IdeApp.ProjectOperations.CanJumpToDeclaration(gotoDeclarationSymbol) || gotoDeclarationSymbol == null && IdeApp.ProjectOperations.CanJumpToDeclaration(info.CandidateSymbols.FirstOrDefault()))
            {
                var type = (gotoDeclarationSymbol ?? info.CandidateSymbols.FirstOrDefault()) as INamedTypeSymbol;
                if (type != null && type.Locations.Length > 1)
                {
                    var declSet = new CommandInfoSet();
                    declSet.Text = GettextCatalog.GetString("_Go to Declaration");
                    foreach (var part in type.Locations)
                    {
                        var loc = part.GetLineSpan();
                        declSet.CommandInfos.Add(string.Format(GettextCatalog.GetString("{0}, Line {1}"), FormatFileName(part.SourceTree.FilePath), loc.StartLinePosition.Line + 1), new Action(() => IdeApp.ProjectOperations.JumpTo(type, part, doc.Project)));
                    }
                    ainfo.Add(declSet);
                }
                else
                {
                    ainfo.Add(IdeApp.CommandService.GetCommandInfo(RefactoryCommands.GotoDeclaration), new Action(() => GotoDeclarationHandler.Run(doc)));
                }
                added = true;
            }


            if (info.DeclaredSymbol != null && GotoBaseDeclarationHandler.CanGotoBase(info.DeclaredSymbol))
            {
                ainfo.Add(GotoBaseDeclarationHandler.GetDescription(info.DeclaredSymbol), new Action(() => GotoBaseDeclarationHandler.GotoBase(doc, info.DeclaredSymbol)));
                added = true;
            }

            var sym = info.Symbol ?? info.DeclaredSymbol;

            if (doc.HasProject && sym != null)
            {
                ainfo.Add(IdeApp.CommandService.GetCommandInfo(RefactoryCommands.FindReferences), new System.Action(() => {
                    if (sym.Kind == SymbolKind.Local || sym.Kind == SymbolKind.Parameter || sym.Kind == SymbolKind.TypeParameter)
                    {
                        FindReferencesHandler.FindRefs(sym);
                    }
                    else
                    {
                        RefactoringService.FindReferencesAsync(FindReferencesHandler.FilterSymbolForFindReferences(sym).GetDocumentationCommentId());
                    }
                }));
                try {
                    if (Microsoft.CodeAnalysis.FindSymbols.SymbolFinder.FindSimilarSymbols(sym, semanticModel.Compilation).Count() > 1)
                    {
                        ainfo.Add(IdeApp.CommandService.GetCommandInfo(RefactoryCommands.FindAllReferences), new System.Action(() => RefactoringService.FindAllReferencesAsync(FindReferencesHandler.FilterSymbolForFindReferences(sym).GetDocumentationCommentId())));
                    }
                } catch (Exception) {
                    // silently ignore roslyn bug.
                }
            }
            added = true;
        }