public static async Task ExecuteAsync(CompilationWithAnalyzers compilation)
    {
        await compilation.GetAllDiagnosticsAsync();

        using (MemoryStream assemblyStream = new MemoryStream())
            using (MemoryStream pdbStream = new MemoryStream())
            {
                var result = compilation.Compilation.Emit(assemblyStream, pdbStream);

                if (!IsWrittenToDisk || !ShouldBreakAtEnd)
                {
                    return;
                }

                Diagnostic[] diagnostics = result.Diagnostics.OrderByDescending(x => x.Severity).ToArray();

                if (result.Success)
                {
                    Success(diagnostics);
                    return;
                }

                string[] errors = diagnostics.TakeWhile(x => x.Severity == DiagnosticSeverity.Error).Select(x => x.ToString()).ToArray();

                try
                {
                    File.WriteAllLines(ErrorFile, errors);
                }
                finally
                {
                    Failure(diagnostics, errors);
                }
            }
    }
示例#2
0
    private static async Task <ImmutableArray <Diagnostic> > GetProjectAnalyzerDiagnosticsAsync(ImmutableArray <DiagnosticAnalyzer> analyzers, Project project, CancellationToken cancellationToken)
    {
        var supportedDiagnosticsSpecificOptions = new Dictionary <string, ReportDiagnostic>();

        foreach (var analyzer in analyzers)
        {
            foreach (var diagnostic in analyzer.SupportedDiagnostics)
            {
                // make sure the analyzers we are testing are enabled
                supportedDiagnosticsSpecificOptions[diagnostic.Id] = ReportDiagnostic.Default;
            }
        }

        // Report exceptions during the analysis process as errors
        supportedDiagnosticsSpecificOptions.Add("AD0001", ReportDiagnostic.Error);

        // update the project compilation options
        var modifiedSpecificDiagnosticOptions = supportedDiagnosticsSpecificOptions.ToImmutableDictionary().SetItems(project.CompilationOptions.SpecificDiagnosticOptions);
        var modifiedCompilationOptions        = project.CompilationOptions.WithSpecificDiagnosticOptions(modifiedSpecificDiagnosticOptions);
        var processedProject = project.WithCompilationOptions(modifiedCompilationOptions);

        Compilation compilation = await processedProject.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

        CompilationWithAnalyzers compilationWithAnalyzers = compilation.WithAnalyzers(analyzers, cancellationToken: cancellationToken);

        //var diagnostics = await FixAllContextHelper.GetAllDiagnosticsAsync(compilation, compilationWithAnalyzers, analyzers, project.Documents, true, cancellationToken).ConfigureAwait(false);
        var diagnostics = await compilationWithAnalyzers.GetAllDiagnosticsAsync();

        return(diagnostics);
    }
示例#3
0
        /// <summary>
        /// Returns a list of all analyzer diagnostics inside the specific project. This is an asynchronous operation.
        /// </summary>
        /// <param name="analyzers">The list of analyzers that should be used</param>
        /// <param name="project">The project that should be analyzed</param>
        /// <param name="cancellationToken">The cancellation token that the task will observe.</param>
        /// <returns>A list of diagnostics inside the project</returns>
        private static async Task <ImmutableArray <Diagnostic> > GetProjectAnalyzerDiagnosticsAsync(ImmutableArray <DiagnosticAnalyzer> analyzers, Project project, CancellationToken cancellationToken)
        {
            Compilation compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

            CompilationWithAnalyzers compilationWithAnalyzers = compilation.WithAnalyzers(analyzers, cancellationToken: cancellationToken);

            var allDiagnostics = await compilationWithAnalyzers.GetAllDiagnosticsAsync().ConfigureAwait(false);

            // We want analyzer diagnostics and analyzer exceptions
            return(allDiagnostics.RemoveRange(compilation.GetDiagnostics()));
        }
        public static async Task <ImmutableArray <Diagnostic> > GetAllDiagnosticsAsync(Compilation compilation, CompilationWithAnalyzers compilationWithAnalyzers, ImmutableArray <DiagnosticAnalyzer> analyzers, IEnumerable <Document> documents, bool includeCompilerDiagnostics, CancellationToken cancellationToken)
        {
            if (GetAnalyzerSyntaxDiagnosticsAsync == null || GetAnalyzerSemanticDiagnosticsAsync == null)
            {
                // In everything except Roslyn 1.1, we use GetAllDiagnosticsAsync and return the result.
                var allDiagnostics = await compilationWithAnalyzers.GetAllDiagnosticsAsync().ConfigureAwait(false);

                return(allDiagnostics);
            }

            compilationWithAnalyzers.Compilation.GetDeclarationDiagnostics(cancellationToken);

            // Note that the following loop to obtain syntax and semantic diagnostics for each document cannot operate
            // on parallel due to our use of a single CompilationWithAnalyzers instance.
            var diagnostics = ImmutableArray.CreateBuilder <Diagnostic>();

            foreach (var document in documents)
            {
                var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

                var syntaxDiagnostics = await GetAnalyzerSyntaxDiagnosticsAsync(compilationWithAnalyzers, syntaxTree, cancellationToken).ConfigureAwait(false);

                diagnostics.AddRange(syntaxDiagnostics);

                var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                var semanticDiagnostics = await GetAnalyzerSemanticDiagnosticsAsync(compilationWithAnalyzers, semanticModel, default(TextSpan?), cancellationToken).ConfigureAwait(false);

                diagnostics.AddRange(semanticDiagnostics);
            }

            foreach (var analyzer in analyzers)
            {
                diagnostics.AddRange(await GetAnalyzerCompilationDiagnosticsAsync(compilationWithAnalyzers, ImmutableArray.Create(analyzer), cancellationToken).ConfigureAwait(false));
            }

            if (includeCompilerDiagnostics)
            {
                // This is the special handling for cases where code fixes operate on warnings produced by the C#
                // compiler, as opposed to being created by specific analyzers.
                var compilerDiagnostics = compilation.GetDiagnostics(cancellationToken);
                diagnostics.AddRange(compilerDiagnostics);
            }

            return(diagnostics.ToImmutable());
        }
