Example #1
0
        private bool IsDiagnosticSuppressed(string id, ISymbol symbol, out SuppressMessageInfo info)
        {
            Debug.Assert(id != null);
            Debug.Assert(symbol != null);

            if (symbol.Kind == SymbolKind.Namespace)
            {
                // Suppressions associated with namespace symbols only apply to namespace declarations themselves
                // and any syntax nodes immediately contained therein, not to nodes attached to any other symbols.
                // Diagnostics those nodes will be filtered by location, not by associated symbol.
                info = default(SuppressMessageInfo);
                return(false);
            }

            if (symbol.Kind == SymbolKind.Method)
            {
                ISymbol associated = ((IMethodSymbol)symbol).AssociatedSymbol;
                if (associated != null &&
                    (IsDiagnosticLocallySuppressed(id, associated, out info) || IsDiagnosticGloballySuppressed(id, associated, out info)))
                {
                    return(true);
                }
            }

            if (IsDiagnosticLocallySuppressed(id, symbol, out info) || IsDiagnosticGloballySuppressed(id, symbol, out info))
            {
                return(true);
            }

            // Check for suppression on parent symbol
            ISymbol parent = symbol.ContainingSymbol;

            return(parent != null && IsDiagnosticSuppressed(id, parent, out info));
        }
Example #2
0
 private static void AddOrUpdate(SuppressMessageInfo info, IDictionary <string, SuppressMessageInfo> builder)
 {
     // TODO: How should we deal with multiple SuppressMessage attributes, with different suppression info/states?
     // For now, we just pick the last attribute, if not suppressed.
     if (!builder.TryGetValue(info.Id, out SuppressMessageInfo currentInfo))
     {
         builder[info.Id] = info;
     }
 }
Example #3
0
        private bool IsDiagnosticSuppressed(Diagnostic diagnostic, out SuppressMessageInfo info, ISymbol symbolOpt = null)
        {
            if (symbolOpt != null && IsDiagnosticSuppressed(diagnostic.Id, symbolOpt, out info))
            {
                return(true);
            }

            return(IsDiagnosticSuppressed(diagnostic.Id, diagnostic.Location, out info));
        }
Example #4
0
            public bool HasGlobalSymbolSuppression(ISymbol symbol, string id, out SuppressMessageInfo info)
            {
                Debug.Assert(symbol != null);
                if (_globalSymbolSuppressions.TryGetValue(symbol, out Dictionary <string, SuppressMessageInfo> suppressions) &&
                    suppressions.TryGetValue(id, out info))
                {
                    return(true);
                }

                info = default(SuppressMessageInfo);
                return(false);
            }
Example #5
0
        private bool IsDiagnosticLocallySuppressed(
            string id,
            ISymbol symbol,
            out SuppressMessageInfo info
            )
        {
            var suppressions = _localSuppressionsBySymbol.GetOrAdd(
                symbol,
                this.DecodeLocalSuppressMessageAttributes
                );

            return(suppressions.TryGetValue(id, out info));
        }
 public void AddGlobalSymbolSuppression(ISymbol symbol, SuppressMessageInfo info)
 {
     Dictionary<string, SuppressMessageInfo> suppressions;
     if (_globalSymbolSuppressions.TryGetValue(symbol, out suppressions))
     {
         AddOrUpdate(info, suppressions);
     }
     else
     {
         suppressions = new Dictionary<string, SuppressMessageInfo>() {{ info.Id, info }};
         _globalSymbolSuppressions.Add(symbol, suppressions);
     }
 }
            public bool HasGlobalSymbolSuppression(ISymbol symbol, string id, out SuppressMessageInfo info)
            {
                Debug.Assert(symbol != null);
                Dictionary<string, SuppressMessageInfo> suppressions;
                if (_globalSymbolSuppressions.TryGetValue(symbol, out suppressions) &&
                    suppressions.TryGetValue(id, out info))
                {
                    return true;
                }

                info = default(SuppressMessageInfo);
                return false;
            }
Example #8
0
 public void AddGlobalSymbolSuppression(ISymbol symbol, SuppressMessageInfo info)
 {
     if (_globalSymbolSuppressions.TryGetValue(symbol, out Dictionary <string, SuppressMessageInfo> suppressions))
     {
         AddOrUpdate(info, suppressions);
     }
     else
     {
         suppressions = new Dictionary <string, SuppressMessageInfo>()
         {
             { info.Id, info }
         };
         _globalSymbolSuppressions.Add(symbol, suppressions);
     }
 }
