/// <summary>
        /// Given a set of compiler or <see cref="DiagnosticAnalyzer"/> generated <paramref name="diagnostics"/>, returns the effective diagnostics after applying the below filters:
        /// 1) <see cref="CompilationOptions.SpecificDiagnosticOptions"/> specified for the given <paramref name="compilation"/>.
        /// 2) <see cref="CompilationOptions.GeneralDiagnosticOption"/> specified for the given <paramref name="compilation"/>.
        /// 3) Diagnostic suppression through applied <see cref="System.Diagnostics.CodeAnalysis.SuppressMessageAttribute"/>.
        /// 4) Pragma directives for the given <paramref name="compilation"/>.
        /// </summary>
        public static IEnumerable<Diagnostic> GetEffectiveDiagnostics(IEnumerable<Diagnostic> diagnostics, Compilation compilation)
        {
            if (diagnostics == null)
            {
                throw new ArgumentNullException(nameof(diagnostics));
            }

            if (compilation == null)
            {
                throw new ArgumentNullException(nameof(compilation));
            }

            var suppressMessageState = new SuppressMessageAttributeState(compilation);
            foreach (var diagnostic in diagnostics.ToImmutableArray())
            {
                if (diagnostic != null)
                {
                    var effectiveDiagnostic = compilation.Options.FilterDiagnostic(diagnostic);
                    if (effectiveDiagnostic != null)
                    {
                        effectiveDiagnostic = suppressMessageState.ApplySourceSuppressions(effectiveDiagnostic);
                        yield return effectiveDiagnostic;
                    }
                }
            }
        }
예제 #2
0
 private static IEnumerable<Diagnostic> GetEffectiveDiagnosticsImpl(ImmutableArray<Diagnostic> diagnostics, Compilation compilation)
 {
     var suppressMessageState = new SuppressMessageAttributeState(compilation);
     foreach (var diagnostic in diagnostics)
     {
         if (diagnostic != null)
         {
             var effectiveDiagnostic = compilation.Options.FilterDiagnostic(diagnostic);
             if (effectiveDiagnostic != null)
             {
                 yield return suppressMessageState.ApplySourceSuppressions(effectiveDiagnostic);
             }
         }
     }
 }
        private static void VerifyNoResolution(string source, string[] fxCopFullyQualifiedNames, SuppressMessageAttributeState.TargetScope scope, string language, string rootNamespace)
        {
            var compilation = CreateCompilation(source, language, rootNamespace);

            foreach (var fxCopName in fxCopFullyQualifiedNames)
            {
                var symbols = SuppressMessageAttributeState.ResolveTargetSymbols(compilation, fxCopName, scope);

                Assert.True(symbols.FirstOrDefault() == null,
                    string.Format("Did not expect FxCop fully-qualified name '{0}' to resolve to any symbol: resolved to:\r\n{1}",
                        fxCopName, string.Join("\r\n", symbols)));
            }
        }
예제 #4
0
        private ImmutableArray<Diagnostic> FilterDiagnosticsSuppressedInSource(ImmutableArray<Diagnostic> diagnostics, Compilation compilation, SuppressMessageAttributeState suppressMessageState)
        {
            if (diagnostics.IsEmpty)
            {
                return diagnostics;
            }

            var reportSuppressedDiagnostics = compilation.Options.ReportSuppressedDiagnostics;
            var builder = ImmutableArray.CreateBuilder<Diagnostic>();
            for (var i = 0; i < diagnostics.Length; i++)
            {
#if DEBUG
                // We should have ignored diagnostics with invalid locations and reported analyzer exception diagnostic for the same.
                DiagnosticAnalysisContextHelpers.VerifyDiagnosticLocationsInCompilation(diagnostics[i], compilation);
#endif

                var diagnostic = suppressMessageState.ApplySourceSuppressions(diagnostics[i]);
                if (!reportSuppressedDiagnostics && diagnostic.IsSuppressed)
                {
                    // Diagnostic suppressed in source.
                    continue;
                }

                builder.Add(diagnostic);
            }

            return builder.ToImmutable();
        }
        private static void VerifyResolution(string markup, string[] fxCopFullyQualifiedNames, SuppressMessageAttributeState.TargetScope scope, string language, string rootNamespace)
        {
            // Parse out the span containing the declaration of the expected symbol
            string source;
            int? pos;
            IDictionary<string, IList<TextSpan>> spans;
            MarkupTestFile.GetPositionAndSpans(markup, out source, out pos, out spans);

            Assert.True(pos != null || spans.Count > 0, "Must specify a position or spans marking expected symbols for resolution");

            // Get the expected symbol from the given position
            var syntaxTree = CreateSyntaxTree(source, language);
            var compilation = CreateCompilation(syntaxTree, language, rootNamespace);
            var model = compilation.GetSemanticModel(syntaxTree);
            var expectedSymbols = new List<ISymbol>();

            bool shouldResolveSingleSymbol = pos != null;
            if (shouldResolveSingleSymbol)
            {
                expectedSymbols.Add(GetSymbolAtPosition(model, pos.Value));
            }
            else
            {
                foreach (var span in spans.Values.First())
                {
                    expectedSymbols.Add(GetSymbolAtPosition(model, span.Start));
                }
            }

            // Resolve the symbol based on each given FxCop fully-qualified name
            foreach (var fxCopName in fxCopFullyQualifiedNames)
            {
                var symbols = SuppressMessageAttributeState.ResolveTargetSymbols(compilation, fxCopName, scope);

                if (shouldResolveSingleSymbol)
                {
                    var expectedSymbol = expectedSymbols.Single();

                    if (symbols.Count() > 1)
                    {
                        Assert.True(false,
                            string.Format("Expected to resolve FxCop fully-qualified name '{0}' to '{1}': got multiple symbols:\r\n{2}",
                                fxCopName, expectedSymbol, string.Join("\r\n", symbols)));
                    }

                    var symbol = symbols.SingleOrDefault();
                    Assert.True(expectedSymbol == symbol,
                        string.Format("Failed to resolve FxCop fully-qualified name '{0}' to symbol '{1}': got '{2}'",
                            fxCopName, expectedSymbol, symbol));
                }
                else
                {
                    foreach (var symbol in symbols)
                    {
                        Assert.True(expectedSymbols.Contains(symbol),
                            string.Format("Failed to resolve FxCop fully-qualified name '{0}' to symbols:\r\n{1}\r\nResolved to unexpected symbol '{2}'",
                                fxCopName, string.Join("\r\n", expectedSymbols), symbol));
                    }
                }
            }
        }