bool IsSuppressed(int id, ICustomAttributeProvider warningOrigin, out SuppressMessageInfo info)
        {
            info = default;

            if (warningOrigin is IMemberDefinition warningOriginMember)
            {
                while (warningOriginMember != null)
                {
                    if (IsSuppressedOnElement(id, warningOriginMember, out info))
                    {
                        return(true);
                    }

                    warningOriginMember = warningOriginMember.DeclaringType;
                }
            }

            ModuleDefinition?module = GetModuleFromProvider(warningOrigin);

            if (module == null)
            {
                return(false);
            }

            // Check if there's an assembly or module level suppression.
            if (IsSuppressedOnElement(id, module, out info) ||
                IsSuppressedOnElement(id, module.Assembly, out info))
            {
                return(true);
            }

            return(false);
        }
Esempio n. 2
0
        public bool IsSuppressed(int id, MessageOrigin warningOrigin, out SuppressMessageInfo info)
        {
            info = default;
            if (warningOrigin.MemberDefinition == null)
            {
                return(false);
            }

            IMemberDefinition elementContainingWarning = warningOrigin.MemberDefinition;
            ModuleDefinition  module = GetModuleFromProvider(warningOrigin.MemberDefinition);

            DecodeModuleLevelAndGlobalSuppressMessageAttributes(module);
            while (elementContainingWarning != null)
            {
                if (IsSuppressed(id, elementContainingWarning, out info))
                {
                    return(true);
                }

                elementContainingWarning = elementContainingWarning.DeclaringType;
            }

            // Check if there's an assembly or module level suppression.
            if (IsSuppressed(id, module, out info) ||
                IsSuppressed(id, module.Assembly, out info))
            {
                return(true);
            }

            return(false);
        }
Esempio n. 3
0
        bool IsSuppressed(int id, IMemberDefinition warningOriginMember, out SuppressMessageInfo info)
        {
            info = default;
            if (warningOriginMember == null)
            {
                return(false);
            }

            ModuleDefinition module = GetModuleFromProvider(warningOriginMember);

            DecodeModuleLevelAndGlobalSuppressMessageAttributes(module);
            while (warningOriginMember != null)
            {
                if (IsSuppressedOnElement(id, warningOriginMember, out info))
                {
                    return(true);
                }

                warningOriginMember = warningOriginMember.DeclaringType;
            }

            // Check if there's an assembly or module level suppression.
            if (IsSuppressedOnElement(id, module, out info) ||
                IsSuppressedOnElement(id, module.Assembly, out info))
            {
                return(true);
            }

            return(false);
        }
Esempio n. 4
0
        private bool IsLocallySuppressed(int id, ICustomAttributeProvider provider, out SuppressMessageInfo info)
        {
            Dictionary <int, SuppressMessageInfo> suppressions;

            info = default;
            return(_localSuppressions.TryGetValue(provider, out suppressions) &&
                   suppressions.TryGetValue(id, out info));
        }
Esempio n. 5
0
        bool IsSuppressed(int id, ICustomAttributeProvider provider, out SuppressMessageInfo info)
        {
            info = default;
            if (provider == null)
            {
                return(false);
            }

            return(_suppressions.TryGetValue(provider, out var suppressions) &&
                   suppressions.TryGetValue(id, out info));
        }
        bool IsSuppressedOnElement(int id, ICustomAttributeProvider?provider, out SuppressMessageInfo info)
        {
            info = default;
            if (provider == null)
            {
                return(false);
            }

            if (_suppressions.TryGetValue(provider, out var suppressions))
            {
                return(suppressions.TryGetValue(id, out info));
            }

            // Populate the cache with suppressions for this member. We need to look for suppressions on the
            // member itself, and on the assembly/module.

            var membersToScan = new HashSet <ICustomAttributeProvider> {
                { provider }
            };

            // Gather assembly-level suppressions if we haven't already. To ensure that we always cache
            // complete information for a member, we will also scan for attributes on any other members
            // targeted by the assembly-level suppressions.
            if (GetModuleFromProvider(provider) is ModuleDefinition module)
            {
                var assembly = module.Assembly;
                if (InitializedAssemblies.Add(assembly))
                {
                    foreach (var suppression in DecodeAssemblyAndModuleSuppressions(module))
                    {
                        AddSuppression(suppression.Info, suppression.Target);
                        membersToScan.Add(suppression.Target);
                    }
                }
            }

            // Populate the cache for this member, and for any members that were targeted by assembly-level
            // suppressions to make sure the cached info is complete.
            foreach (var member in membersToScan)
            {
                if (member is ModuleDefinition or AssemblyDefinition)
                {
                    continue;
                }
                foreach (var suppressionInfo in DecodeSuppressions(member))
                {
                    AddSuppression(suppressionInfo, member);
                }
            }

            return(_suppressions.TryGetValue(provider, out suppressions) && suppressions.TryGetValue(id, out info));
        }
        static bool TryDecodeSuppressMessageAttributeData(CustomAttribute attribute, out SuppressMessageInfo info)
        {
            info = default;

            // We need at least the Category and Id to decode the warning to suppress.
            // The only UnconditionalSuppressMessageAttribute constructor requires those two parameters.
            if (attribute.ConstructorArguments.Count < 2)
            {
                return(false);
            }

            // Ignore the category parameter because it does not identify the warning
            // and category information can be obtained from warnings themselves.
            // We only support warnings with code pattern IL####.
            if (!(attribute.ConstructorArguments[1].Value is string warningId) ||
                warningId.Length < 6 ||
                !warningId.StartsWith("IL") ||
                !int.TryParse(warningId.AsSpan(2, 4), out info.Id))
            {
                return(false);
            }

            if (warningId.Length > 6 && warningId[6] != ':')
            {
                return(false);
            }

            if (attribute.HasProperties)
            {
                foreach (var p in attribute.Properties)
                {
                    switch (p.Name)
                    {
                    case ScopeProperty when p.Argument.Value is string scope:
                        info.Scope = scope;
                        break;

                    case TargetProperty when p.Argument.Value is string target:
                        info.Target = target;
                        break;

                    case MessageIdProperty when p.Argument.Value is string messageId:
                        info.MessageId = messageId;
                        break;
                    }
                }
            }

            return(true);
        }
