Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "Implement equality semantics for async tagger tags." #64867

Merged
merged 1 commit into from
Oct 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -121,19 +121,5 @@ diagnostic.Severity is DiagnosticSeverity.Warning or DiagnosticSeverity.Error &&
return null;
}
}

/// <summary>
/// TODO: is there anything we can do better here? Inline diagnostic tags are not really data, but more UI
/// elements with specific constrols, positions and events attached to them. There doesn't seem to be a safe
/// way to reuse any of these currently. Ideally we could do something similar to inline-hints where there's a
/// data tagger portion (which is async and has clean equality semantics), and then the UI portion which just
/// translates those data-tags to the UI tags.
/// <para>
/// Doing direct equality means we'll always end up regenerating all tags. But hopefully there won't be that
/// many in a document to matter.
/// </para>
/// </summary>
protected override bool TagEquals(InlineDiagnosticsTag tag1, InlineDiagnosticsTag tag2)
=> tag1 == tag2;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,5 @@ protected override async Task ProduceTagsAsync(
context.AddTag(new TagSpan<LineSeparatorTag>(span.ToSnapshotSpan(snapshotSpan.Snapshot), tag));
}
}

/// <summary>
/// We create and cache a separator tag to use (unless the format mapping changes). So we can just use identity
/// comparisons here.
/// </summary>
protected override bool TagEquals(LineSeparatorTag tag1, LineSeparatorTag tag2)
=> tag1 == tag2;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,27 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Immutable;
using System.Windows.Media;
using Microsoft.CodeAnalysis.Editor.Implementation.Adornments;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Classification;
using Microsoft.VisualStudio.Text.Editor;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis.Editor.Implementation.StringIndentation
{
/// <summary>
/// Tag that specifies how a string's content is indented.
/// </summary>
internal class StringIndentationTag : BrushTag, IEquatable<StringIndentationTag>
internal class StringIndentationTag : BrushTag
{
private readonly StringIndentationTaggerProvider _provider;

public readonly ImmutableArray<SnapshotSpan> OrderedHoleSpans;

public StringIndentationTag(
StringIndentationTaggerProvider provider,
IEditorFormatMap editorFormatMap,
ImmutableArray<SnapshotSpan> orderedHoleSpans)
: base(editorFormatMap)
{
_provider = provider;
OrderedHoleSpans = orderedHoleSpans;
}

Expand All @@ -37,28 +31,5 @@ public StringIndentationTag(
var brush = view.VisualElement.TryFindResource("outlining.verticalrule.foreground") as SolidColorBrush;
return brush?.Color;
}

public override int GetHashCode()
=> throw ExceptionUtilities.Unreachable();

public override bool Equals(object? obj)
=> Equals(obj as StringIndentationTag);

public bool Equals(StringIndentationTag? other)
{
if (other is null)
return false;

if (this.OrderedHoleSpans.Length != other.OrderedHoleSpans.Length)
return false;

for (int i = 0, n = this.OrderedHoleSpans.Length; i < n; i++)
{
if (!_provider.SpanEquals(this.OrderedHoleSpans[i], other.OrderedHoleSpans[i]))
return false;
}

return true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public StringIndentationTaggerProvider(
/// then the span of the tag will grow to the right and the line will immediately redraw in the correct position
/// while we're in the process of recomputing the up to date tags.
/// </summary>
public override SpanTrackingMode SpanTrackingMode => SpanTrackingMode.EdgeInclusive;
protected override SpanTrackingMode SpanTrackingMode => SpanTrackingMode.EdgeInclusive;

protected override ITaggerEventSource CreateEventSource(
ITextView? textView, ITextBuffer subjectBuffer)
Expand Down Expand Up @@ -113,13 +113,9 @@ protected override async Task ProduceTagsAsync(
context.AddTag(new TagSpan<StringIndentationTag>(
region.IndentSpan.ToSnapshotSpan(snapshot),
new StringIndentationTag(
this,
_editorFormatMap,
region.OrderedHoleSpans.SelectAsArray(s => s.ToSnapshotSpan(snapshot)))));
}
}

protected override bool TagEquals(StringIndentationTag tag1, StringIndentationTag tag2)
=> tag1.Equals(tag2);
}
}
6 changes: 3 additions & 3 deletions src/EditorFeatures/Core/BraceMatching/BraceHighlightTag.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
#nullable disable

using Microsoft.VisualStudio.Text.Tagging;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis.BraceMatching
{
internal sealed class BraceHighlightTag : TextMarkerTag
internal class BraceHighlightTag : TextMarkerTag
{
public static readonly BraceHighlightTag StartTag = new(navigateToStart: true);
public static readonly BraceHighlightTag EndTag = new(navigateToStart: false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,5 @@ private static void AddBraces(
context.AddTag(snapshot.GetTagSpan(braces.Value.RightSpan.ToSpan(), BraceHighlightTag.EndTag));
}
}

// Safe to directly compare as BraceHighlightTag uses singleton instances.
protected override bool TagEquals(BraceHighlightTag tag1, BraceHighlightTag tag2)
=> tag1 == tag2;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Tagging;
using Newtonsoft.Json;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis.Classification
Expand Down Expand Up @@ -125,8 +124,5 @@ protected sealed override Task ProduceTagsAsync(
return ClassificationUtilities.ProduceTagsAsync(
context, spanToTag, classificationService, _typeMap, classificationOptions, _type, cancellationToken);
}

protected override bool TagEquals(IClassificationTag tag1, IClassificationTag tag2)
=> tag1.ClassificationType.Classification == tag2.ClassificationType.Classification;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@
// See the LICENSE file in the project root for more information.

using System;
using Microsoft.CodeAnalysis.Classification;
using Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.QuickInfo;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.CodeAnalysis.Workspaces;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Adornments;
using Microsoft.VisualStudio.Text.Tagging;

namespace Microsoft.CodeAnalysis.Diagnostics
{
internal abstract partial class AbstractDiagnosticsAdornmentTaggerProvider<TTag> :
internal abstract class AbstractDiagnosticsAdornmentTaggerProvider<TTag> :
AbstractDiagnosticsTaggerProvider<TTag>
where TTag : class, ITag
{
Expand Down Expand Up @@ -45,6 +48,33 @@ protected AbstractDiagnosticsAdornmentTaggerProvider(
return new TagSpan<TTag>(adjustedSpan, errorTag);
}

protected static object CreateToolTipContent(Workspace workspace, DiagnosticData diagnostic)
{
Action? navigationAction = null;
string? tooltip = null;
if (workspace != null)
{
var helpLinkUri = diagnostic.GetValidHelpLinkUri();
if (helpLinkUri != null)
{
navigationAction = new QuickInfoHyperLink(workspace, helpLinkUri).NavigationAction;
tooltip = diagnostic.HelpLink;
}
}

var diagnosticIdTextRun = navigationAction is null
? new ClassifiedTextRun(ClassificationTypeNames.Text, diagnostic.Id)
: new ClassifiedTextRun(ClassificationTypeNames.Text, diagnostic.Id, navigationAction, tooltip);

return new ContainerElement(
ContainerElementStyle.Wrapped,
new ClassifiedTextElement(
diagnosticIdTextRun,
new ClassifiedTextRun(ClassificationTypeNames.Punctuation, ":"),
new ClassifiedTextRun(ClassificationTypeNames.WhiteSpace, " "),
new ClassifiedTextRun(ClassificationTypeNames.Text, diagnostic.Message)));
}

// By default, tags must have at least length '1' so that they can be visible in the UI layer.
protected virtual SnapshotSpan AdjustSnapshotSpan(SnapshotSpan span)
=> AdjustSnapshotSpan(span, minimumLength: 1, maximumLength: int.MaxValue);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,5 @@ protected internal override ImmutableArray<DiagnosticDataLocation> GetLocationsT
// Default to the base implementation for the diagnostic data
return base.GetLocationsToTag(diagnosticData);
}

protected override bool TagEquals(ClassificationTag tag1, ClassificationTag tag2)
=> tag1.ClassificationType.Classification == tag2.ClassificationType.Classification;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,9 @@
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.CodeAnalysis.Workspaces;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Adornments;
using Microsoft.VisualStudio.Text.Tagging;
using Microsoft.VisualStudio.Utilities;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis.Diagnostics
{
Expand Down Expand Up @@ -75,7 +73,7 @@ protected internal override bool IncludeDiagnostic(DiagnosticData diagnostic)
return null;
}

return new RoslynErrorTag(errorType, workspace, diagnostic);
return new ErrorTag(errorType, CreateToolTipContent(workspace, diagnostic));
}

private static string? GetErrorTypeFromDiagnostic(DiagnosticData diagnostic)
Expand Down Expand Up @@ -128,12 +126,5 @@ protected internal override bool IncludeDiagnostic(DiagnosticData diagnostic)
return PredefinedErrorTypeNames.OtherError;
}
}

protected override bool TagEquals(IErrorTag tag1, IErrorTag tag2)
{
Contract.ThrowIfFalse(tag1 is RoslynErrorTag);
Contract.ThrowIfFalse(tag2 is RoslynErrorTag);
return tag1.Equals(tag2);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
using Microsoft.VisualStudio.Text.Adornments;
using Microsoft.VisualStudio.Text.Tagging;
using Microsoft.VisualStudio.Utilities;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis.Diagnostics
{
Expand Down Expand Up @@ -57,19 +56,14 @@ protected internal override bool SupportsDignosticMode(DiagnosticMode mode)
}

protected override IErrorTag CreateTag(Workspace workspace, DiagnosticData diagnostic)
=> new RoslynErrorTag(PredefinedErrorTypeNames.HintedSuggestion, workspace, diagnostic);
=> new ErrorTag(
PredefinedErrorTypeNames.HintedSuggestion,
CreateToolTipContent(workspace, diagnostic));

protected override SnapshotSpan AdjustSnapshotSpan(SnapshotSpan snapshotSpan)
{
// We always want suggestion tags to be two characters long.
return AdjustSnapshotSpan(snapshotSpan, minimumLength: 2, maximumLength: 2);
}

protected override bool TagEquals(IErrorTag tag1, IErrorTag tag2)
{
Contract.ThrowIfFalse(tag1 is RoslynErrorTag);
Contract.ThrowIfFalse(tag2 is RoslynErrorTag);
return tag1.Equals(tag2);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.ComponentModel.Composition;
using System.Diagnostics;
Expand Down Expand Up @@ -102,11 +101,5 @@ protected override async Task ProduceTagsAsync(
// Let the context know that this was the span we actually tried to tag.
context.SetSpansTagged(ImmutableArray.Create(spanToTag.SnapshotSpan));
}

protected override bool TagEquals(ITextMarkerTag tag1, ITextMarkerTag tag2)
{
Contract.ThrowIfFalse(tag1 == tag2, "ActiveStatementTag is a supposed to be a singleton");
return true;
}
}
}
Loading