diff --git a/Codist/Controls/CSharpSymbolContextMenu.cs b/Codist/Controls/CSharpSymbolContextMenu.cs index 4379e112..52c67636 100644 --- a/Codist/Controls/CSharpSymbolContextMenu.cs +++ b/Codist/Controls/CSharpSymbolContextMenu.cs @@ -304,11 +304,15 @@ internal static void ShowLocations(ISymbol symbol, SemanticContext context) { var locs = symbol.GetSourceLocations().Sort((x, y) => String.CompareOrdinal(x.SourceTree.FilePath, y.SourceTree.FilePath)); m.Title.SetGlyph(ThemeHelper.GetImage(symbol.GetImageId())) .Append(symbol.ToDisplayString(WpfHelper.MemberNameFormat), true) - .Append(" locations: ") + .Append(" source locations: ") .Append(locs.Length); foreach (var loc in locs) { m.Menu.Add(loc); } + locs = symbol.Locations.RemoveAll(l => l.IsInMetadata == false).Sort((x, y) => String.CompareOrdinal(x.MetadataModule.Name, y.MetadataModule.Name)); + foreach (var loc in locs) { + m.Menu.Add(loc); + } m.Show(); } static void ShowSymbolMenuForResult(ISymbol source, SemanticContext context, List members, string suffix, bool groupByType) { diff --git a/Codist/Controls/SymbolList.cs b/Codist/Controls/SymbolList.cs index 714a87ab..adb21dfb 100644 --- a/Codist/Controls/SymbolList.cs +++ b/Codist/Controls/SymbolList.cs @@ -437,7 +437,13 @@ async Task CreateItemToolTipAsync(ListBoxItem li) { return ToolTipFactory.CreateToolTip(item.Symbol, false, SemanticContext.SemanticModel.Compilation); } if (item.Location != null) { - return new ThemedToolTip(Path.GetFileName(item.Location.SourceTree.FilePath), $"Folder: {item.Hint}{Environment.NewLine}Line: {item.Location.GetLineSpan().StartLinePosition.Line + 1}"); + if (item.Location.IsInSource) { + var p = item.Location.SourceTree.FilePath; + return new ThemedToolTip(Path.GetFileName(p), $"Folder: {Path.GetDirectoryName(p)}{Environment.NewLine}Line: {item.Location.GetLineSpan().StartLinePosition.Line + 1}"); + } + else { + return new ThemedToolTip(item.Location.MetadataModule.Name, $"Containing assembly: {item.Location.MetadataModule.ContainingAssembly}"); + } } return null; } @@ -678,10 +684,18 @@ public SymbolItem(SymbolList list) { public SymbolItem(Location location, SymbolList list) { Container = list; Location = location; - var filePath = location.SourceTree.FilePath; - _Content = new ThemedMenuText(Path.GetFileNameWithoutExtension(filePath)).Append(Path.GetExtension(filePath), ThemeHelper.SystemGrayTextBrush); - _Hint = Path.GetFileName(Path.GetDirectoryName(filePath)); - _ImageId = KnownImageIds.CSFile; + if (location.IsInSource) { + var filePath = location.SourceTree.FilePath; + _Content = new ThemedMenuText(Path.GetFileNameWithoutExtension(filePath)).Append(Path.GetExtension(filePath), ThemeHelper.SystemGrayTextBrush); + _Hint = Path.GetFileName(Path.GetDirectoryName(filePath)); + _ImageId = KnownImageIds.CSFile; + } + else { + var m = location.MetadataModule; + _Content = new ThemedMenuText(Path.GetFileNameWithoutExtension(m.Name)).Append(Path.GetExtension(m.Name), ThemeHelper.SystemGrayTextBrush); + _Hint = String.Empty; + _ImageId = KnownImageIds.Module; + } } public SymbolItem(ISymbol symbol, SymbolList list, ISymbol containerSymbol) : this (symbol, list, false) { @@ -700,7 +714,7 @@ public SymbolItem(SyntaxNode node, SymbolList list) { } public void GoToSource() { - if (Location != null) { + if (Location != null && Location.IsInSource) { Location.GoToSource(); } else if (Symbol != null) { diff --git a/Codist/QuickInfo/CSharpQuickInfo.cs b/Codist/QuickInfo/CSharpQuickInfo.cs index 2090f20c..d018112b 100644 --- a/Codist/QuickInfo/CSharpQuickInfo.cs +++ b/Codist/QuickInfo/CSharpQuickInfo.cs @@ -191,7 +191,7 @@ public void AugmentQuickInfoSession(IQuickInfoSession session, IList qiC if (Config.Instance.QuickInfoOptions.MatchFlags(QuickInfoOptions.Diagnostics)) { qiWrapper.SetDiagnostics(semanticModel.GetDiagnostics(token.Span)); } - qiWrapper.ApplyClickAndGo(symbol); + qiWrapper.ApplyClickAndGo(symbol, session); } qiWrapper.LimitQuickInfoItemSize(qiContent); applicableToSpan = qiContent.Count > 0 && session.TextView.TextSnapshot == currentSnapshot diff --git a/Codist/QuickInfo/QuickInfoOverrider.cs b/Codist/QuickInfo/QuickInfoOverrider.cs index 41fab4e0..4ff1f83e 100644 --- a/Codist/QuickInfo/QuickInfoOverrider.cs +++ b/Codist/QuickInfo/QuickInfoOverrider.cs @@ -18,7 +18,7 @@ namespace Codist.QuickInfo interface IQuickInfoOverrider { void SetDiagnostics(IList diagnostics); - void ApplyClickAndGo(ISymbol symbol); + void ApplyClickAndGo(ISymbol symbol, IQuickInfoSession quickInfoSession); void LimitQuickInfoItemSize(IList qiContent); void OverrideDocumentation(UIElement docElement); void OverrideException(UIElement exceptionDoc); @@ -29,10 +29,10 @@ static class QuickInfoOverrider static readonly SolidColorBrush __HighlightBrush = SystemColors.HighlightBrush.Alpha(0.3); public static IQuickInfoOverrider CreateOverrider(IList qiContent) { var o = new Legacy(qiContent); - return o.Panel != null ? o : (IQuickInfoOverrider)new Default(qiContent); + return o.Panel != null ? o : (IQuickInfoOverrider)new Default(); } - static void ApplyClickAndGo(ISymbol symbol, TextBlock description) { + static void ApplyClickAndGo(ISymbol symbol, TextBlock description, IQuickInfoSession quickInfoSession) { var locs = symbol.GetSourceLocations(); string path; description.ToolTip = String.Empty; @@ -46,36 +46,47 @@ static void ApplyClickAndGo(ISymbol symbol, TextBlock description) { goto ClickAndGo; } } + if (symbol.Kind == SymbolKind.Namespace) { + description.ToolTip = "Locations: " + symbol.Locations.Length; + description.Cursor = Cursors.Hand; + description.MouseEnter += HighlightSymbol; + description.MouseLeave += RemoveSymbolHighlight; + description.MouseLeftButtonUp += ListLocations; + return; + } var asm = symbol.GetAssemblyModuleName(); if (asm != null) { path = asm; - description.ToolTipOpening += DescriptionShowToolTip; + description.ToolTipOpening += ShowToolTip; } return; } ClickAndGo: path = System.IO.Path.GetFileName(locs[0].SourceTree.FilePath); - description.ToolTipOpening += DescriptionShowToolTip; + description.ToolTipOpening += ShowToolTip; description.Cursor = Cursors.Hand; - description.MouseEnter += (s, args) => (s as TextBlock).Background = __HighlightBrush; - description.MouseLeave += (s, args) => (s as TextBlock).Background = Brushes.Transparent; + description.MouseEnter += HighlightSymbol; + description.MouseLeave += RemoveSymbolHighlight; if (locs.Length == 1) { description.MouseLeftButtonUp += (s, args) => symbol.GoToSource(); return; } - description.MouseLeftButtonUp += ListMultiLocations; + description.MouseLeftButtonUp += ListLocations; - void ListMultiLocations(object sender, MouseButtonEventArgs e) { - var view = TextEditorHelper.GetMouseOverDocumentView(); - if (view == null) { - return; - } - CSharpSymbolContextMenu.ShowLocations(symbol, SemanticContext.GetOrCreateSingetonInstance(view)); + 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 DescriptionShowToolTip(object sender, ToolTipEventArgs e) { - var d = sender as TextBlock; - d.ToolTip = ShowSymbolLocation(symbol, path); - d.ToolTipOpening -= DescriptionShowToolTip; + void RemoveSymbolHighlight(object sender, MouseEventArgs e) { + ((TextBlock)sender).Background = Brushes.Transparent; } } @@ -108,12 +119,13 @@ sealed class Default : IQuickInfoOverrider { readonly Overrider _Overrider; - public Default(IList qiContent) { + public Default() { _Overrider = new Overrider(); } - public void ApplyClickAndGo(ISymbol symbol) { + public void ApplyClickAndGo(ISymbol symbol, IQuickInfoSession quickInfoSession) { _Overrider.ClickAndGoSymbol = symbol; + _Overrider.QuickInfoSession = quickInfoSession; } public void LimitQuickInfoItemSize(IList qiContent) { @@ -147,6 +159,7 @@ sealed class Overrider : UIElement public UIElement DocElement; public UIElement ExceptionDoc; public IList Diagnostics; + public IQuickInfoSession QuickInfoSession; protected override void OnVisualParentChanged(DependencyObject oldParent) { base.OnVisualParentChanged(oldParent); @@ -288,7 +301,7 @@ void FixQuickInfo(StackPanel infoPanel) { if (icon != null && signature != null) { // apply click and go feature if (ClickAndGoSymbol != null) { - QuickInfoOverrider.ApplyClickAndGo(ClickAndGoSymbol, signature); + QuickInfoOverrider.ApplyClickAndGo(ClickAndGoSymbol, signature, QuickInfoSession); } // fix the width of the signature part to prevent it from falling down to the next row if (Config.Instance.QuickInfoMaxWidth > 0) { @@ -442,7 +455,7 @@ public Legacy(IList qiContent) { public TextBlock Documentation => Panel != null ? __GetDocumentation(Panel) : null; /// Hack into the default QuickInfo panel and provides click and go feature for symbols. - public void ApplyClickAndGo(ISymbol symbol) { + public void ApplyClickAndGo(ISymbol symbol, IQuickInfoSession quickInfoSession) { if (symbol == null) { return; } @@ -453,7 +466,7 @@ public void ApplyClickAndGo(ISymbol symbol) { if (symbol.IsImplicitlyDeclared) { symbol = symbol.ContainingType; } - QuickInfoOverrider.ApplyClickAndGo(symbol, description); + QuickInfoOverrider.ApplyClickAndGo(symbol, description, quickInfoSession); } /// @@ -502,7 +515,7 @@ public void SetDiagnostics(IList diagnostics) { static StackPanel FindDefaultQuickInfoPanel(IList qiContent) { foreach (var item in qiContent) { var o = item as StackPanel; - if (o != null && o.GetType().Name == "QuickInfoDisplayPanel") { + if (o?.GetType().Name == "QuickInfoDisplayPanel") { return o; } }