提交 6e6163c9 编写于 作者: M manishv

Add more diagnostics for intermittently failing unit test (Bug 1000457:...

Add more diagnostics for intermittently failing unit test (Bug 1000457: SuppressSyntaxDiagnosticsOnEventAddAccessorBasic - compiler unit test failing on build servers)

This unit test seems to be failing intermittently on build servers for release builds. I added some debug only code (changeset 1314572) for better diagnostics of this failure, but that turns out to be useless due to release only failures. So I am rolling back changeset 1314572 and adding unit test framework support for configuring if the analyzer driver should handle exceptions or not. The default behavior for unit tests would be to *not* catch any driver/analyzer exceptions. However, tests can explicitly flip his behavior for testing exception scenarios.
This should enable us to get a stack dump when this test fails again on build servers. (changeset 1317998)
上级 e188697a
......@@ -81,17 +81,15 @@ public class C
}").VerifyAnalyzerDiagnostics(new[] { new CSharpTrackingDiagnosticAnalyzer() });
}
#endregion
#endregion
#if !DEBUG
[Fact]
public void AnalyzerDriverIsSafeAgainstAnalyzerExceptions()
{
var compilation = CreateCompilationWithMscorlib45(TestResource.AllInOneCSharpCode, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.Experimental));
ThrowingDiagnosticAnalyzer<SyntaxKind>.VerifyAnalyzerEngineIsSafeAgainstExceptions(analyzer =>
compilation.GetCSharpAnalyzerDiagnostics(new[] { analyzer }, continueOnError: true), typeof(AnalyzerDriver).Name);
compilation.GetCSharpAnalyzerDiagnostics(new[] { analyzer }, null, CodeAnalysis.DiagnosticExtensions.AlwaysCatchAnalyzerExceptions), typeof(AnalyzerDriver).Name);
}
#endif
[Fact]
public void AnalyzerOptionsArePassedToAllAnalyzers()
......
......@@ -180,7 +180,7 @@ int x1(int x2)
// public class C : NotFound
Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "NotFound").WithArguments("NotFound")
)
.VerifyCSharpAnalyzerDiagnostics(new IDiagnosticAnalyzer[] { new ComplainAboutX() }, null,
.VerifyCSharpAnalyzerDiagnostics(new IDiagnosticAnalyzer[] { new ComplainAboutX() }, null, null,
// (5,18): warning CA9999_UseOfVariableThatStartsWithX: Use of variable whose name starts with 'x': 'x1'
// int x3 = x1(x2);
Diagnostic("CA9999_UseOfVariableThatStartsWithX", "x1").WithArguments("x1"),
......@@ -212,7 +212,7 @@ public class C : NotFound
// public class C : NotFound
Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "NotFound").WithArguments("NotFound")
)
.VerifyCSharpAnalyzerDiagnostics(new IDiagnosticAnalyzer[] { new ComplainAboutX() }, null,
.VerifyCSharpAnalyzerDiagnostics(new IDiagnosticAnalyzer[] { new ComplainAboutX() }, null, null,
// (6,14): warning CA9999_UseOfVariableThatStartsWithX: Use of variable whose name starts with 'x': 'x1'
// int x3 = x1 + x2;
Diagnostic("CA9999_UseOfVariableThatStartsWithX", "x1").WithArguments("x1"),
......@@ -273,7 +273,7 @@ int x1(int x2)
// (2,18): error CS0246: The type or namespace name 'NotFound' could not be found (are you missing a using directive or an assembly reference?)
// public class C : NotFound
Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "NotFound").WithArguments("NotFound"))
.VerifyCSharpAnalyzerDiagnostics(new IDiagnosticAnalyzer[] { new ComplainAboutX() }, null,
.VerifyCSharpAnalyzerDiagnostics(new IDiagnosticAnalyzer[] { new ComplainAboutX() }, null, null,
// (6,18): error CA9999_UseOfVariableThatStartsWithX: Use of variable whose name starts with 'x': 'x1'
// int x3 = x1(x2);
Diagnostic("CA9999_UseOfVariableThatStartsWithX", "x1").WithArguments("x1").WithWarningAsError(true),
......@@ -306,7 +306,7 @@ int x1(int x2)
// public class C : NotFound
Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "NotFound").WithArguments("NotFound")
)
.VerifyCSharpAnalyzerDiagnostics(new IDiagnosticAnalyzer[] { new ComplainAboutX() }, null,
.VerifyCSharpAnalyzerDiagnostics(new IDiagnosticAnalyzer[] { new ComplainAboutX() }, null, null,
// (6,18): error CA9999_UseOfVariableThatStartsWithX: Use of variable whose name starts with 'x': 'x1'
// int x3 = x1(x2);
Diagnostic("CA9999_UseOfVariableThatStartsWithX", "x1").WithArguments("x1").WithWarningAsError(true),
......@@ -387,7 +387,7 @@ public class C { }";
CreateCompilationWithMscorlib45(source, options: options)
.VerifyDiagnostics()
.VerifyCSharpAnalyzerDiagnostics(new IDiagnosticAnalyzer[] { new SyntaxAndSymbolAnalyzer() }, null,
.VerifyCSharpAnalyzerDiagnostics(new IDiagnosticAnalyzer[] { new SyntaxAndSymbolAnalyzer() }, null, null,
// Symbol diagnostics
Diagnostic("XX0001", "C").WithWarningAsError(true),
// Syntax diagnostics
......
......@@ -1137,7 +1137,7 @@ protected virtual void Verify(string source, string language, IDiagnosticAnalyze
{
Assert.True(analyzers != null && analyzers.Length > 0, "Must specify at least one diagnostic analyzer to test suppression");
var compilation = CreateCompilation(source, language, analyzers, rootNamespace);
compilation.VerifyAnalyzerDiagnostics(analyzers, diagnostics);
compilation.VerifyAnalyzerDiagnostics(analyzers, expected: diagnostics);
}
// Generate a diagnostic on every token in the specified spans, and verify that only the specified diagnostics are not suppressed
......
// Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.CodeAnalysis.Collections;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
using System;
using System.Collections.Generic;
......@@ -9,7 +8,6 @@
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
......@@ -26,7 +24,7 @@ public abstract class AnalyzerDriver : IDisposable
private const string DiagnosticId = "AnalyzerDriver";
private readonly Action<Diagnostic> addDiagnostic;
private Compilation compilation;
internal Func<Exception, IDiagnosticAnalyzer, bool> continueOnAnalyzerException = (e, a) => true; // should be a parameter?
internal Func<Exception, IDiagnosticAnalyzer, bool> continueOnAnalyzerException;
private ImmutableArray<Task> workers;
private ImmutableArray<Task> syntaxAnalyzers;
......@@ -68,12 +66,20 @@ internal static Compilation AttachAnalyzerDriverToCompilation(Compilation compil
/// <param name="analyzers">The set of analyzers to include in the analysis</param>
/// <param name="options">Options that are passed to analyzers</param>
/// <param name="cancellationToken">a cancellation token that can be used to abort analysis</param>
protected AnalyzerDriver(ImmutableArray<IDiagnosticAnalyzer> analyzers, AnalyzerOptions options, CancellationToken cancellationToken)
/// <param name="continueOnAnalyzerException">Delegate which is invoked when an analyzer throws an exception.
/// If a non-null delegate is provided and it returns true, then the exception is handled and converted into a diagnostic and driver continues with other analyzers.
/// Otherwise if it returns false, then the exception is not handled by the driver.
/// If null, then the driver always handles the exception.
/// </param>
protected AnalyzerDriver(ImmutableArray<IDiagnosticAnalyzer> analyzers, AnalyzerOptions options, CancellationToken cancellationToken, Func<Exception, IDiagnosticAnalyzer, bool> continueOnAnalyzerException = null)
{
CompilationEventQueue = new AsyncQueue<CompilationEvent>();
DiagnosticQueue = new AsyncQueue<Diagnostic>();
addDiagnostic = GetDiagnosticSinkWithSuppression();
analyzerOptions = options;
this.CompilationEventQueue = new AsyncQueue<CompilationEvent>();
this.DiagnosticQueue = new AsyncQueue<Diagnostic>();
this.addDiagnostic = GetDiagnosticSinkWithSuppression();
this.analyzerOptions = options;
Func<Exception, IDiagnosticAnalyzer, bool> defaultExceptionHandler = (exception, analyzer) => true;
this.continueOnAnalyzerException = continueOnAnalyzerException ?? defaultExceptionHandler;
// start the first task to drain the event queue. The first compilation event is to be handled before
// any other ones, so we cannot have more than one event processing task until the first event has been handled.
......@@ -259,9 +265,6 @@ private async Task ProcessEventsAsync(CancellationToken cancellationToken)
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true);
addDiagnostic(Diagnostic.Create(desc, Location.None));
#if DEBUG
throw ex;
#endif
}
}
}
......@@ -544,18 +547,12 @@ protected static void ExecuteAndCatchIfThrows(IDiagnosticAnalyzer a, Action<Diag
{
// Create a info diagnostic saying that the analyzer failed
addDiagnostic(GetAnalyzerDiagnostic(a, oce));
#if DEBUG
throw oce;
#endif
}
}
catch (Exception e) if (continueOnAnalyzerException(e, a))
{
// Create a info diagnostic saying that the analyzer failed
addDiagnostic(GetAnalyzerDiagnostic(a, e));
#if DEBUG
throw e;
#endif
}
}
......@@ -597,7 +594,12 @@ public class AnalyzerDriver<TSyntaxKind> : AnalyzerDriver
/// <param name="getKind">A delegate that returns the language-specific kind for a given syntax node</param>
/// <param name="options">Options that are passed to analyzers</param>
/// <param name="cancellationToken">a cancellation token that can be used to abort analysis</param>
public AnalyzerDriver(ImmutableArray<IDiagnosticAnalyzer> analyzers, Func<SyntaxNode, TSyntaxKind> getKind, AnalyzerOptions options, CancellationToken cancellationToken) : base(analyzers, options, cancellationToken)
/// <param name="continueOnAnalyzerException">Delegate which is invoked when an analyzer throws an exception.
/// If a non-null delegate is provided and it returns true, then the exception is handled and converted into a diagnostic and driver continues with other analyzers.
/// Otherwise if it returns false, then the exception is not handled by the driver.
/// If null, then the driver always handles the exception.
/// </param>
public AnalyzerDriver(ImmutableArray<IDiagnosticAnalyzer> analyzers, Func<SyntaxNode, TSyntaxKind> getKind, AnalyzerOptions options, CancellationToken cancellationToken, Func<Exception, IDiagnosticAnalyzer, bool> continueOnAnalyzerException = null) : base(analyzers, options, cancellationToken, continueOnAnalyzerException)
{
GetKind = getKind;
}
......@@ -885,9 +887,6 @@ protected override async Task AnalyzeDeclaringReferenceAsync(SymbolDeclaredCompi
{
// Create a info diagnostic saying that the analyzer failed
addDiagnostic(GetAnalyzerDiagnostic(nodeAnalyzer, e));
#if DEBUG
throw e;
#endif
}
}
......
......@@ -38,14 +38,12 @@ End Enum
CreateCompilationWithMscorlib(source).VerifyAnalyzerDiagnostics({New BasicTrackingDiagnosticAnalyzer()})
End Sub
#If Not DEBUG Then
<Fact>
Public Sub AnalyzerDriverIsSafeAgainstAnalyzerExceptions()
Dim compilation = CreateCompilationWithMscorlib({TestResource.AllInOneVisualBasicCode})
ThrowingDiagnosticAnalyzer(Of SyntaxKind).VerifyAnalyzerEngineIsSafeAgainstExceptions(
Function(analyzer) compilation.GetVisualBasicAnalyzerDiagnostics({analyzer}, continueOnError:=True), GetType(AnalyzerDriver).Name)
Function(analyzer) compilation.GetVisualBasicAnalyzerDiagnostics({analyzer}, Nothing, DiagnosticExtensions.AlwaysCatchAnalyzerExceptions), GetType(AnalyzerDriver).Name)
End Sub
#End If
<Fact>
Public Sub AnalyzerOptionsArePassedToAllAnalyzers()
......
......@@ -426,7 +426,7 @@ End Module
Dim comp = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime(source)
comp.VerifyDiagnostics()
comp.VerifyAnalyzerDiagnostics({analyzer},
comp.VerifyAnalyzerDiagnostics({analyzer}, Nothing,
AnalyzerDiagnostic("XX001", <![CDATA[Public Module ThisModule]]>))
End Sub
......@@ -474,7 +474,7 @@ End Class
Assert.NotNull(MyTemplate)
compilation.VerifyDiagnostics()
compilation.VerifyAnalyzerDiagnostics({analyzer},
compilation.VerifyAnalyzerDiagnostics({analyzer}, Nothing,
AnalyzerDiagnostic("XX001", <![CDATA[C]]>))
End Sub
End Class
......
......@@ -3113,13 +3113,13 @@ End Module
Dim analyzers = {analyzer}
Dim expectedId = analyzer.SupportedDiagnostics.Single.Id
Dim expectedMsg = analyzer.SupportedDiagnostics.Single.MessageFormat
CreateCompilationWithMscorlibAndVBRuntime(compXml).VerifyAnalyzerDiagnostics(analyzers,
CreateCompilationWithMscorlibAndVBRuntime(compXml).VerifyAnalyzerDiagnostics(analyzers, Nothing,
New Test.Utilities.DiagnosticDescription(expectedId, "As Long", Nothing, Nothing, Nothing, False, GetType(String)).WithLocation(10, 15))
Dim diagOptions = New Dictionary(Of String, ReportDiagnostic)
diagOptions.Add("soMeId", ReportDiagnostic.Error)
Dim compOptions = TestOptions.ReleaseExe.WithSpecificDiagnosticOptions(diagOptions)
CreateCompilationWithMscorlibAndVBRuntime(compXml, compOptions).VerifyAnalyzerDiagnostics(analyzers,
CreateCompilationWithMscorlibAndVBRuntime(compXml, compOptions).VerifyAnalyzerDiagnostics(analyzers, Nothing,
New Test.Utilities.DiagnosticDescription(expectedId, "As Long", Nothing, Nothing, Nothing, False, GetType(String)).WithLocation(10, 15).WithWarningAsError(True),
Diagnostic(ERRID.ERR_WarningTreatedAsError, "As Long").WithArguments(expectedMsg).WithLocation(10, 15))
......@@ -3129,7 +3129,7 @@ End Module
CreateCompilationWithMscorlibAndVBRuntime(compXml, compOptions).VerifyAnalyzerDiagnostics(analyzers)
compOptions = TestOptions.ReleaseExe.WithGeneralDiagnosticOption(ReportDiagnostic.Error)
CreateCompilationWithMscorlibAndVBRuntime(compXml, compOptions).VerifyAnalyzerDiagnostics(analyzers,
CreateCompilationWithMscorlibAndVBRuntime(compXml, compOptions).VerifyAnalyzerDiagnostics(analyzers, Nothing,
New Test.Utilities.DiagnosticDescription(expectedId, "As Long", Nothing, Nothing, Nothing, False, GetType(String)).WithLocation(10, 15).WithWarningAsError(True),
Diagnostic(ERRID.ERR_WarningTreatedAsError, "As Long").WithArguments(expectedMsg).WithLocation(10, 15))
......@@ -3224,13 +3224,13 @@ End Module
Dim analyzers = {analyzer}
Dim expectedId = analyzer.SupportedDiagnostics.Single.Id
Dim expectedMsg = analyzer.SupportedDiagnostics.Single.MessageFormat
CreateCompilationWithMscorlibAndVBRuntime(compXml).VerifyAnalyzerDiagnostics(analyzers,
CreateCompilationWithMscorlibAndVBRuntime(compXml).VerifyAnalyzerDiagnostics(analyzers, Nothing,
New Test.Utilities.DiagnosticDescription(expectedId, "As Long", Nothing, Nothing, Nothing, False, GetType(String)).WithLocation(10, 15))
Dim diagOptions = New Dictionary(Of String, ReportDiagnostic)
diagOptions.Add("__someThing_123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789023456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678902345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789023456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678902345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789023456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678902345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", ReportDiagnostic.Error)
Dim compOptions = TestOptions.ReleaseExe.WithSpecificDiagnosticOptions(diagOptions)
CreateCompilationWithMscorlibAndVBRuntime(compXml, compOptions).VerifyAnalyzerDiagnostics(analyzers,
CreateCompilationWithMscorlibAndVBRuntime(compXml, compOptions).VerifyAnalyzerDiagnostics(analyzers, Nothing,
New Test.Utilities.DiagnosticDescription(expectedId, "As Long", Nothing, Nothing, Nothing, False, GetType(String)).WithLocation(10, 15).WithWarningAsError(True),
Diagnostic(ERRID.ERR_WarningTreatedAsError, "As Long").WithArguments(expectedMsg).WithLocation(10, 15))
......@@ -3240,7 +3240,7 @@ End Module
CreateCompilationWithMscorlibAndVBRuntime(compXml, compOptions).VerifyAnalyzerDiagnostics(analyzers)
compOptions = TestOptions.ReleaseExe.WithGeneralDiagnosticOption(ReportDiagnostic.Error)
CreateCompilationWithMscorlibAndVBRuntime(compXml, compOptions).VerifyAnalyzerDiagnostics(analyzers,
CreateCompilationWithMscorlibAndVBRuntime(compXml, compOptions).VerifyAnalyzerDiagnostics(analyzers, Nothing,
New Test.Utilities.DiagnosticDescription(expectedId, "As Long", Nothing, Nothing, Nothing, False, GetType(String)).WithLocation(10, 15).WithWarningAsError(True),
Diagnostic(ERRID.ERR_WarningTreatedAsError, "As Long").WithArguments(expectedMsg).WithLocation(10, 15))
......
......@@ -23,7 +23,6 @@ protected override IDiagnosticAnalyzer GetCSharpDiagnosticAnalyzer()
return new ExceptionThrowingSymbolAnalyzer_ThrowSymbolKindsOfInterest();
}
#if !DEBUG
[Fact, Trait(Traits.Feature, Traits.Features.Diagnostics)]
public void TestTypeParameterNamesCSharp()
{
......@@ -42,12 +41,11 @@ public class Class6<TTypeParameter>
";
var diagnosticsBag = DiagnosticBag.GetInstance();
var documentsAndSpan = GetDocumentsAndSpans(new[] { source }, LanguageNames.CSharp);
AnalyzeDocumentCore(GetCSharpDiagnosticAnalyzer(), documentsAndSpan.Item1[0], diagnosticsBag.Add, null, continueOnError: true);
AnalyzeDocumentCore(GetCSharpDiagnosticAnalyzer(), documentsAndSpan.Item1[0], diagnosticsBag.Add, null, continueOnAnalyzerException: DiagnosticExtensions.AlwaysCatchAnalyzerExceptions);
var diagnostics = diagnosticsBag.ToReadOnlyAndFree();
Assert.True(diagnostics.Length > 0);
Assert.Equal(diagnostics[0].ToString(), "info AnalyzerDriver: The Compiler Analyzer '" + GetCSharpDiagnosticAnalyzer().GetType() + "' threw an exception with message 'The method or operation is not implemented.'.");
}
#endif
#region "Test_Class"
internal const string RuleId = "CA1715_Test";
......
......@@ -293,10 +293,10 @@ protected static Diagnostic[] GetSortedDiagnostics(IDiagnosticAnalyzer analyzer,
return results;
}
protected static void AnalyzeDocumentCore(IDiagnosticAnalyzer analyzer, Document document, Action<Diagnostic> addDiagnostic, TextSpan? span = null, bool continueOnError = false)
protected static void AnalyzeDocumentCore(IDiagnosticAnalyzer analyzer, Document document, Action<Diagnostic> addDiagnostic, TextSpan? span = null, Func<Exception, IDiagnosticAnalyzer, bool> continueOnAnalyzerException = null)
{
var semanticModel = document.GetSemanticModelAsync().Result;
var diagnostics = semanticModel.Compilation.GetAnalyzerDiagnostics(new[] { analyzer }, continueOnError: continueOnError);
var diagnostics = semanticModel.Compilation.GetAnalyzerDiagnostics(new[] { analyzer }, continueOnAnalyzerException: continueOnAnalyzerException);
foreach (var diagnostic in diagnostics)
{
if (!span.HasValue ||
......
......@@ -19,6 +19,9 @@ namespace Microsoft.CodeAnalysis
public static class DiagnosticExtensions
{
private const int EN_US = 1033;
public static Func<Exception, IDiagnosticAnalyzer, bool> AlwaysCatchAnalyzerExceptions = (e, a) => true;
public static Func<Exception, IDiagnosticAnalyzer, bool> DonotCatchAnalyzerExceptions = (e, a) => e is OperationCanceledException;
/// <summary>
/// This is obsolete. Use Verify instead.
/// </summary>
......@@ -93,93 +96,93 @@ public static TCompilation VerifyDiagnostics<TCompilation>(this TCompilation c,
return c;
}
public static CSharpCompilation VerifyCSharpAnalyzerDiagnostics(this CSharpCompilation c, IDiagnosticAnalyzer[] analyzers, AnalyzerOptions options = null, params DiagnosticDescription[] expected)
public static CSharpCompilation VerifyCSharpAnalyzerDiagnostics(this CSharpCompilation c, IDiagnosticAnalyzer[] analyzers, AnalyzerOptions options = null, Func<Exception, IDiagnosticAnalyzer, bool> continueOnAnalyzerException = null, params DiagnosticDescription[] expected)
{
return VerifyAnalyzerDiagnostics(c, n => n.CSharpKind(), analyzers, options, expected: expected);
return VerifyAnalyzerDiagnostics(c, n => n.CSharpKind(), analyzers, options, expected, continueOnAnalyzerException);
}
public static VisualBasicCompilation VerifyVisualBasicAnalyzerDiagnostics(this VisualBasicCompilation c, IDiagnosticAnalyzer[] analyzers, AnalyzerOptions options = null, params DiagnosticDescription[] expected)
public static VisualBasicCompilation VerifyVisualBasicAnalyzerDiagnostics(this VisualBasicCompilation c, IDiagnosticAnalyzer[] analyzers, AnalyzerOptions options = null, Func<Exception, IDiagnosticAnalyzer, bool> continueOnAnalyzerException = null, params DiagnosticDescription[] expected)
{
return VerifyAnalyzerDiagnostics(c, n => n.VisualBasicKind(), analyzers, options, expected: expected);
return VerifyAnalyzerDiagnostics(c, n => n.VisualBasicKind(), analyzers, options, expected, continueOnAnalyzerException);
}
public static TCompilation VerifyAnalyzerOccuranceCount<TCompilation>(this TCompilation c, IDiagnosticAnalyzer[] analyzers, int expectedCount)
public static TCompilation VerifyAnalyzerOccuranceCount<TCompilation>(this TCompilation c, IDiagnosticAnalyzer[] analyzers, int expectedCount, Func<Exception, IDiagnosticAnalyzer, bool> continueOnAnalyzerException = null)
where TCompilation : Compilation
{
var csComp = c as CSharpCompilation;
if (csComp != null)
{
Assert.Equal(expectedCount, csComp.GetCSharpAnalyzerDiagnostics(analyzers).Length);
Assert.Equal(expectedCount, csComp.GetCSharpAnalyzerDiagnostics(analyzers, null, continueOnAnalyzerException).Length);
return c;
}
else
{
var vbComp = c as VisualBasicCompilation;
Assert.Equal(expectedCount, vbComp.GetVisualBasicAnalyzerDiagnostics(analyzers).Length);
Assert.Equal(expectedCount, vbComp.GetVisualBasicAnalyzerDiagnostics(analyzers, null, continueOnAnalyzerException).Length);
return c;
}
}
public static TCompilation VerifyAnalyzerDiagnostics<TCompilation>(
this TCompilation c, IDiagnosticAnalyzer[] analyzers, params DiagnosticDescription[] expected)
this TCompilation c, IDiagnosticAnalyzer[] analyzers, Func<Exception, IDiagnosticAnalyzer, bool> continueOnAnalyzerException = null, params DiagnosticDescription[] expected)
where TCompilation : Compilation
{
return c.VerifyAnalyzerDiagnostics(analyzers, null, expected);
return c.VerifyAnalyzerDiagnostics(analyzers, null, continueOnAnalyzerException, expected);
}
public static TCompilation VerifyAnalyzerDiagnostics<TCompilation>(
this TCompilation c, IDiagnosticAnalyzer[] analyzers, AnalyzerOptions options, params DiagnosticDescription[] expected)
this TCompilation c, IDiagnosticAnalyzer[] analyzers, AnalyzerOptions options, Func<Exception, IDiagnosticAnalyzer, bool> continueOnAnalyzerException = null, params DiagnosticDescription[] expected)
where TCompilation : Compilation
{
var csComp = c as CSharpCompilation;
if (csComp != null)
{
return csComp.VerifyCSharpAnalyzerDiagnostics(analyzers, options, expected) as TCompilation;
return csComp.VerifyCSharpAnalyzerDiagnostics(analyzers, options, continueOnAnalyzerException, expected) as TCompilation;
}
else
{
var vbComp = c as VisualBasicCompilation;
return vbComp.VerifyVisualBasicAnalyzerDiagnostics(analyzers, options, expected) as TCompilation;
return vbComp.VerifyVisualBasicAnalyzerDiagnostics(analyzers, options, continueOnAnalyzerException, expected) as TCompilation;
}
}
private static TCompilation VerifyAnalyzerDiagnostics<TCompilation, TSyntaxKind>(
this TCompilation c, Func<SyntaxNode, TSyntaxKind> getKind, IDiagnosticAnalyzer[] analyzers, AnalyzerOptions options, DiagnosticDescription[] expected)
this TCompilation c, Func<SyntaxNode, TSyntaxKind> getKind, IDiagnosticAnalyzer[] analyzers, AnalyzerOptions options, DiagnosticDescription[] expected, Func<Exception, IDiagnosticAnalyzer, bool> continueOnAnalyzerException = null)
where TCompilation : Compilation
where TSyntaxKind : struct
{
ImmutableArray<Diagnostic> diagnostics;
c = c.GetAnalyzerDiagnostics(getKind, analyzers, options, continueOnError: false, diagnostics: out diagnostics);
c = c.GetAnalyzerDiagnostics(getKind, analyzers, options, continueOnAnalyzerException, diagnostics: out diagnostics);
diagnostics.Verify(expected);
return c; // note this is a new compilation
}
public static ImmutableArray<Diagnostic> GetCSharpAnalyzerDiagnostics(this CSharpCompilation c, IDiagnosticAnalyzer[] analyzers, AnalyzerOptions options = null, bool continueOnError = false)
public static ImmutableArray<Diagnostic> GetCSharpAnalyzerDiagnostics(this CSharpCompilation c, IDiagnosticAnalyzer[] analyzers, AnalyzerOptions options = null, Func<Exception, IDiagnosticAnalyzer, bool> continueOnAnalyzerException = null)
{
ImmutableArray<Diagnostic> diagnostics;
c = GetAnalyzerDiagnostics(c, n => n.CSharpKind(), analyzers, options, continueOnError, out diagnostics);
c = GetAnalyzerDiagnostics(c, n => n.CSharpKind(), analyzers, options, continueOnAnalyzerException, out diagnostics);
return diagnostics;
}
public static ImmutableArray<Diagnostic> GetVisualBasicAnalyzerDiagnostics(this VisualBasicCompilation c, IDiagnosticAnalyzer[] analyzers, AnalyzerOptions options = null, bool continueOnError = false)
public static ImmutableArray<Diagnostic> GetVisualBasicAnalyzerDiagnostics(this VisualBasicCompilation c, IDiagnosticAnalyzer[] analyzers, AnalyzerOptions options = null, Func<Exception, IDiagnosticAnalyzer, bool> continueOnAnalyzerException = null)
{
ImmutableArray<Diagnostic> diagnostics;
c = GetAnalyzerDiagnostics(c, n => n.VisualBasicKind(), analyzers, options, continueOnError, out diagnostics);
c = GetAnalyzerDiagnostics(c, n => n.VisualBasicKind(), analyzers, options, continueOnAnalyzerException, out diagnostics);
return diagnostics;
}
public static ImmutableArray<Diagnostic> GetAnalyzerDiagnostics<TCompilation>(this TCompilation c, IDiagnosticAnalyzer[] analyzers, AnalyzerOptions options = null, bool continueOnError = false)
public static ImmutableArray<Diagnostic> GetAnalyzerDiagnostics<TCompilation>(this TCompilation c, IDiagnosticAnalyzer[] analyzers, AnalyzerOptions options = null, Func<Exception, IDiagnosticAnalyzer, bool> continueOnAnalyzerException = null)
where TCompilation : Compilation
{
var csComp = c as CSharpCompilation;
if (csComp != null)
{
return csComp.GetCSharpAnalyzerDiagnostics(analyzers, options, continueOnError);
return csComp.GetCSharpAnalyzerDiagnostics(analyzers, options, continueOnAnalyzerException);
}
else
{
var vbComp = c as VisualBasicCompilation;
return vbComp.GetVisualBasicAnalyzerDiagnostics(analyzers, options, continueOnError);
return vbComp.GetVisualBasicAnalyzerDiagnostics(analyzers, options, continueOnAnalyzerException);
}
}
......@@ -188,12 +191,15 @@ public static ImmutableArray<Diagnostic> GetAnalyzerDiagnostics<TCompilation>(th
Func<SyntaxNode, TSyntaxKind> getKind,
IDiagnosticAnalyzer[] analyzers,
AnalyzerOptions options,
bool continueOnError,
Func<Exception, IDiagnosticAnalyzer, bool> continueOnAnalyzerException,
out ImmutableArray<Diagnostic> diagnostics)
where TCompilation : Compilation
where TSyntaxKind : struct
{
var driver = new AnalyzerDriver<TSyntaxKind>(analyzers.ToImmutableArray(), getKind, options, default(CancellationToken));
// We want unit tests to throw if any analyzer OR the driver throws, unless the test explicitly provides a delegate.
continueOnAnalyzerException = continueOnAnalyzerException ?? DonotCatchAnalyzerExceptions;
var driver = new AnalyzerDriver<TSyntaxKind>(analyzers.ToImmutableArray(), getKind, options, default(CancellationToken), continueOnAnalyzerException);
c = (TCompilation)c.WithEventQueue(driver.CompilationEventQueue);
var discarded = c.GetDiagnostics();
diagnostics = driver.GetDiagnosticsAsync().Result;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册