示例#5
0
 public Task <ImmutableArray <Diagnostic> > GetDiagnosticsWithAnalyzers()
 => _compWithAnalyzers.GetAllDiagnosticsAsync();
示例#6
0
 public static async Task <ImmutableArray <Diagnostic> > GetAllDiagnosticsAsync(Compilation compilation, CompilationWithAnalyzers compilationWithAnalyzers, ImmutableArray <DiagnosticAnalyzer> analyzers, IEnumerable <Document> documents, bool includeCompilerDiagnostics, CancellationToken cancellationToken)
 {
     return(await compilationWithAnalyzers.GetAllDiagnosticsAsync().ConfigureAwait(false));
 }
示例#7
0
        //---------------------------------------------------------------------
        protected async Task <Diagnostic[]> GetDiagnosticsAsync(
            Document[] documents,
            DiagnosticAnalyzer analyzer,
            string[] additionalEnabledDiagnostics = null)
        {
            var projects = new HashSet <Project>();

            foreach (Document document in documents)
            {
                projects.Add(document.Project);
            }

            var diagnostics = new List <Diagnostic>();

            foreach (Project project in projects)
            {
                Compilation compilation = await project.GetCompilationAsync();

                // Enable any additional diagnostics
                CompilationOptions options = compilation.Options;

                if (additionalEnabledDiagnostics?.Length > 0)
                {
                    options = compilation.Options
                              .WithSpecificDiagnosticOptions(additionalEnabledDiagnostics.ToDictionary(s => s, _ => ReportDiagnostic.Info));
                }

                CompilationWithAnalyzers compilationWithAnalyzers = compilation
                                                                    .WithOptions(options)
                                                                    .WithAnalyzers(ImmutableArray.Create(analyzer));

                ImmutableArray <Diagnostic> diags = await compilationWithAnalyzers.GetAllDiagnosticsAsync();

                foreach (Diagnostic diag in diags)
                {
                    TestContext.WriteLine("Diagnostics: " + diag);
                }

                Assume.That(diags.Any(d => d.Id == "AD0001"), Is.False, "diagnostics with AD0001 present");

                // Filter out non-error diagnostics not produced by our analyzer
                // We want to KEEP errors because we might have written bad code. But sometimes we leave warnings in to make the
                // test code more convenient
                diags = diags.Where(d =>
                                    d.Severity == DiagnosticSeverity.Error ||
                                    analyzer.SupportedDiagnostics.Any(s => s.Id.Equals(d.Id)))
                        .ToImmutableArray();

                foreach (Diagnostic diag in diags)
                {
                    if (diag.Location == Location.None || diag.Location.IsInMetadata)
                    {
                        diagnostics.Add(diag);
                    }
                    else
                    {
                        foreach (Document document in documents)
                        {
                            SyntaxTree tree = await document.GetSyntaxTreeAsync();

                            if (tree == diag.Location.SourceTree)
                            {
                                diagnostics.Add(diag);
                            }
                        }
                    }
                }
            }

            return(diagnostics.OrderBy(d => d.Location.SourceSpan.Start).ToArray());
        }