Example #1
0
            static bool isEnabledWithAnalyzerConfigOptions(
                DiagnosticDescriptor descriptor,
                SeverityFilter severityFilter,
                Compilation? compilation,
                AnalyzerOptions? analyzerOptions,
                CancellationToken cancellationToken)
            {
                if (compilation != null && compilation.Options.SyntaxTreeOptionsProvider is { } treeOptions)
                {
                    foreach (var tree in compilation.SyntaxTrees)
                    {
                        // Check if diagnostic is enabled by SyntaxTree.DiagnosticOptions or Bulk configuration from AnalyzerConfigOptions.
                        if (treeOptions.TryGetDiagnosticValue(tree, descriptor.Id, cancellationToken, out var configuredValue) ||
                            analyzerOptions.TryGetSeverityFromBulkConfiguration(tree, compilation, descriptor, cancellationToken, out configuredValue))
                        {
                            if (configuredValue != ReportDiagnostic.Suppress && !severityFilter.Contains(configuredValue))
                            {
                                return true;
                            }
                        }
                    }
                }

                return false;
            }
Example #2
0
        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());
        }
 /// <summary>
 /// Returns a new compilation with attached diagnostic analyzers.
 /// </summary>
 /// <param name="compilation">Compilation to which analyzers are to be added.</param>
 /// <param name="analyzers">The set of analyzers to include in future analyses.</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 static CompilationWithAnalyzers WithAnalyzers(
     this Compilation compilation,
     ImmutableArray <DiagnosticAnalyzer> analyzers,
     AnalyzerOptions?options             = null,
     CancellationToken cancellationToken = default
     )
 {
     return(new CompilationWithAnalyzers(compilation, analyzers, options, cancellationToken));
 }
        /// <summary>
        /// Tries to get configured severity for the given <paramref name="descriptor"/>
        /// for the given <paramref name="tree"/> from bulk configuration analyzer config options, i.e.
        ///     'dotnet_analyzer_diagnostic.category-%RuleCategory%.severity = %severity%'
        ///         or
        ///     'dotnet_analyzer_diagnostic.severity = %severity%'
        /// </summary>
        public static bool TryGetSeverityFromBulkConfiguration(
            this AnalyzerOptions?analyzerOptions,
            SyntaxTree tree,
            Compilation compilation,
            DiagnosticDescriptor descriptor,
            out ReportDiagnostic severity)
        {
            // Analyzer bulk configuration does not apply to:
            //  1. Disabled by default diagnostics
            //  2. Compiler diagnostics
            //  3. Non-configurable diagnostics
            if (analyzerOptions == null ||
                !descriptor.IsEnabledByDefault ||
                descriptor.CustomTags.Any(tag => tag == WellKnownDiagnosticTags.Compiler || tag == WellKnownDiagnosticTags.NotConfigurable))
            {
                severity = default;
                return(false);
            }

            // If user has explicitly configured severity for this diagnostic ID, that should be respected.
            if (compilation.Options.SpecificDiagnosticOptions.TryGetValue(descriptor.Id, out severity))
            {
                return(true);
            }

            // If user has explicitly configured severity for this diagnostic ID, that should be respected.
            // For example, 'dotnet_diagnostic.CA1000.severity = error'
            if (tree.DiagnosticOptions.TryGetValue(descriptor.Id, out severity))
            {
                return(true);
            }

            var analyzerConfigOptions = analyzerOptions.AnalyzerConfigOptionsProvider.GetOptions(tree);

            // If user has explicitly configured default severity for the diagnostic category, that should be respected.
            // For example, 'dotnet_analyzer_diagnostic.category-security.severity = error'
            var categoryBasedKey = GetCategoryBasedDotnetAnalyzerDiagnosticSeverityKey(descriptor.Category);

            if (analyzerConfigOptions.TryGetValue(categoryBasedKey, out var value) &&
                TryParseSeverity(value, out severity))
            {
                return(true);
            }

            // Otherwise, if user has explicitly configured default severity for all analyzer diagnostics, that should be respected.
            // For example, 'dotnet_analyzer_diagnostic.severity = error'
            if (analyzerConfigOptions.TryGetValue(DotnetAnalyzerDiagnosticSeverityKey, out value) &&
                TryParseSeverity(value, out severity))
            {
                return(true);
            }

            severity = default;
            return(false);
        }
