コード例 #1
0
        public RuleResult CheckMethod(MethodDefinition method)
        {
            if (!method.HasBody)
            {
                return(RuleResult.DoesNotApply);
            }

            // exclude methods that don't have calls
            if (!OpCodeBitmask.Calls.Intersect(OpCodeEngine.GetBitmask(method)))
            {
                return(RuleResult.DoesNotApply);
            }

            foreach (Instruction ins in method.Body.Instructions)
            {
                MethodReference mr = ins.GetMethod();
                if ((mr == null) || !mr.DeclaringType.IsNamed("System", "Math"))
                {
                    continue;
                }

                Instruction value = null;
                string      name  = mr.Name;
                switch (name)
                {
                case "Ceiling":
                case "Floor":
                case "Truncate":
                    value = ins.Previous;
                    break;

                case "Round":
                    // variable number of arguments for different overloads
                    int n = ins.GetPopCount(method);
                    value = ins.Previous;
                    while (value != null)
                    {
                        // stop before first parameter
                        if (n == 1)
                        {
                            break;
                        }
                        n    += value.GetPopCount(method) - value.GetPushCount();
                        value = value.Previous;
                    }
                    break;
                }

                if (value == null)
                {
                    continue;
                }

                TypeReference type = GetArgumentType(value, method);
                if (type == null)
                {
                    continue;
                }

                string msg = String.Format(CultureInfo.InvariantCulture, "Math.{0} called on a {1}.",
                                           name, type.GetFullName());
                Runner.Report(method, ins, Severity.Medium, Confidence.Normal, msg);
            }
            return(Runner.CurrentRuleResult);
        }