Example #9
0
        private bool IsDiagnosticSuppressed(string id, Location location, out SuppressMessageInfo info)
        {
            Debug.Assert(id != null);
            Debug.Assert(location != null);

            info = default(SuppressMessageInfo);

            if (IsDiagnosticGloballySuppressed(id, symbolOpt: null, info: out info))
            {
                return(true);
            }

            // Walk up the syntax tree checking for suppression by any declared symbols encountered
            if (location.IsInSource)
            {
                SemanticModel model = _compilation.GetSemanticModel(location.SourceTree);
                bool          inImmediatelyContainingSymbol = true;

                for (SyntaxNode node = location.SourceTree.GetRoot().FindNode(location.SourceSpan, getInnermostNodeForTie: true);
                     node != null;
                     node = node.Parent)
                {
                    ImmutableArray <ISymbol> declaredSymbols = model.GetDeclaredSymbolsForNode(node);
                    Debug.Assert(declaredSymbols != null);

                    foreach (ISymbol symbol in declaredSymbols)
                    {
                        if (symbol.Kind == SymbolKind.Namespace)
                        {
                            // Special case: Only suppress syntax diagnostics in namespace declarations if the namespace is the closest containing symbol.
                            // In other words, only apply suppression to the immediately containing namespace declaration and not to its children or parents.
                            return(inImmediatelyContainingSymbol && IsDiagnosticGloballySuppressed(id, symbol, out info));
                        }
                        else if (IsDiagnosticLocallySuppressed(id, symbol, out info) || IsDiagnosticGloballySuppressed(id, symbol, out info))
                        {
                            return(true);
                        }

                        inImmediatelyContainingSymbol = false;
                    }
                }
            }

            return(false);
        }
Example #10
0
        private bool IsDiagnosticGloballySuppressed(
            string id,
            ISymbol?symbolOpt,
            bool isImmediatelyContainingSymbol,
            out SuppressMessageInfo info
            )
        {
            var globalSuppressions = this.DecodeGlobalSuppressMessageAttributes();

            return(globalSuppressions.HasCompilationWideSuppression(id, out info) ||
                   symbolOpt != null &&
                   globalSuppressions.HasGlobalSymbolSuppression(
                       symbolOpt,
                       id,
                       isImmediatelyContainingSymbol,
                       out info
                       ));
        }
Example #11
0
        private static bool TryDecodeSuppressMessageAttributeData(
            AttributeData attribute,
            out SuppressMessageInfo info
            )
        {
            info = default(SuppressMessageInfo);

            // We need at least the Category and Id to decode the diagnostic to suppress.
            // The only SuppressMessageAttribute constructor requires those two parameters.
            if (attribute.CommonConstructorArguments.Length < 2)
            {
                return(false);
            }

            // Ignore the category parameter because it does not identify the diagnostic
            // and category information can be obtained from diagnostics themselves.
            info.Id = attribute.CommonConstructorArguments[1].ValueInternal as string;
            if (info.Id == null)
            {
                return(false);
            }

            // Allow an optional human-readable descriptive name on the end of an Id.
            // See http://msdn.microsoft.com/en-us/library/ms244717.aspx
            var separatorIndex = info.Id.IndexOf(':');

            if (separatorIndex != -1)
            {
                info.Id = info.Id.Remove(separatorIndex);
            }

            info.Scope  = attribute.DecodeNamedArgument <string>("Scope", SpecialType.System_String);
            info.Target = attribute.DecodeNamedArgument <string>(
                "Target",
                SpecialType.System_String
                );
            info.MessageId = attribute.DecodeNamedArgument <string>(
                "MessageId",
                SpecialType.System_String
                );
            info.Attribute = attribute;

            return(true);
        }
Example #12
0
            public bool HasGlobalSymbolSuppression(
                ISymbol symbol,
                string id,
                bool isImmediatelyContainingSymbol,
                out SuppressMessageInfo info
                )
            {
                Debug.Assert(symbol != null);
                Dictionary <string, SuppressMessageInfo>?suppressions;

                if (
                    _globalSymbolSuppressions.TryGetValue(symbol, out suppressions) &&
                    suppressions.TryGetValue(id, out info)
                    )
                {
                    if (symbol.Kind != SymbolKind.Namespace)
                    {
                        return(true);
                    }

                    if (TryGetTargetScope(info, out TargetScope targetScope))
                    {
                        switch (targetScope)
                        {
                        case TargetScope.Namespace:
                            // Special case: Only suppress syntax diagnostics in namespace declarations if the namespace is the closest containing symbol.
                            // In other words, only apply suppression to the immediately containing namespace declaration and not to its children or parents.
                            return(isImmediatelyContainingSymbol);

                        case TargetScope.NamespaceAndDescendants:
                            return(true);
                        }
                    }
                }

                info = default(SuppressMessageInfo);
                return(false);
            }