Example #5
0
        /// <summary>
        /// Tries to get configured severity for the given <paramref name="descriptor"/>
        /// for the given <paramref name="tree"/> from bulk configuration analyzer config options, i.e.
        ///     'dotnet_analyzer_diagnostic.category-%RuleCategory%.severity = %severity%'
        ///         or
        ///     'dotnet_analyzer_diagnostic.severity = %severity%'
        /// </summary>
        public static bool TryGetSeverityFromBulkConfiguration(
            this AnalyzerOptions?analyzerOptions,
            SyntaxTree tree,
            Compilation compilation,
            DiagnosticDescriptor descriptor,
            CancellationToken cancellationToken,
            out ReportDiagnostic severity)
        {
            // Analyzer bulk configuration does not apply to:
            //  1. Disabled by default diagnostics
            //  2. Compiler diagnostics
            //  3. Non-configurable diagnostics
            if (analyzerOptions == null ||
                !descriptor.IsEnabledByDefault ||
                descriptor.IsCompilerOrNotConfigurable())
            {
                severity = default;
                return(false);
            }

            // If user has explicitly configured severity for this diagnostic ID, that should be respected and
            // bulk configuration should not be applied.
            // For example, 'dotnet_diagnostic.CA1000.severity = error'
            if (compilation.Options.SpecificDiagnosticOptions.ContainsKey(descriptor.Id) ||
                compilation.Options.SyntaxTreeOptionsProvider?.TryGetDiagnosticValue(tree, descriptor.Id, cancellationToken, out _) == true ||
                compilation.Options.SyntaxTreeOptionsProvider?.TryGetGlobalDiagnosticValue(descriptor.Id, cancellationToken, out _) == true)
            {
                severity = default;
                return(false);
            }

            var analyzerConfigOptions = analyzerOptions.AnalyzerConfigOptionsProvider.GetOptions(tree);

            // If user has explicitly configured default severity for the diagnostic category, that should be respected.
            // For example, 'dotnet_analyzer_diagnostic.category-security.severity = error'
            var categoryBasedKey = GetCategoryBasedDotnetAnalyzerDiagnosticSeverityKey(descriptor.Category);

            if (analyzerConfigOptions.TryGetValue(categoryBasedKey, out var value) &&
                AnalyzerConfigSet.TryParseSeverity(value, out severity))
            {
                return(true);
            }

            // Otherwise, if user has explicitly configured default severity for all analyzer diagnostics, that should be respected.
            // For example, 'dotnet_analyzer_diagnostic.severity = error'
            if (analyzerConfigOptions.TryGetValue(DotnetAnalyzerDiagnosticSeverityKey, out value) &&
                AnalyzerConfigSet.TryParseSeverity(value, out severity))
            {
                return(true);
            }

            severity = default;
            return(false);
        }
 public CompilationWithAnalyzersOptions(
     AnalyzerOptions?options,
     Action <Exception, DiagnosticAnalyzer, Diagnostic>?onAnalyzerException,
     bool concurrentAnalysis,
     bool logAnalyzerExecutionTime,
     bool reportSuppressedDiagnostics,
     Func <Exception, bool>?analyzerExceptionFilter)
 {
     _options                     = options;
     _onAnalyzerException         = onAnalyzerException;
     _analyzerExceptionFilter     = analyzerExceptionFilter;
     _concurrentAnalysis          = concurrentAnalysis;
     _logAnalyzerExecutionTime    = logAnalyzerExecutionTime;
     _reportSuppressedDiagnostics = reportSuppressedDiagnostics;
 }