Esempio n. 8
0
        void AddSuppression(SuppressMessageInfo info, ICustomAttributeProvider provider)
        {
            if (!_suppressions.TryGetValue(provider, out var suppressions))
            {
                suppressions = new Dictionary <int, SuppressMessageInfo> ();
                _suppressions.Add(provider, suppressions);
            }

            if (suppressions.ContainsKey(info.Id))
            {
                _context.LogMessage($"Element {provider} has more than one unconditional suppression. Note that only the last one is used.");
            }

            suppressions[info.Id] = info;
        }
        void AddSuppression(SuppressMessageInfo info, ICustomAttributeProvider provider)
        {
            if (!_suppressions.TryGetValue(provider, out var suppressions))
            {
                suppressions = new Dictionary <int, SuppressMessageInfo> ();
                _suppressions.Add(provider, suppressions);
            }
            else if (suppressions.ContainsKey(info.Id))
            {
                string?elementName = provider is MemberReference memberRef?memberRef.GetDisplayName() : provider.ToString();

                _context.LogMessage($"Element '{elementName}' has more than one unconditional suppression. Note that only the last one is used.");
            }

            suppressions[info.Id] = info;
        }
Esempio n. 10
0
        public bool IsSuppressed(int id, MessageOrigin warningOrigin, out SuppressMessageInfo info)
        {
            if (HasLocalSuppressions && warningOrigin.MemberDefinition != null)
            {
                IMemberDefinition memberDefinition = warningOrigin.MemberDefinition;
                while (memberDefinition != null)
                {
                    if (IsLocallySuppressed(id, memberDefinition, out info))
                    {
                        return(true);
                    }

                    memberDefinition = memberDefinition.DeclaringType;
                }
            }

            info = default;
            return(false);
        }
Esempio n. 11
0
        public bool IsSuppressed(int id, MessageOrigin warningOrigin, out SuppressMessageInfo info)
        {
            // Check for suppressions on both the suppression context as well as the original member
            // (if they're different). This is to correctly handle compiler generated code
            // which needs to use suppressions from both the compiler generated scope
            // as well as the original user defined method.
            info = default;

            ICustomAttributeProvider?provider = warningOrigin.Provider;

            if (provider == null)
            {
                return(false);
            }

            if (IsSuppressed(id, provider, out info))
            {
                return(true);
            }

            if (provider is not IMemberDefinition member)
            {
                return(false);
            }

            MethodDefinition?owningMethod;

            while (_context.CompilerGeneratedState.TryGetOwningMethodForCompilerGeneratedMember(member, out owningMethod))
            {
                Debug.Assert(owningMethod != member);
                if (IsSuppressed(id, owningMethod, out info))
                {
                    return(true);
                }
                member = owningMethod;
            }

            return(false);
        }
Esempio n. 12
0
        public bool IsSuppressed(int id, MessageOrigin warningOrigin, out SuppressMessageInfo info)
        {
            // Check for suppressions on both the suppression context as well as the original member
            // (if they're different). This is to correctly handle compiler generated code
            // which needs to use suppressions from both the compiler generated scope
            // as well as the original user defined method.
            ICustomAttributeProvider?suppressionContextMember = warningOrigin.SuppressionContextMember;

            if (IsSuppressed(id, suppressionContextMember, out info))
            {
                return(true);
            }

            ICustomAttributeProvider?provider = warningOrigin.Provider;

            if (suppressionContextMember != provider && IsSuppressed(id, provider, out info))
            {
                return(true);
            }

            return(false);
        }