Example #13
0
 private bool IsDiagnosticSuppressed(Diagnostic diagnostic, out SuppressMessageInfo info)
 => IsDiagnosticSuppressed(diagnostic.Id, diagnostic.Location, out info);
 public void AddCompilationWideSuppression(SuppressMessageInfo info)
 {
     AddOrUpdate(info, _compilationWideSuppressions);
 }
 private static void AddOrUpdate(SuppressMessageInfo info, IDictionary<string, SuppressMessageInfo> builder)
 {
     // TODO: How should we deal with multiple SuppressMessage attributes, with different suppression info/states?
     // For now, we just pick the last attribute, if not suppressed.
     SuppressMessageInfo currentInfo;
     if (!builder.TryGetValue(info.Id, out currentInfo))
     {
         builder[info.Id] = info;
     }
 }
 private bool IsDiagnosticLocallySuppressed(string id, ISymbol symbol, out SuppressMessageInfo info)
 {
     var suppressions = _localSuppressionsBySymbol.GetOrAdd(symbol, this.DecodeLocalSuppressMessageAttributes);
     return suppressions.TryGetValue(id, out info);
 }
 private bool IsDiagnosticGloballySuppressed(string id, ISymbol symbolOpt, out SuppressMessageInfo info)
 {
     this.DecodeGlobalSuppressMessageAttributes();
     return _lazyGlobalSuppressions.HasCompilationWideSuppression(id, out info) ||
         symbolOpt != null && _lazyGlobalSuppressions.HasGlobalSymbolSuppression(symbolOpt, id, out info);
 }
        private bool IsDiagnosticSuppressed(string id, Location location, out SuppressMessageInfo info)
        {
            Debug.Assert(id != null);
            Debug.Assert(location != null);

            info = default(SuppressMessageInfo);

            if (IsDiagnosticGloballySuppressed(id, symbolOpt: null, info: out info))
            {
                return true;
            }

            // Walk up the syntax tree checking for suppression by any declared symbols encountered
            if (location.IsInSource)
            {
                var model = _compilation.GetSemanticModel(location.SourceTree);
                bool inImmediatelyContainingSymbol = true;

                for (var node = location.SourceTree.GetRoot().FindNode(location.SourceSpan, getInnermostNodeForTie: true);
                    node != null;
                    node = node.Parent)
                {
                    var declaredSymbols = model.GetDeclaredSymbolsForNode(node);
                    Debug.Assert(declaredSymbols != null);

                    foreach (var symbol in declaredSymbols)
                    {
                        if (symbol.Kind == SymbolKind.Namespace)
                        {
                            // Special case: Only suppress syntax diagnostics in namespace declarations if the namespace is the closest containing symbol.
                            // In other words, only apply suppression to the immediately containing namespace declaration and not to its children or parents.
                            return inImmediatelyContainingSymbol && IsDiagnosticGloballySuppressed(id, symbol, out info);
                        }
                        else if (IsDiagnosticLocallySuppressed(id, symbol, out info) || IsDiagnosticGloballySuppressed(id, symbol, out info))
                        {
                            return true;
                        }

                        inImmediatelyContainingSymbol = false;
                    }
                }
            }

            return false;
        }
        private bool IsDiagnosticSuppressed(string id, Location location, Func <Compilation, SyntaxTree, SemanticModel> getSemanticModel, out SuppressMessageInfo info)
        {
            Debug.Assert(id != null);
            Debug.Assert(location != null);

            info = default(SuppressMessageInfo);

            if (IsDiagnosticGloballySuppressed(id, symbolOpt: null, isImmediatelyContainingSymbol: false, info: out info))
            {
                return(true);
            }

            // Walk up the syntax tree checking for suppression by any declared symbols encountered
            if (location.IsInSource)
            {
                var  model = getSemanticModel(_compilation, location.SourceTree);
                bool inImmediatelyContainingSymbol = true;

                for (var node = location.SourceTree.GetRoot().FindNode(location.SourceSpan, getInnermostNodeForTie: true);
                     node != null;
                     node = node.Parent)
                {
                    var declaredSymbols = model.GetDeclaredSymbolsForNode(node);
                    Debug.Assert(declaredSymbols != null);

                    foreach (var symbol in declaredSymbols)
                    {
                        if (symbol.Kind == SymbolKind.Namespace)
                        {
                            return(hasNamespaceSuppression((INamespaceSymbol)symbol, inImmediatelyContainingSymbol));
                        }
                        else if (IsDiagnosticLocallySuppressed(id, symbol, out info) || IsDiagnosticGloballySuppressed(id, symbol, inImmediatelyContainingSymbol, out info))
                        {
                            return(true);
                        }
                    }

                    if (!declaredSymbols.IsEmpty)
                    {
                        inImmediatelyContainingSymbol = false;
                    }
                }
            }

            return(false);

            bool hasNamespaceSuppression(INamespaceSymbol namespaceSymbol, bool inImmediatelyContainingSymbol)
            {
                do
                {
                    if (IsDiagnosticGloballySuppressed(id, namespaceSymbol, inImmediatelyContainingSymbol, out _))
                    {
                        return(true);
                    }

                    namespaceSymbol = namespaceSymbol.ContainingNamespace;
                    inImmediatelyContainingSymbol = false;
                }while (namespaceSymbol != null);

                return(false);
            }
        }
 public bool HasCompilationWideSuppression(string id, out SuppressMessageInfo info)
 {
     return(_compilationWideSuppressions.TryGetValue(id, out info));
 }
 public void AddCompilationWideSuppression(SuppressMessageInfo info)
 {
     AddOrUpdate(info, _compilationWideSuppressions);
 }
 private static bool TryGetTargetScope(SuppressMessageInfo info, out TargetScope scope)
 => s_suppressMessageScopeTypes.TryGetValue(info.Scope ?? string.Empty, out scope);
        private bool IsDiagnosticSuppressed(Diagnostic diagnostic, out SuppressMessageInfo info)
        {
            info = default;

            if (diagnostic.CustomTags.Contains(WellKnownDiagnosticTags.Compiler))
            {
                // SuppressMessage attributes do not apply to compiler diagnostics.
                return(false);
            }

            var id       = diagnostic.Id;
            var location = diagnostic.Location;

            if (IsDiagnosticGloballySuppressed(id, symbolOpt: null, isImmediatelyContainingSymbol: false, info: out info))
            {
                return(true);
            }

            // Walk up the syntax tree checking for suppression by any declared symbols encountered
            if (location.IsInSource)
            {
                var  model = _compilation.GetSemanticModel(location.SourceTree);
                bool inImmediatelyContainingSymbol = true;

                for (var node = location.SourceTree.GetRoot().FindNode(location.SourceSpan, getInnermostNodeForTie: true);
                     node != null;
                     node = node.Parent)
                {
                    var declaredSymbols = model.GetDeclaredSymbolsForNode(node);
                    Debug.Assert(declaredSymbols != null);

                    foreach (var symbol in declaredSymbols)
                    {
                        if (symbol.Kind == SymbolKind.Namespace)
                        {
                            return(hasNamespaceSuppression((INamespaceSymbol)symbol, inImmediatelyContainingSymbol));
                        }
                        else if (IsDiagnosticLocallySuppressed(id, symbol, out info) || IsDiagnosticGloballySuppressed(id, symbol, inImmediatelyContainingSymbol, out info))
                        {
                            return(true);
                        }
                    }

                    if (!declaredSymbols.IsEmpty)
                    {
                        inImmediatelyContainingSymbol = false;
                    }
                }
            }

            return(false);

            bool hasNamespaceSuppression(INamespaceSymbol namespaceSymbol, bool inImmediatelyContainingSymbol)
            {
                do
                {
                    if (IsDiagnosticGloballySuppressed(id, namespaceSymbol, inImmediatelyContainingSymbol, out _))
                    {
                        return(true);
                    }

                    namespaceSymbol = namespaceSymbol.ContainingNamespace;
                    inImmediatelyContainingSymbol = false;
                }while (namespaceSymbol != null);

                return(false);
            }
        }