Example #7
0
        public async Task <ImmutableArray <Diagnostic> > GetDiagnosticsAsync(CancellationToken cancellationToken)
        {
            var compilation = await Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

            var solution = Project.Solution;

            if (_lastWorkspaceAnalyzerOptionsSolution != solution)
            {
                _workspaceAnalyzerOptions             = RoslynReflection.NewWorkspaceAnalyzerOptions(EmptyAnalyzerOptions, EmptyOptionSet, solution);
                _lastWorkspaceAnalyzerOptionsSolution = solution;
            }

            return(await compilation.WithAnalyzers(Analyzers, _workspaceAnalyzerOptions, cancellationToken)
                   .GetAllDiagnosticsAsync(cancellationToken)
                   .ConfigureAwait(false));
        }
Example #8
0
        private static DiagnosticSeverity GetSeverity(
            this DiagnosticAnalyzer analyzer,
            Document document,
            AnalyzerOptions?analyzerOptions,
            OptionSet options,
            Compilation compilation)
        {
            var severity = DiagnosticSeverity.Hidden;

            if (!document.TryGetSyntaxTree(out var tree))
            {
                return(severity);
            }

            foreach (var descriptor in analyzer.SupportedDiagnostics)
            {
                if (severity == DiagnosticSeverity.Error)
                {
                    break;
                }

                if (analyzerOptions.TryGetSeverityFromBulkConfiguration(tree, compilation, descriptor, out var reportDiagnostic))
                {
                    var configuredSeverity = ToSeverity(reportDiagnostic);
                    if (configuredSeverity > severity)
                    {
                        severity = configuredSeverity;
                    }
                    continue;
                }

                if (TryGetSeverityFromCodeStyleOption(descriptor, compilation, options, out var codeStyleSeverity))
                {
                    if (codeStyleSeverity > severity)
                    {
                        severity = codeStyleSeverity;
                    }
                    continue;
                }

                if (descriptor.DefaultSeverity > severity)
                {
                    severity = descriptor.DefaultSeverity;
                }
            }

            return(severity);
Example #9
0
 public AnalysisScope(
     Compilation compilation,
     AnalyzerOptions?analyzerOptions,
     ImmutableArray <DiagnosticAnalyzer> analyzers,
     bool hasAllAnalyzers,
     bool concurrentAnalysis,
     bool categorizeDiagnostics
     )
     : this(
         compilation.SyntaxTrees,
         analyzerOptions?.AdditionalFiles ?? ImmutableArray <AdditionalText> .Empty,
         analyzers,
         isPartialAnalysis : !hasAllAnalyzers,
         filterFile : null,
         filterSpanOpt : null,
         isSyntacticSingleFileAnalysis : false,
         concurrentAnalysis : concurrentAnalysis,
         categorizeDiagnostics : categorizeDiagnostics
         )
 {
 }
 public AsaAnalyzer(AnalyzerOptions?opts = null) : base(opts)
 {
     CustomPropertyExtractionDelegates.Add(ParseCustomAsaProperties);
     CustomObjectToValuesDelegates.Add(ParseCustomAsaObjectValues);
 }
Example #11
0
        // Analysis
        public static async Task <Diagnostic[]> AnalyzeAsync(Compilation compilation, DiagnosticAnalyzer[] analyzers, AnalyzerOptions?analyzerOptions, CancellationToken cancellationToken)
        {
            var compilationWithAnalyzers = compilation.WithAnalyzers(analyzers.ToImmutableArray(), analyzerOptions, cancellationToken);
            var diagnostics = await compilationWithAnalyzers.GetAllDiagnosticsAsync(cancellationToken).ConfigureAwait(false);

            return(diagnostics.Where(i => !IsCompilerDiagnostic(i)).OrderBy(i => i.Id).ThenBy(i => i.Location.SourceTree?.FilePath).ThenBy(i => i.Location.SourceSpan).ToArray());
        }