private IdentifierContentGroup GetIdentifierContentGroupCore( DocumentRange documentRange, [NotNull] IContextBoundSettingsStore settings, [CanBeNull] IHighlighter highlighter) { PresentableInfo presentable = FindPresentable(documentRange); if (!presentable.IsValid()) { return(null); } IdentifierTooltipContent standardContent = TryPresentColorized(presentable.DeclaredElementInfo, settings) ?? TryPresentColorized(presentable.PresentableNode, settings) ?? TryPresentNonColorized(highlighter, presentable.DeclaredElementInfo?.DeclaredElement, settings); IdentifierTooltipContent additionalContent = TryGetAdditionalIdentifierContent(presentable.DeclaredElementInfo, settings, out bool replacesStandardContent); if (replacesStandardContent) { standardContent = additionalContent; additionalContent = null; } var result = new IdentifierContentGroup(); if (standardContent != null) { result.Identifiers.Add(standardContent); } if (additionalContent != null) { result.Identifiers.Add(additionalContent); } ITreeNode node = presentable.DeclaredElementInfo?.TreeNode ?? presentable.PresentableNode.Node; result.ArgumentRole = TryGetArgumentRoleContent(node, settings); return(result); }
private IdentifierContentGroup GetIdentifierContentGroupCore( DocumentRange documentRange, [NotNull] IContextBoundSettingsStore settings, [CanBeNull] IHighlighter highlighter) { DeclaredElementInfo info = FindDeclaredElement(documentRange); if (info == null) { return(null); } IdentifierTooltipContent standardContent = TryPresentColorized(info, settings) ?? TryPresentNonColorized(highlighter, info.DeclaredElement, settings); bool replacesStandardContent; IdentifierTooltipContent additionalContent = TryGetAdditionalIdentifierContent(info, settings, out replacesStandardContent); if (replacesStandardContent) { standardContent = additionalContent; additionalContent = null; } var result = new IdentifierContentGroup(); if (standardContent != null) { result.Identifiers.Add(standardContent); } if (additionalContent != null) { result.Identifiers.Add(additionalContent); } result.ArgumentRole = TryGetArgumentRoleContent(info.TreeNode, settings); return(result); }
protected override void AugmentQuickInfoSessionCore( IQuickInfoSession session, IList <object> quickInfoContent, IDocumentMarkup documentMarkup, TooltipFormattingProvider tooltipFormattingProvider, out ITrackingSpan applicableToSpan) { applicableToSpan = null; ITextSnapshot textSnapshot = TextBuffer.CurrentSnapshot; TextRange textRange = GetCurrentTextRange(session, textSnapshot); IShellLocks shellLocks = Shell.Instance.GetComponent <IShellLocks>(); Span? finalSpan = null; void GetEnhancedTooltips() { using (shellLocks.UsingReadLock()) { IDocument document = documentMarkup.Document; var presenter = new MultipleTooltipContentPresenter(tooltipFormattingProvider.GetTooltipFormatting(), document); IContextBoundSettingsStore settings = document.GetSettings(); ISolution solution = TryGetCurrentSolution(); bool hasIdentifierTooltipContent = false; var resolveContext = solution != null?document.GetContext(solution) : UniversalModuleReferenceContext.Instance; using (CompilationContextCookie.GetOrCreate(resolveContext)) { if (solution != null) { DocumentRange documentRange = textRange.CreateDocumentRange(document); IdentifierContentGroup contentGroup = GetIdentifierContentGroup(documentRange, solution, settings); if (contentGroup != null) { foreach (IdentifierTooltipContent content in contentGroup.Identifiers) { presenter.AddIdentifierTooltipContent(content); finalSpan = content.TrackingRange.ToSpan().Union(finalSpan); hasIdentifierTooltipContent = true; } if (contentGroup.ArgumentRole != null) { presenter.AddArgumentRoleTooltipContent(contentGroup.ArgumentRole); if (finalSpan == null) { // Only track the argument role if we have nothing else displayed. // See https://github.com/MrJul/ReSharper.EnhancedTooltip/issues/70 finalSpan = contentGroup.ArgumentRole.TrackingRange.ToSpan(); } } } } List <Vs10Highlighter> highlighters = documentMarkup.GetHighlightersOver(textRange).OfType <Vs10Highlighter>().ToList(); foreach (Vs10Highlighter highlighter in highlighters) { IEnumerable <IReSharperTooltipContent> contents = GetTooltipContents(highlighter, highlighter.Range, documentMarkup, solution, hasIdentifierTooltipContent); foreach (IReSharperTooltipContent content in contents) { if (presenter.TryAddReSharperContent(content)) { finalSpan = content.TrackingRange.ToSpan().Union(finalSpan); } } } } var vsSquiggleContents = session.RetrieveVsSquiggleContents() .OfType <string>() .ToSet(); bool ignoredFirstVsElement = false; foreach (object content in quickInfoContent) { if (content == null) { continue; } // ignore existing R# elements if (content is IQuickInfoContent) { continue; } var contentFullName = content.GetType().FullName; // ignore the first VS element, as it's the identifier tooltip and we already have one if (hasIdentifierTooltipContent && !ignoredFirstVsElement) { if (contentFullName == VsFullTypeNames.ContainerElement || /* VS 2017 >= 15.8 */ contentFullName == VsFullTypeNames.QuickInfoDisplayPanel || /* VS 2015 and VS 2017 < 15.8 */ content is ITextBuffer /* VS2012 and VS2013 */) { ignoredFirstVsElement = true; continue; } } // ignore Roslyn's bulb info placeholder (interactive tooltip "press ctrl+.") if (contentFullName == VsFullTypeNames.LightBulbQuickInfoPlaceHolder) { continue; } if (contentFullName == VsFullTypeNames.QuickInfoDisplayPanel) { presenter.AddVsIdentifierContent(new VsIdentifierContent(content)); } else if (content is string stringContent && vsSquiggleContents.Contains(stringContent)) { presenter.AddVsSquiggleContent(new VsSquiggleContent(stringContent)); }
protected override void AugmentQuickInfoSessionCore( IQuickInfoSession session, IList <object> quickInfoContent, IDocumentMarkup documentMarkup, TooltipFormattingProvider tooltipFormattingProvider, out ITrackingSpan applicableToSpan) { applicableToSpan = null; ITextSnapshot textSnapshot = TextBuffer.CurrentSnapshot; TextRange textRange = GetCurrentTextRange(session, textSnapshot); IShellLocks shellLocks = Shell.Instance.GetComponent <IShellLocks>(); Span? finalSpan = null; Action getEnhancedTooltips = () => { using (shellLocks.UsingReadLock()) { IDocument document = documentMarkup.Document; var presenter = new MultipleTooltipContentPresenter(tooltipFormattingProvider.GetTooltipFormatting(), document); IContextBoundSettingsStore settings = document.GetSettings(); ISolution solution = TryGetCurrentSolution(); bool hasIdentifierTooltipContent = false; if (solution != null) { DocumentRange documentRange = textRange.CreateDocumentRange(document); IdentifierContentGroup contentGroup = GetIdentifierContentGroup(documentRange, solution, settings); if (contentGroup != null) { foreach (IdentifierTooltipContent content in contentGroup.Identifiers) { presenter.AddIdentifierTooltipContent(content); finalSpan = content.TrackingRange.ToSpan().Union(finalSpan); hasIdentifierTooltipContent = true; } if (contentGroup.ArgumentRole != null) { presenter.AddArgumentRoleTooltipContent(contentGroup.ArgumentRole); if (finalSpan == null) { // Only track the argument role if we have nothing else displayed. // See https://github.com/MrJul/ReSharper.EnhancedTooltip/issues/70 finalSpan = contentGroup.ArgumentRole.TrackingRange.ToSpan(); } } } } List <Vs10Highlighter> highlighters = documentMarkup.GetHighlightersOver(textRange).OfType <Vs10Highlighter>().ToList(); foreach (Vs10Highlighter highlighter in highlighters) { IEnumerable <IReSharperTooltipContent> contents = GetTooltipContents(highlighter, highlighter.Range, documentMarkup, solution, hasIdentifierTooltipContent); foreach (IReSharperTooltipContent content in contents) { if (presenter.TryAddReSharperContent(content)) { finalSpan = content.TrackingRange.ToSpan().Union(finalSpan); } } } var vsSquiggleContents = session.RetrieveVsSquiggleContents() .OfType <string>() .ToHashSet(); bool ignoredFirstTextBuffer = false; foreach (object content in quickInfoContent) { if (content == null) { continue; } // ignore existing R# elements if (content is RichTextPresenter) { continue; } var contentFullName = content.GetType().FullName; if (hasIdentifierTooltipContent) { // ignore Roslyn identifier tooltip (for VS2015) if (contentFullName == VsFullTypeNames.QuickInfoDisplayPanel) { continue; } // ignore the first VS text buffer (for VS2012 and VS2013) if (content is ITextBuffer && !ignoredFirstTextBuffer) { ignoredFirstTextBuffer = true; continue; } } if (contentFullName == VsFullTypeNames.LightBulbQuickInfoPlaceHolder) { // ignore Roslyn's bulb info placeholder (interactive tooltip "press ctrl+.") continue; } if (contentFullName == VsFullTypeNames.QuickInfoDisplayPanel) { presenter.AddVsIdentifierContent(new VsIdentifierContent(content)); } else if (vsSquiggleContents.Contains(content)) { presenter.AddVsSquiggleContent(new VsSquiggleContent(content)); } else { presenter.AddVsUnknownContent(content); } } quickInfoContent.Clear(); quickInfoContent.AddRange(presenter.PresentContents()); } }; if (shellLocks.ReentrancyGuard.TryExecute("GetEnhancedTooltips", getEnhancedTooltips) && finalSpan != null) { applicableToSpan = textSnapshot.CreateTrackingSpan(finalSpan.Value, SpanTrackingMode.EdgeInclusive); } }