Example #24
0
        private static bool IsDiagnosticSuppressed(Diagnostic diagnostic, Compilation compilation, out SuppressMessageInfo info)
        {
            var suppressMessageState = AnalyzerDriver.GetOrCreateCachedCompilationData(compilation).SuppressMessageAttributeState;

            return(suppressMessageState.IsDiagnosticSuppressed(diagnostic, out info));
        }
        private bool IsDiagnosticSuppressed(Diagnostic diagnostic, out SuppressMessageInfo info, ISymbol symbolOpt = null)
        {
            if (symbolOpt != null && IsDiagnosticSuppressed(diagnostic.Id, symbolOpt, out info))
            {
                return true;
            }

            return IsDiagnosticSuppressed(diagnostic.Id, diagnostic.Location, out info);
        }
 private bool IsDiagnosticSuppressed(Diagnostic diagnostic, Func <Compilation, SyntaxTree, SemanticModel> getSemanticModel, out SuppressMessageInfo info)
 => IsDiagnosticSuppressed(diagnostic.Id, diagnostic.Location, getSemanticModel, out info);
 public bool HasCompilationWideSuppression(string id, out SuppressMessageInfo info)
 {
     return _compilationWideSuppressions.TryGetValue(id, out info);
 }
        private bool IsDiagnosticSuppressed(string id, ISymbol symbol, out SuppressMessageInfo info)
        {
            Debug.Assert(id != null);
            Debug.Assert(symbol != null);

            if (symbol.Kind == SymbolKind.Namespace)
            {
                // Suppressions associated with namespace symbols only apply to namespace declarations themselves
                // and any syntax nodes immediately contained therein, not to nodes attached to any other symbols.
                // Diagnostics those nodes will be filtered by location, not by associated symbol.
                info = default(SuppressMessageInfo);
                return false;
            }

            if (symbol.Kind == SymbolKind.Method)
            {
                var associated = ((IMethodSymbol)symbol).AssociatedSymbol;
                if (associated != null &&
                    (IsDiagnosticLocallySuppressed(id, associated, out info) || IsDiagnosticGloballySuppressed(id, associated, out info)))
                {
                    return true;
                }
            }

            if (IsDiagnosticLocallySuppressed(id, symbol, out info) || IsDiagnosticGloballySuppressed(id, symbol, out info))
            {
                return true;
            }

            // Check for suppression on parent symbol
            var parent = symbol.ContainingSymbol;
            return parent != null && IsDiagnosticSuppressed(id, parent, out info);
        }
