提交 29e7f7f7 编写于 作者: C CyrusNajmabadi

Provide a way for code actions to supress diagnostics in their previews.

This is useful for code actions that will make changes that can't be
represented in the Roslyn snapshot model.  Because of this, the
preview may end up showing errors that teh code fix doesn't want to
be shown (because after the code fix actually applies, no error will
occur).
上级 8b8d7ec5
......@@ -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<TTag> 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<TTag> 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<TTag> 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
......
......@@ -398,7 +398,9 @@ public Task<object> 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<object> CreateChangedAdditionalDocumentPreviewViewAsync(TextDocument
return CreateNewDifferenceViewerAsync(leftWorkspace, rightWorkspace, originalBuffer, changedBuffer, zoomLevel, cancellationToken);
}
private static void AttachConflictAndWarningAnnotationToBuffer(ITextBuffer newBuffer, IEnumerable<Span> conflictSpans, IEnumerable<Span> warningSpans)
private static void AttachAnnotationsToBuffer(
ITextBuffer newBuffer, IEnumerable<Span> conflictSpans, IEnumerable<Span> warningSpans, IEnumerable<Span> 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)
......
......@@ -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();
}
}
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
......@@ -291,6 +291,7 @@
<Compile Include="Classification\Classifier.cs" />
<Compile Include="Classification\Classifiers\ISyntaxClassifier.cs" />
<Compile Include="Classification\IClassificationService.cs" />
<Compile Include="CodeActions\Annotations\SuppressDiagnosticsAnnotation.cs" />
<Compile Include="CodeActions\Operations\PreviewOperation.cs" />
<Compile Include="CodeCleanup\AbstractCodeCleanerService.cs" />
<Compile Include="CodeCleanup\CodeCleaner.cs" />
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册