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); }