Example #29
0
 private bool IsDiagnosticGloballySuppressed(string id, ISymbol symbolOpt, out SuppressMessageInfo info)
 {
     this.DecodeGlobalSuppressMessageAttributes();
     return(_lazyGlobalSuppressions.HasCompilationWideSuppression(id, out info) ||
            symbolOpt != null && _lazyGlobalSuppressions.HasGlobalSymbolSuppression(symbolOpt, id, out info));
 }
        private static bool TryDecodeSuppressMessageAttributeData(AttributeData attribute, out SuppressMessageInfo info)
        {
            info = default(SuppressMessageInfo);

            // We need at least the Category and Id to decode the diagnostic to suppress.
            // The only SuppressMessageAttribute constructor requires those two parameters.
            if (attribute.CommonConstructorArguments.Length < 2)
            {
                return false;
            }

            // Ignore the category parameter because it does not identify the diagnostic
            // and category information can be obtained from diagnostics themselves.
            info.Id = attribute.CommonConstructorArguments[1].Value as string;
            if (info.Id == null)
            {
                return false;
            }

            // Allow an optional human-readable descriptive name on the end of an Id.
            // See http://msdn.microsoft.com/en-us/library/ms244717.aspx
            var separatorIndex = info.Id.IndexOf(':');
            if (separatorIndex != -1)
            {
                info.Id = info.Id.Remove(separatorIndex);
            }

            info.Scope = attribute.DecodeNamedArgument<string>("Scope", SpecialType.System_String);
            info.Target = attribute.DecodeNamedArgument<string>("Target", SpecialType.System_String);
            info.MessageId = attribute.DecodeNamedArgument<string>("MessageId", SpecialType.System_String);

            return true;
        }
 private static bool IsDiagnosticSuppressed(Diagnostic diagnostic, Compilation compilation, out SuppressMessageInfo info)
 {
     var suppressMessageState = AnalyzerDriver.GetOrCreateCachedCompilationData(compilation).SuppressMessageAttributeState;
     return suppressMessageState.IsDiagnosticSuppressed(diagnostic, out info);
 }