public static ImmutableArray <Diagnostic> GetAnalyzerDiagnostics <TCompilation>( this TCompilation c, DiagnosticAnalyzer[] analyzers, TestValidationMode validationMode, AnalyzerOptions options = null) where TCompilation : Compilation { var compilationWithAnalyzers = c.WithAnalyzers(analyzers.ToImmutableArray(), options, CancellationToken.None); var diagnostics = c.GetDiagnostics(); if (validationMode != TestValidationMode.AllowCompileErrors) { CompilationUtils.ValidateNoCompileErrors(diagnostics); } var diagnosticDescriptors = analyzers.SelectMany(analyzer => analyzer.SupportedDiagnostics); var analyzerDiagnosticIds = diagnosticDescriptors.Select(diagnosticDescriptor => diagnosticDescriptor.Id); var allDiagnosticIds = new HashSet <string>(analyzerDiagnosticIds, StringComparer.Ordinal) { "AD0001" // Failures caught by the Analyzer Driver. }; var allDiagnostics = compilationWithAnalyzers.GetAllDiagnosticsAsync().Result; var resultDiagnostics = allDiagnostics.Where(diagnostic => allDiagnosticIds.Contains(diagnostic.Id)); return(resultDiagnostics.ToImmutableArray()); }
private void VerifyFix( string language, DiagnosticAnalyzer analyzerOpt, CodeFixProvider codeFixProvider, string[] oldSources, string[] newSources, int?codeFixIndex, bool allowNewCompilerDiagnostics, bool onlyFixFirstFixableDiagnostic, bool allowUnsafeCode, TestValidationMode validationMode, ReferenceFlags referenceFlags = ReferenceFlags.None) { var runner = new CodeFixRunner(analyzerOpt, codeFixProvider, validationMode); Assert.True(oldSources.Length == newSources.Length, "Length of expected and actual sources arrays must match."); Document[] documents = CreateDocuments(oldSources, language, referenceFlags, allowUnsafeCode: allowUnsafeCode); var project = documents.First().Project; Solution newSolution; if (onlyFixFirstFixableDiagnostic) { newSolution = runner.ApplySingleFix(project, ImmutableArray <TestAdditionalDocument> .Empty, codeFixIndex ?? 0); } else { newSolution = runner.ApplyFixesOneByOne(project.Solution, ImmutableArray <TestAdditionalDocument> .Empty, allowNewCompilerDiagnostics, codeFixIndex ?? 0); } VerifyDocuments(newSolution, documents, newSources); }
private IEnumerable <Diagnostic> EnumerateDiagnosticsForDocument([NotNull] Document document, TestValidationMode validationMode, DiagnosticsCaptureMode diagnosticsCaptureMode, [NotNull] AnalyzerOptions options) { CompilationWithAnalyzers compilationWithAnalyzers = GetCompilationWithAnalyzers(document, validationMode, options); SyntaxTree tree = document.GetSyntaxTreeAsync().Result; return(EnumerateAnalyzerDiagnostics(compilationWithAnalyzers, tree, diagnosticsCaptureMode)); }
public FixAllDiagnosticProvider( DiagnosticAnalyzer analyzerOpt, IEnumerable <TestAdditionalDocument> additionalFiles, TestValidationMode testValidationMode, Func <IEnumerable <Diagnostic>, ImmutableArray <Diagnostic> > getFixableDiagnostics) { _analyzerOpt = analyzerOpt; _additionalFiles = additionalFiles; _testValidationMode = testValidationMode; _getFixableDiagnostics = getFixableDiagnostics; }
public CodeFixRunner( DiagnosticAnalyzer analyzerOpt, CodeFixProvider codeFixProvider, TestValidationMode validationMode) { _analyzerOpt = analyzerOpt; _codeFixProvider = codeFixProvider; _validationMode = validationMode; _fixableDiagnosticIds = _codeFixProvider.FixableDiagnosticIds.ToSet(); _getFixableDiagnostics = diags => diags.Where(d => _fixableDiagnosticIds.Contains(d.Id)).ToImmutableArrayOrEmpty(); }
private void VerifyFixAll( Document document, DiagnosticAnalyzer analyzerOpt, CodeFixProvider codeFixProvider, string newSource, string newSourceFileName, IEnumerable <TestAdditionalDocument> additionalFiles, bool allowNewCompilerDiagnostics, TestValidationMode validationMode) { var fixableDiagnosticIds = codeFixProvider.FixableDiagnosticIds.ToSet(); Func <IEnumerable <Diagnostic>, ImmutableArray <Diagnostic> > getFixableDiagnostics = diags => diags.Where(d => fixableDiagnosticIds.Contains(d.Id)).ToImmutableArrayOrEmpty(); var analyzerDiagnostics = GetSortedDiagnostics(analyzerOpt, new[] { document }, additionalFiles: additionalFiles, validationMode: validationMode); var compilerDiagnostics = document.GetSemanticModelAsync().Result.GetDiagnostics(); var fixableDiagnostics = getFixableDiagnostics(analyzerDiagnostics.Concat(compilerDiagnostics)); var fixAllProvider = codeFixProvider.GetFixAllProvider(); var diagnosticProvider = new FixAllDiagnosticProvider(analyzerOpt, additionalFiles, validationMode, getFixableDiagnostics); var fixAllContext = new FixAllContext(document, codeFixProvider, FixAllScope.Document, string.Empty, fixableDiagnostics.Select(d => d.Id), diagnosticProvider, CancellationToken.None); var codeAction = fixAllProvider.GetFixAsync(fixAllContext).Result; document = document.Apply(codeAction); additionalFiles = document.Project.AdditionalDocuments.Select(a => new TestAdditionalDocument(a)); additionalFiles = document.Project.AdditionalDocuments.Select(a => new TestAdditionalDocument(a)); analyzerDiagnostics = GetSortedDiagnostics(analyzerOpt, new[] { document }, additionalFiles: additionalFiles, validationMode: validationMode); var updatedCompilerDiagnostics = document.GetSemanticModelAsync().Result.GetDiagnostics(); var newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, updatedCompilerDiagnostics); if (!allowNewCompilerDiagnostics && newCompilerDiagnostics.Any()) { // Format and get the compiler diagnostics again so that the locations make sense in the output document = document.WithSyntaxRoot(Formatter.Format(document.GetSyntaxRootAsync().Result, Formatter.Annotation, document.Project.Solution.Workspace)); newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, document.GetSemanticModelAsync().Result.GetDiagnostics()); Assert.True(false, string.Format("Fix introduced new compiler diagnostics:\r\n{0}\r\n\r\nNew document:\r\n{1}\r\n", newCompilerDiagnostics.Select(d => d.ToString()).Join("\r\n"), document.GetSyntaxRootAsync().Result.ToFullString())); } var actualText = GetActualTextForNewDocument(document, newSourceFileName); Assert.Equal(newSource, actualText.ToString()); }
private CompilationWithAnalyzers GetCompilationWithAnalyzers([NotNull] Document document, TestValidationMode validationMode, [NotNull] AnalyzerOptions options) { ImmutableArray <DiagnosticAnalyzer> analyzers = ImmutableArray.Create(CreateAnalyzer()); Compilation compilation = document.Project.GetCompilationAsync().Result; ImmutableArray <Diagnostic> compilerDiagnostics = compilation.GetDiagnostics(CancellationToken.None); if (validationMode != TestValidationMode.AllowCompileErrors) { ValidateCompileErrors(compilerDiagnostics); } return(compilation.WithAnalyzers(analyzers, options)); }
#pragma warning disable AV1561 // Method or constructor contains more than three parameters #pragma warning disable AV1500 // Member contains more than seven statements private AnalyzerTestContext([NotNull] string markupCode, [NotNull] string languageName, [NotNull] string fileName, [NotNull] string assemblyName, [NotNull][ItemNotNull] ImmutableHashSet <MetadataReference> references, DocumentationMode documentationMode, [CanBeNull] int?compilerWarningLevel, TestValidationMode validationMode, DiagnosticsCaptureMode diagnosticsCaptureMode) { MarkupCode = markupCode; LanguageName = languageName; FileName = fileName; AssemblyName = assemblyName; References = references; DocumentationMode = documentationMode; CompilerWarningLevel = compilerWarningLevel; ValidationMode = validationMode; DiagnosticsCaptureMode = diagnosticsCaptureMode; }
private void VerifyFixAll( string language, DiagnosticAnalyzer analyzerOpt, CodeFixProvider codeFixProvider, string[] oldSources, string[] newSources, FixAllScope fixAllScope, int?codeFixIndex, bool allowNewCompilerDiagnostics, bool allowUnsafeCode, TestValidationMode validationMode) { var runner = new CodeFixRunner(analyzerOpt, codeFixProvider, validationMode); Assert.True(oldSources.Length == newSources.Length, "Length of expected and actual sources arrays must match."); Document[] documents = CreateDocuments(oldSources, language, allowUnsafeCode: allowUnsafeCode); VerifyFixAll(runner, documents, newSources, fixAllScope, codeFixIndex, allowNewCompilerDiagnostics); }
private void VerifyFixAll( string language, DiagnosticAnalyzer analyzerOpt, CodeFixProvider codeFixProvider, string[] oldSources, string[] newSources, bool allowNewCompilerDiagnostics, bool allowUnsafeCode, TestValidationMode validationMode) { var runner = new CodeFixRunner(analyzerOpt, codeFixProvider, validationMode); Assert.True(oldSources.Length == newSources.Length, "Length of expected and actual sources arrays must match."); Document[] documents = CreateDocuments(oldSources, language, allowUnsafeCode: allowUnsafeCode); var solution = documents.First().Project.Solution; solution = runner.ApplyFixAll(solution, ImmutableArray <TestAdditionalDocument> .Empty, allowNewCompilerDiagnostics); VerifyDocuments(solution, documents, newSources); }
protected void VerifyAdditionalFileFix( string language, DiagnosticAnalyzer analyzerOpt, CodeFixProvider codeFixProvider, string source, IEnumerable <TestAdditionalDocument> additionalFiles, TestAdditionalDocument newAdditionalFileToVerify, int?codeFixIndex = null, bool allowNewCompilerDiagnostics = false, bool onlyFixFirstFixableDiagnostic = false, TestValidationMode validationMode = DefaultTestValidationMode) { Document document = CreateDocument(source, language); if (additionalFiles != null) { var project = document.Project; foreach (var additionalFile in additionalFiles) { project = project.AddAdditionalDocument(additionalFile.Name, additionalFile.GetText(), filePath: additionalFile.Path).Project; } document = project.GetDocument(document.Id); } var additionalFileName = newAdditionalFileToVerify.Name; var additionalFileText = newAdditionalFileToVerify.GetText().ToString(); Solution newSolution; var runner = new CodeFixRunner(analyzerOpt, codeFixProvider, DefaultTestValidationMode); if (onlyFixFirstFixableDiagnostic || codeFixIndex.HasValue) { newSolution = runner.ApplySingleFix(document.Project, additionalFiles, codeFixIndex.HasValue ? codeFixIndex.Value : 0, fixableDiagnosticIndex: 0); } else { newSolution = runner.ApplyFixesOneByOne(document.Project.Solution, additionalFiles, allowNewCompilerDiagnostics); } Assert.Equal(additionalFileText, GetActualTextForNewDocument(newSolution.GetDocument(document.Id), newAdditionalFileToVerify.Name).ToString()); }
public static ImmutableArray <Diagnostic> GetAnalyzerDiagnostics <TCompilation>( this TCompilation c, DiagnosticAnalyzer[] analyzers, TestValidationMode validationMode, AnalyzerOptions options = null, Action <Exception, DiagnosticAnalyzer, Diagnostic> onAnalyzerException = null, bool logAnalyzerExceptionAsDiagnostics = true) where TCompilation : Compilation { ImmutableArray <DiagnosticAnalyzer> analyzersArray = analyzers.ToImmutableArray(); var exceptionDiagnostics = new ConcurrentSet <Diagnostic>(); if (onAnalyzerException == null) { if (logAnalyzerExceptionAsDiagnostics) { onAnalyzerException = (ex, analyzer, diagnostic) => { exceptionDiagnostics.Add(diagnostic); }; } else { // We want unit tests to throw if any analyzer OR the driver throws, unless the test explicitly provides a delegate. onAnalyzerException = FailFastOnAnalyzerException; } } Compilation newCompilation; AnalyzerDriver driver = AnalyzerDriver.CreateAndAttachToCompilation(c, analyzersArray, options, AnalyzerManager.Instance, onAnalyzerException, null, false, out newCompilation, CancellationToken.None); ImmutableArray <Diagnostic> diagnostics = newCompilation.GetDiagnostics(); if (validationMode != TestValidationMode.AllowCompileErrors) { ValidateNoCompileErrors(diagnostics); } return(driver.GetDiagnosticsAsync(newCompilation).Result.AddRange(exceptionDiagnostics)); }
private void TestCSharpCore(string source, bool withCustomCodeActions = false, TestValidationMode validationMode = DefaultTestValidationMode, params DiagnosticResult[] expected) { var fixAllProviderString = @"public override FixAllProvider GetFixAllProvider() { return WellKnownFixAllProviders.BatchFixer; }"; var sourceSuffix = @" }"; if (withCustomCodeActions) { sourceSuffix = sourceSuffix + CSharpCustomCodeActions; } // Verify expected diagnostics for fixer that supports FixAllProvider. VerifyCSharp(source + fixAllProviderString + sourceSuffix, validationMode, expected); // Verify no diagnostics for fixer that does not support FixAllProvider. VerifyCSharp(source + sourceSuffix, validationMode); }
public static ImmutableArray <Diagnostic> GetAnalyzerDiagnostics <TCompilation>( this TCompilation c, DiagnosticAnalyzer[] analyzers, TestValidationMode validationMode, AnalyzerOptions options = null) where TCompilation : Compilation { var compilationWithAnalyzers = c.WithAnalyzers(analyzers.ToImmutableArray(), options, CancellationToken.None); var diagnostics = c.GetDiagnostics(); if (validationMode != TestValidationMode.AllowCompileErrors) { CompilationUtils.ValidateNoCompileErrors(diagnostics); } var analyzerDiagnostics = compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync().Result; var allDiagnostics = compilationWithAnalyzers.GetAllDiagnosticsAsync().Result; var failureDiagnostics = allDiagnostics.Where(diagnostic => diagnostic.Id == "AD0001"); var resultDiagnostics = analyzerDiagnostics.Concat(failureDiagnostics); return(resultDiagnostics.ToImmutableArray()); }
protected static Diagnostic[] GetSortedDiagnostics(FileAndSource[] sources, string language, DiagnosticAnalyzer analyzer, TestValidationMode validationMode = DefaultTestValidationMode, bool addLanguageSpecificCodeAnalysisReference = true, bool allowUnsafeCode = false, string projectName = TestProjectName, IEnumerable <TestAdditionalDocument> additionalFiles = null) { Tuple <Document[], bool, TextSpan?[]> documentsAndUseSpan = GetDocumentsAndSpans(sources, language, addLanguageSpecificCodeAnalysisReference, projectName, allowUnsafeCode); Document[] documents = documentsAndUseSpan.Item1; bool useSpans = documentsAndUseSpan.Item2; TextSpan?[] spans = documentsAndUseSpan.Item3; return(GetSortedDiagnostics(analyzer, documents, useSpans ? spans : null, validationMode, additionalFiles)); }
private void Verify(string source, string language, DiagnosticAnalyzer analyzer, bool addLanguageSpecificCodeAnalysisReference, TestValidationMode validationMode, params DiagnosticResult[] expected) { var diagnostics = GetSortedDiagnostics(new[] { source }.ToFileAndSource(), language, analyzer, addLanguageSpecificCodeAnalysisReference: addLanguageSpecificCodeAnalysisReference, validationMode: validationMode); diagnostics.Verify(analyzer, PrintActualDiagnosticsOnFailure, ExpectedDiagnosticsAssertionTemplate, expected); }
private void Verify(FileAndSource[] sources, string language, DiagnosticAnalyzer analyzer, TestValidationMode validationMode, bool allowUnsafeCode, params DiagnosticResult[] expected) { var diagnostics = GetSortedDiagnostics(sources, language, analyzer, validationMode, allowUnsafeCode: allowUnsafeCode); diagnostics.Verify(analyzer, PrintActualDiagnosticsOnFailure, ExpectedDiagnosticsAssertionTemplate, expected); }
protected void VerifyBasic(string source, bool addLanguageSpecificCodeAnalysisReference, TestValidationMode validationMode = DefaultTestValidationMode, params DiagnosticResult[] expected) { Verify(source, LanguageNames.VisualBasic, GetBasicDiagnosticAnalyzer(), addLanguageSpecificCodeAnalysisReference, validationMode, expected); }
protected void VerifyCSharpFix(string oldSource, string newSource, int?codeFixIndex = null, bool allowNewCompilerDiagnostics = false, bool onlyFixFirstFixableDiagnostic = false, TestValidationMode validationMode = DefaultTestValidationMode) { VerifyFix(LanguageNames.CSharp, GetCSharpDiagnosticAnalyzer(), GetCSharpCodeFixProvider(), new[] { oldSource }, new[] { newSource }, codeFixIndex, allowNewCompilerDiagnostics, onlyFixFirstFixableDiagnostic, allowUnsafeCode: false, validationMode: validationMode); }
protected void VerifyBasicFixAll(string oldSource, string newSource, bool allowNewCompilerDiagnostics = false, TestValidationMode validationMode = DefaultTestValidationMode) { VerifyFixAll(LanguageNames.VisualBasic, GetBasicDiagnosticAnalyzer(), GetBasicCodeFixProvider(), new[] { oldSource }, new[] { newSource }, allowNewCompilerDiagnostics, allowUnsafeCode: false, validationMode: validationMode); }
protected void VerifyBasicFix(string oldSource, string newSource, int?codeFixIndex = null, bool allowNewCompilerDiagnostics = false, bool onlyFixFirstFixableDiagnostic = false, FixAllScope?testFixAllScope = FixAllScope.Document, TestValidationMode validationMode = DefaultTestValidationMode) { VerifyFix(LanguageNames.VisualBasic, GetBasicDiagnosticAnalyzer(), GetBasicCodeFixProvider(), new[] { oldSource }, new[] { newSource }, codeFixIndex, allowNewCompilerDiagnostics, onlyFixFirstFixableDiagnostic, testFixAllScope, allowUnsafeCode: false, validationMode: validationMode); }
protected void VerifyCSharpFix(string[] oldSources, string[] newSources, int?codeFixIndex = null, bool allowNewCompilerDiagnostics = false, bool onlyFixFirstFixableDiagnostic = false, FixAllScope?testFixAllScope = FixAllScope.Project, TestValidationMode validationMode = DefaultTestValidationMode) { VerifyFix(LanguageNames.CSharp, GetCSharpDiagnosticAnalyzer(), GetCSharpCodeFixProvider(), oldSources, newSources, codeFixIndex, allowNewCompilerDiagnostics, onlyFixFirstFixableDiagnostic, testFixAllScope, allowUnsafeCode: false, validationMode: validationMode); }
private void TestBasicCore(string source, bool withCustomCodeActions = false, TestValidationMode validationMode = DefaultTestValidationMode, params DiagnosticResult[] expected) { var fixAllProviderString = @"Public Overrides Function GetFixAllProvider() As FixAllProvider Return WellKnownFixAllProviders.BatchFixer End Function "; var sourceSuffix = @" End Class "; if (withCustomCodeActions) { sourceSuffix = sourceSuffix + VisualBasicCustomCodeActions; } // Verify expected diagnostics for fixer that supports FixAllProvider. VerifyBasic(source + fixAllProviderString + sourceSuffix, validationMode, expected); // Verify no diagnostics for fixer that does not support FixAllProvider. VerifyBasic(source + sourceSuffix, validationMode); }
protected void VerifyCSharpFix(string[] oldSources, string[] newSources, int?codeFixIndex = null, bool allowNewCompilerDiagnostics = false, bool onlyFixFirstFixableDiagnostic = false, TestValidationMode validationMode = DefaultTestValidationMode, ReferenceFlags referenceFlags = ReferenceFlags.None) { VerifyFix(LanguageNames.CSharp, GetCSharpDiagnosticAnalyzer(), GetCSharpCodeFixProvider(), oldSources, newSources, codeFixIndex, allowNewCompilerDiagnostics, onlyFixFirstFixableDiagnostic, allowUnsafeCode: false, validationMode: validationMode, referenceFlags: referenceFlags); }
protected static Diagnostic[] GetSortedDiagnostics(DiagnosticAnalyzer analyzerOpt, Document[] documents, TextSpan?[] spans = null, TestValidationMode validationMode = DefaultTestValidationMode, IEnumerable <TestAdditionalDocument> additionalFiles = null) { if (analyzerOpt == null) { return(Array.Empty <Diagnostic>()); } var projects = new HashSet <Project>(); foreach (Document document in documents) { projects.Add(document.Project); } var analyzerOptions = additionalFiles != null ? new AnalyzerOptions(additionalFiles.ToImmutableArray <AdditionalText>()) : null; DiagnosticBag diagnostics = DiagnosticBag.GetInstance(); foreach (Project project in projects) { Compilation compilation = project.GetCompilationAsync().Result; compilation = EnableAnalyzer(analyzerOpt, compilation); ImmutableArray <Diagnostic> diags = compilation.GetAnalyzerDiagnostics(new[] { analyzerOpt }, validationMode, analyzerOptions); if (spans == null) { diagnostics.AddRange(diags); } else { Debug.Assert(spans.Length == documents.Length); foreach (Diagnostic diag in diags) { if (diag.Location == Location.None || diag.Location.IsInMetadata) { diagnostics.Add(diag); } else { for (int i = 0; i < documents.Length; i++) { Document document = documents[i]; SyntaxTree tree = document.GetSyntaxTreeAsync().Result; if (tree == diag.Location.SourceTree) { TextSpan?span = spans[i]; if (span == null || span.Value.Contains(diag.Location.SourceSpan)) { diagnostics.Add(diag); } } } } } } } Diagnostic[] results = diagnostics.AsEnumerable().OrderBy(d => d.Location.SourceSpan.Start).ToArray(); diagnostics.Free(); return(results); }
protected void VerifyCSharp(string source, bool addLanguageSpecificCodeAnalysisReference, TestValidationMode validationMode = DefaultTestValidationMode, params DiagnosticResult[] expected) { Verify(source, LanguageNames.CSharp, GetCSharpDiagnosticAnalyzer(), addLanguageSpecificCodeAnalysisReference, validationMode, compilationOptions: null, expected: expected); }
protected void VerifyCSharp(string source, TestValidationMode validationMode, CompilationOptions compilationOptions, params DiagnosticResult[] expected) { Verify(new[] { source }.ToFileAndSource(), LanguageNames.CSharp, GetCSharpDiagnosticAnalyzer(), validationMode, false, compilationOptions, expected: expected); }
public AnalyzerTestContext InValidationMode(TestValidationMode validationMode) { return(new AnalyzerTestContext(MarkupCode, LanguageName, FileName, AssemblyName, References, DocumentationMode, CompilerWarningLevel, validationMode, DiagnosticsCaptureMode)); }
protected void VerifyBasicFix(string[] oldSources, string[] newSources, int?codeFixIndex = null, bool allowNewCompilerDiagnostics = false, bool onlyFixFirstFixableDiagnostic = false, TestValidationMode validationMode = DefaultTestValidationMode) { VerifyFix(LanguageNames.VisualBasic, GetBasicDiagnosticAnalyzer(), GetBasicCodeFixProvider(), oldSources, newSources, codeFixIndex, allowNewCompilerDiagnostics, onlyFixFirstFixableDiagnostic, allowUnsafeCode: false, validationMode: validationMode); }
protected void VerifyBasic(string source, TestValidationMode validationMode, params DiagnosticResult[] expected) { Verify(new[] { source }.ToFileAndSource(), LanguageNames.VisualBasic, GetBasicDiagnosticAnalyzer(), validationMode, false, expected); }
protected static Diagnostic[] GetSortedDiagnostics(FileAndSource[] sources, string language, DiagnosticAnalyzer analyzer, TestValidationMode validationMode = DefaultTestValidationMode, bool addLanguageSpecificCodeAnalysisReference = true, bool allowUnsafeCode = false, string projectName = TestProjectName, IEnumerable<TestAdditionalDocument> additionalFiles = null) { Tuple<Document[], bool, TextSpan?[]> documentsAndUseSpan = GetDocumentsAndSpans(sources, language, addLanguageSpecificCodeAnalysisReference, projectName, allowUnsafeCode); Document[] documents = documentsAndUseSpan.Item1; bool useSpans = documentsAndUseSpan.Item2; TextSpan?[] spans = documentsAndUseSpan.Item3; return GetSortedDiagnostics(analyzer, documents, useSpans ? spans : null, validationMode, additionalFiles); }
protected static Diagnostic[] GetSortedDiagnostics(DiagnosticAnalyzer analyzerOpt, Document[] documents, TextSpan?[] spans = null, TestValidationMode validationMode = DefaultTestValidationMode, IEnumerable<TestAdditionalDocument> additionalFiles = null) { if (analyzerOpt == null) { return SpecializedCollections.EmptyArray<Diagnostic>(); } var projects = new HashSet<Project>(); foreach (Document document in documents) { projects.Add(document.Project); } var analyzerOptions = additionalFiles != null ? new AnalyzerOptions(additionalFiles.ToImmutableArray<AdditionalText>()) : null; DiagnosticBag diagnostics = DiagnosticBag.GetInstance(); foreach (Project project in projects) { Compilation compilation = project.GetCompilationAsync().Result; compilation = EnableAnalyzer(analyzerOpt, compilation); ImmutableArray <Diagnostic> diags = compilation.GetAnalyzerDiagnostics(new[] { analyzerOpt }, validationMode, analyzerOptions); if (spans == null) { diagnostics.AddRange(diags); } else { Debug.Assert(spans.Length == documents.Length); foreach (Diagnostic diag in diags) { if (diag.Location == Location.None || diag.Location.IsInMetadata) { diagnostics.Add(diag); } else { for (int i = 0; i < documents.Length; i++) { Document document = documents[i]; SyntaxTree tree = document.GetSyntaxTreeAsync().Result; if (tree == diag.Location.SourceTree) { TextSpan? span = spans[i]; if (span == null || span.Value.Contains(diag.Location.SourceSpan)) { diagnostics.Add(diag); } } } } } } } Diagnostic[] results = diagnostics.AsEnumerable().OrderBy(d => d.Location.SourceSpan.Start).ToArray(); diagnostics.Free(); return results; }