diff --git a/src/EditorFeatures/Core/Implementation/Diagnostics/AbstractDiagnosticsTaggerProvider.TaggerProvider.cs b/src/EditorFeatures/Core/Implementation/Diagnostics/AbstractDiagnosticsTaggerProvider.TaggerProvider.cs index 5f594faee95b8076f09cd014d2269bbdc49b267a..6171cce5f4d7c04fc58d13995ac9969682d11152 100644 --- a/src/EditorFeatures/Core/Implementation/Diagnostics/AbstractDiagnosticsTaggerProvider.TaggerProvider.cs +++ b/src/EditorFeatures/Core/Implementation/Diagnostics/AbstractDiagnosticsTaggerProvider.TaggerProvider.cs @@ -3,8 +3,10 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; +using System.Linq; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Editor.Shared.Preview; using Microsoft.CodeAnalysis.Editor.Shared.Tagging; using Microsoft.CodeAnalysis.Editor.Tagging; using Microsoft.CodeAnalysis.Options; @@ -86,6 +88,13 @@ private void ProduceTags(TaggerContext context, DocumentSnapshotSpan spanT return; } + // See if we've marked any spans as those we want to suppress diagnostics for. + // This can happen for buffers used in the preview workspace where some feature + // is generating code that it doesn't want errors shown for. + var buffer = spanToTag.SnapshotSpan.Snapshot.TextBuffer; + NormalizedSnapshotSpanCollection suppressedDiagnosticsSpans = null; + buffer?.Properties.TryGetProperty(PredefinedPreviewTaggerKeys.SuppressDiagnosticsSpansKey, out suppressedDiagnosticsSpans); + // Producing tags is simple. We just grab the diagnostics we were already told about, // and we convert them to tag spans. object id; @@ -120,7 +129,8 @@ private void ProduceTags(TaggerContext context, DocumentSnapshotSpan spanT .ToSnapshotSpan(editorSnapshot) .TranslateTo(requestedSnapshot, SpanTrackingMode.EdgeExclusive); - if (actualSpan.IntersectsWith(requestedSpan)) + if (actualSpan.IntersectsWith(requestedSpan) && + !IsSuppressed(suppressedDiagnosticsSpans, actualSpan)) { var tagSpan = _owner.CreateTagSpan(isLiveUpdate, actualSpan, diagnosticData); if (tagSpan != null) @@ -132,6 +142,11 @@ private void ProduceTags(TaggerContext context, DocumentSnapshotSpan spanT } } + private bool IsSuppressed(NormalizedSnapshotSpanCollection suppressedSpans, SnapshotSpan span) + { + return suppressedSpans != null && suppressedSpans.IntersectsWith(span); + } + internal void OnDiagnosticsUpdated(DiagnosticsUpdatedArgs e, SourceText sourceText, ITextSnapshot editorSnapshot) { // We were told about new diagnostics. Store them, and then let the diff --git a/src/EditorFeatures/Core/Implementation/Preview/PreviewFactoryService.cs b/src/EditorFeatures/Core/Implementation/Preview/PreviewFactoryService.cs index 89d5d4efa9c6a845fb278b8e72ed6fd635648dd5..ca7c70a968b067d9fe3a6a78223a253f7c805619 100644 --- a/src/EditorFeatures/Core/Implementation/Preview/PreviewFactoryService.cs +++ b/src/EditorFeatures/Core/Implementation/Preview/PreviewFactoryService.cs @@ -398,7 +398,9 @@ public Task CreateChangedDocumentPreviewViewAsync(Document oldDocument, .Select(a => WarningAnnotation.GetDescription(a)) .Distinct(); - AttachConflictAndWarningAnnotationToBuffer(newBuffer, conflictSpans, warningSpans); + var suppressDiagnosticsNodes = newRoot.GetAnnotatedNodesAndTokens(SuppressDiagnosticsAnnotation.Kind); + var suppressDiagnosticsSpans = suppressDiagnosticsNodes.Select(n => n.Span.ToSpan()).ToList(); + AttachAnnotationsToBuffer(newBuffer, conflictSpans, warningSpans, suppressDiagnosticsSpans); description = conflictSpans.Count == 0 && warningSpans.Count == 0 ? null @@ -520,11 +522,13 @@ public Task CreateChangedAdditionalDocumentPreviewViewAsync(TextDocument return CreateNewDifferenceViewerAsync(leftWorkspace, rightWorkspace, originalBuffer, changedBuffer, zoomLevel, cancellationToken); } - private static void AttachConflictAndWarningAnnotationToBuffer(ITextBuffer newBuffer, IEnumerable conflictSpans, IEnumerable warningSpans) + private static void AttachAnnotationsToBuffer( + ITextBuffer newBuffer, IEnumerable conflictSpans, IEnumerable warningSpans, IEnumerable suppressDiagnosticsSpans) { // Attach the spans to the buffer. newBuffer.Properties.AddProperty(PredefinedPreviewTaggerKeys.ConflictSpansKey, new NormalizedSnapshotSpanCollection(newBuffer.CurrentSnapshot, conflictSpans)); newBuffer.Properties.AddProperty(PredefinedPreviewTaggerKeys.WarningSpansKey, new NormalizedSnapshotSpanCollection(newBuffer.CurrentSnapshot, warningSpans)); + newBuffer.Properties.AddProperty(PredefinedPreviewTaggerKeys.SuppressDiagnosticsSpansKey, new NormalizedSnapshotSpanCollection(newBuffer.CurrentSnapshot, suppressDiagnosticsSpans)); } private ITextBuffer CreateNewBuffer(Document document, CancellationToken cancellationToken) diff --git a/src/EditorFeatures/Core/Shared/Preview/PredefinedPreviewTaggerKeys.cs b/src/EditorFeatures/Core/Shared/Preview/PredefinedPreviewTaggerKeys.cs index 218053c21f42c7e1c93eb6f27f586c8f16fa21db..fabb6df94aca17e1d81326c81979886b4031c3e9 100644 --- a/src/EditorFeatures/Core/Shared/Preview/PredefinedPreviewTaggerKeys.cs +++ b/src/EditorFeatures/Core/Shared/Preview/PredefinedPreviewTaggerKeys.cs @@ -6,5 +6,6 @@ internal static class PredefinedPreviewTaggerKeys { public static readonly object ConflictSpansKey = new object(); public static readonly object WarningSpansKey = new object(); + public static readonly object SuppressDiagnosticsSpansKey = new object(); } } diff --git a/src/Workspaces/Core/Portable/CodeActions/Annotations/SuppressDiagnosticsAnnotation.cs b/src/Workspaces/Core/Portable/CodeActions/Annotations/SuppressDiagnosticsAnnotation.cs new file mode 100644 index 0000000000000000000000000000000000000000..acc97570f897a933e484bff9b5983d819513b8af --- /dev/null +++ b/src/Workspaces/Core/Portable/CodeActions/Annotations/SuppressDiagnosticsAnnotation.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Microsoft.CodeAnalysis.CodeActions +{ + internal class SuppressDiagnosticsAnnotation + { + public const string Kind = "CodeAction_SuppressDiagnostics"; + + public static SyntaxAnnotation Create() + { + return new SyntaxAnnotation(Kind); + } + } +} \ No newline at end of file diff --git a/src/Workspaces/Core/Portable/Workspaces.csproj b/src/Workspaces/Core/Portable/Workspaces.csproj index a44cb8cff38c80eac2342e194b23046c7b244bb0..ec864e86155aad31ffffa78c5247fd588c6b5033 100644 --- a/src/Workspaces/Core/Portable/Workspaces.csproj +++ b/src/Workspaces/Core/Portable/Workspaces.csproj @@ -291,6 +291,7 @@ +