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)
                        )
                    );
            }
        }
        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
            MarkupTestFile.GetPositionAndSpans(markup,
                                               out var source, out var pos, out IDictionary <string, ImmutableArray <TextSpan> > 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));
                    }
                }
            }
        }
Beispiel #3
0
 public CompilationAnalyzer(
     Compilation compilation,
     INamedTypeSymbol suppressMessageAttributeType
     )
 {
     _state = new SuppressMessageAttributeState(
         compilation,
         suppressMessageAttributeType
         );
 }
        public void TestResolveEnumFieldWithoutName()
        {
            var source      = @"
enum E
{
    $$,
}
";
            var syntaxTree  = CreateSyntaxTree(source, LanguageNames.CSharp);
            var compilation = CreateCompilation(syntaxTree, LanguageNames.CSharp, "");

            _ = SuppressMessageAttributeState.ResolveTargetSymbols(compilation, "E.", SuppressMessageAttributeState.TargetScope.Member);
        }
        /// <summary>
        /// Gets the <see cref="SuppressionInfo"/> for suppressed diagnostics, i.e. <see cref="IsSuppressed"/> = true.
        /// Otherwise, returns null.
        /// </summary>
        public SuppressionInfo GetSuppressionInfo(Compilation compilation)
        {
            if (!IsSuppressed)
            {
                return(null);
            }

            SuppressMessageAttributeState suppressMessageState = new SuppressMessageAttributeState(compilation);

            if (!suppressMessageState.IsDiagnosticSuppressed(this, out AttributeData attribute))
            {
                attribute = null;
            }

            return(new SuppressionInfo(this.Id, attribute));
        }
            public void AnalyzeAssemblyOrModuleAttribute(SyntaxNode attributeSyntax, SemanticModel model, Action <Diagnostic> reportDiagnostic, CancellationToken cancellationToken)
            {
                if (!_state.IsSuppressMessageAttributeWithNamedArguments(attributeSyntax, model, cancellationToken, out var namedAttributeArguments))
                {
                    return;
                }

                if (!SuppressMessageAttributeState.HasValidScope(namedAttributeArguments, out var targetScope))
                {
                    reportDiagnostic(Diagnostic.Create(s_invalidScopeDescriptor, attributeSyntax.GetLocation()));
                    return;
                }

                if (!_state.HasValidTarget(namedAttributeArguments, targetScope, out var targetHasDocCommentIdFormat,
                                           out var targetSymbolString, out var targetValueOperation, out var resolvedSymbols))
                {
                    reportDiagnostic(Diagnostic.Create(s_invalidOrMissingTargetDescriptor, attributeSyntax.GetLocation()));
                    return;
                }

                // We want to flag valid target which uses legacy format to update to Roslyn based DocCommentId format.
                if (resolvedSymbols.Length > 0 && !targetHasDocCommentIdFormat)
                {
                    RoslynDebug.Assert(!string.IsNullOrEmpty(targetSymbolString));
                    RoslynDebug.Assert(targetValueOperation != null);

                    var properties = ImmutableDictionary <string, string?> .Empty;
                    if (resolvedSymbols.Length == 1)
                    {
                        // We provide a code fix for the case where the target resolved to a single symbol.
                        var docCommentId = DocumentationCommentId.CreateDeclarationId(resolvedSymbols[0]);
                        if (!string.IsNullOrEmpty(docCommentId))
                        {
                            // Suppression target has an optional "~" prefix to distinguish it from legacy FxCop suppressions.
                            // IDE suppression code fixes emit this prefix, so we we also add this prefix to new suppression target string.
                            properties = properties.Add(DocCommentIdKey, "~" + docCommentId);
                        }
                    }

                    reportDiagnostic(Diagnostic.Create(LegacyFormatTargetDescriptor, targetValueOperation.Syntax.GetLocation(), properties !, targetSymbolString));
                    return;
                }
            }
Beispiel #7
0
        public SuppressionInfo?GetSuppressionInfo(Compilation compilation)
        {
            if (!IsSuppressed)
            {
                return(null);
            }

            AttributeData?attribute;
            var           suppressMessageState = new SuppressMessageAttributeState(compilation);

            if (!suppressMessageState.IsDiagnosticSuppressed(
                    this,
                    getSemanticModel: (compilation, tree) => compilation.GetSemanticModel(tree),
                    out attribute))
            {
                attribute = null;
            }

            return(new SuppressionInfo(this.Id, attribute));
        }
Beispiel #8
0
            public void AnalyzeAssemblyOrModuleAttribute(SyntaxNode attributeSyntax, SemanticModel model, Action <Diagnostic> reportDiagnostic, CancellationToken cancellationToken)
            {
                if (!_state.IsSuppressMessageAttributeWithNamedArguments(attributeSyntax, model, cancellationToken, out var namedAttributeArguments))
                {
                    return;
                }

                DiagnosticDescriptor rule;

                if (SuppressMessageAttributeState.HasInvalidScope(namedAttributeArguments, out var targetScope))
                {
                    rule = s_invalidScopeDescriptor;
                }
                else if (_state.HasInvalidOrMissingTarget(namedAttributeArguments, targetScope))
                {
                    rule = s_invalidOrMissingTargetDescriptor;
                }
                else
                {
                    return;
                }

                reportDiagnostic(Diagnostic.Create(rule, attributeSyntax.GetLocation()));
            }