public static void GoToDefinition(this ISymbol symbol) { var r = symbol.GetSourceReferences(); if (r.Length == 1) { r[0].GoToSource(); } else { var ctx = SemanticContext.GetHovered(); if (ctx != null) { if (r.Length == 0) { if (ctx.Document != null) { ServicesHelper.Instance.VisualStudioWorkspace.TryGoToDefinition(symbol, ctx.Document.Project, default); } } else { CSharpSymbolContextMenu.ShowLocations(symbol, r, ctx); } } } }
void AddSymbolCommands(bool isReadOnly, SyntaxNode node) { if (node.IsKind(SyntaxKind.IdentifierName) || node.IsKind(SyntaxKind.GenericName)) { AddEditorCommand(MyToolBar, IconIds.GoToDefinition, "Edit.GoToDefinition", R.CMD_GoToDefinitionPeek, "Edit.PeekDefinition"); } AddCommand(MyToolBar, IconIds.FindReference, R.CMD_AnalyzeSymbol, ctx => { ctx.KeepToolBar(false); if (UpdateSemanticModel() == false) { return; } var m = new CSharpSymbolContextMenu(_Context) { Placement = System.Windows.Controls.Primitives.PlacementMode.Bottom, PlacementTarget = ctx.Sender, Symbol = _Symbol, SyntaxNode = node }; m.ItemClicked += (s, args) => HideToolBar(); m.AddAnalysisCommands(); m.AddFindAllReferencesCommand(); m.AddGoToAnyCommands(); ctx.Sender.ContextMenu = m; m.IsOpen = true; }); if (Taggers.SymbolMarkManager.CanBookmark(_Symbol)) { AddCommands(MyToolBar, IconIds.Marks, R.CMD_MarkSymbol, null, GetMarkerCommands); } if (/*isDesignMode && */ isReadOnly == false) { AddRefactorCommands(node); } }
protected override void OnContextMenuOpening(ContextMenuEventArgs e) { if (ContextMenu == null) { var m = new CSharpSymbolContextMenu(_Bar._SemanticContext) { SyntaxNode = Node }; m.AddNodeCommands(); var s = Symbol; if (s != null) { m.Symbol = s; m.Items.Add(new Separator()); m.AddAnalysisCommands(); m.AddSymbolCommands(); m.AddTitleItem(Node.GetDeclarationSignature()); } m.PlacementTarget = this; m.Placement = System.Windows.Controls.Primitives.PlacementMode.Bottom; ContextMenu = m; } base.OnContextMenuOpening(e); }
static void ApplyClickAndGo(ISymbol symbol, ITextBuffer textBuffer, TextBlock description, IAsyncQuickInfoSession quickInfoSession) { if (symbol.Kind == SymbolKind.Namespace) { description.ToolTip = R.T_Locations + symbol.DeclaringSyntaxReferences.Length; description.MouseEnter += HookEvents; return; } if (symbol.Kind == SymbolKind.Method) { if (((IMethodSymbol)symbol).MethodKind == MethodKind.LambdaMethod) { using (var sbr = Microsoft.VisualStudio.Utilities.ReusableStringBuilder.AcquireDefault(30)) { var sb = sbr.Resource; sb.Append('('); foreach (var item in ((IMethodSymbol)symbol).Parameters) { if (item.Ordinal > 0) { sb.Append(", "); } sb.Append(item.Type.ToDisplayString(CodeAnalysisHelper.QuickInfoSymbolDisplayFormat)) .Append(item.Type.GetParameterString()) .Append(' ') .Append(item.Name); } sb.Append(')'); description.Append(sb.ToString(), ThemeHelper.DocumentTextBrush); } } } description.UseDummyToolTip(); if (symbol.HasSource() == false && symbol.ContainingType?.HasSource() == true) { // if the symbol is implicitly declared but its containing type is in source, // navigate to the containing type symbol = symbol.ContainingType; } description.MouseEnter += HookEvents; void HookEvents(object sender, MouseEventArgs e) { var s = sender as FrameworkElement; s.MouseEnter -= HookEvents; HighlightSymbol(sender, e); s.Cursor = Cursors.Hand; if (symbol.Kind != SymbolKind.Namespace) { s.ToolTipOpening += ShowToolTip; s.UseDummyToolTip(); } s.MouseEnter += HighlightSymbol; s.MouseLeave += RemoveSymbolHighlight; s.MouseLeftButtonUp += GoToSource; s.ContextMenuOpening += ShowContextMenu; s.ContextMenuClosing += ReleaseQuickInfo; } async void GoToSource(object sender, MouseButtonEventArgs e) { await quickInfoSession.DismissAsync(); symbol.GoToDefinition(); } void ShowToolTip(object sender, ToolTipEventArgs e) { var t = sender as TextBlock; t.ToolTip = ShowSymbolLocation(symbol, symbol.HasSource() ? System.IO.Path.GetFileName(symbol.Locations[0].SourceTree.FilePath) : symbol.GetAssemblyModuleName()); t.ToolTipOpening -= ShowToolTip; } void HighlightSymbol(object sender, EventArgs e) { ((TextBlock)sender).Background = (symbol.HasSource() ? SystemColors.HighlightBrush : SystemColors.GrayTextBrush).Alpha(0.3); } void RemoveSymbolHighlight(object sender, MouseEventArgs e) { ((TextBlock)sender).Background = Brushes.Transparent; } void ShowContextMenu(object sender, ContextMenuEventArgs e) { var s = sender as FrameworkElement; if (s.ContextMenu == null) { var ctx = SemanticContext.GetOrCreateSingetonInstance(quickInfoSession.TextView as IWpfTextView); SyncHelper.RunSync(() => ctx.UpdateAsync(textBuffer, default)); var m = new CSharpSymbolContextMenu(ctx) { Symbol = symbol, SyntaxNode = symbol.GetSyntaxNode() }; m.AddAnalysisCommands(); if (m.HasItems) { m.Items.Add(new Separator()); } m.AddSymbolNodeCommands(); m.AddTitleItem(symbol.GetOriginalName()); m.ItemClicked += HideQuickInfo; s.ContextMenu = m; } HoldQuickInfo(s, true); s.ContextMenu.IsOpen = true; } void ReleaseQuickInfo(object sender, ContextMenuEventArgs e) { HoldQuickInfo(sender as DependencyObject, false); } void HideQuickInfo(object sender, RoutedEventArgs e) { DismissQuickInfo(description); } }
static void ApplyClickAndGo(ISymbol symbol, TextBlock description, IQuickInfoSession quickInfoSession) { var locs = symbol.DeclaringSyntaxReferences; if (symbol.Kind == SymbolKind.Namespace) { description.ToolTip = "Locations: " + locs.Length; description.MouseEnter += HookNamespaceSymbolEvents; return; } string path; description.UseDummyToolTip(); if (locs.IsDefaultOrEmpty) { if (symbol.ContainingType != null) { // if the symbol is implicitly declared but its containing type is in source, // navigate to the containing type locs = symbol.ContainingType.DeclaringSyntaxReferences; if (locs.Length != 0) { symbol = symbol.ContainingType; goto ClickAndGo; } } var asm = symbol.GetAssemblyModuleName(); if (asm != null) { path = asm; description.MouseEnter += HookMetaSymbolEvents; } return; } ClickAndGo: path = System.IO.Path.GetFileName(locs[0].SyntaxTree.FilePath); description.MouseEnter += HookEvents; void HookMetaSymbolEvents(object sender, MouseEventArgs e) { var s = sender as FrameworkElement; s.MouseEnter -= HookMetaSymbolEvents; s.ToolTipOpening += ShowToolTip; s.UseDummyToolTip(); s.ContextMenuOpening += ShowContextMenu; } void HookNamespaceSymbolEvents(object sender, EventArgs e) { var s = sender as FrameworkElement; s.MouseEnter -= HookNamespaceSymbolEvents; ((TextBlock)sender).Background = __HighlightBrush; s.Cursor = Cursors.Hand; s.MouseEnter += HighlightSymbol; s.MouseLeave += RemoveSymbolHighlight; s.MouseLeftButtonUp += ListLocations; s.ContextMenuOpening += ShowContextMenu; s.ContextMenuClosing += ReleaseQuickInfo; } void HookEvents(object sender, MouseEventArgs e) { var s = sender as FrameworkElement; s.MouseEnter -= HookEvents; ((TextBlock)sender).Background = __HighlightBrush; s.Cursor = Cursors.Hand; s.ToolTipOpening += ShowToolTip; s.MouseEnter += HighlightSymbol; s.MouseLeave += RemoveSymbolHighlight; if (locs.Length == 1) { s.MouseLeftButtonUp += GoToSource; } else { s.MouseLeftButtonUp += ListLocations; } s.UseDummyToolTip(); s.ContextMenuOpening += ShowContextMenu; s.ContextMenuClosing += ReleaseQuickInfo; } void GoToSource(object sender, MouseButtonEventArgs e) { symbol.GoToSource(); } void ListLocations(object sender, MouseButtonEventArgs e) { quickInfoSession.Dismiss(); CSharpSymbolContextMenu.ShowLocations(symbol, SemanticContext.GetOrCreateSingetonInstance(quickInfoSession.TextView as IWpfTextView)); } void ShowToolTip(object sender, ToolTipEventArgs e) { var t = sender as TextBlock; t.ToolTip = ShowSymbolLocation(symbol, path); t.ToolTipOpening -= ShowToolTip; } void HighlightSymbol(object sender, MouseEventArgs e) { ((TextBlock)sender).Background = __HighlightBrush; } void RemoveSymbolHighlight(object sender, MouseEventArgs e) { ((TextBlock)sender).Background = Brushes.Transparent; } void ShowContextMenu(object sender, ContextMenuEventArgs e) { var s = sender as FrameworkElement; if (s.ContextMenu == null) { var ctx = SemanticContext.GetHovered(); SyncHelper.RunSync(() => ctx.UpdateAsync(default));