Beispiel #1
0
        private void CheckIfBaseDisposeIsCalled(MethodDefinition method, MemberReference baseMethod)
        {
            bool found = false;

            if (method.HasBody)
            {
                OpCodeBitmask bitmask = OpCodeEngine.GetBitmask(method);
                if (bitmask.Get(Code.Ldarg_0) && (OpCodeBitmask.Calls.Intersect(bitmask)))
                {
                    //Check for a call to base.Dispose();
                    foreach (Instruction ins in method.Body.Instructions)
                    {
                        if (ins.OpCode.Code != Code.Ldarg_0) //ldarg_0 (this)
                        {
                            continue;
                        }

                        Instruction call = ins.Next; //call baseMethod
                        if (call == null)
                        {
                            continue;
                        }
                        if (call.OpCode.Code != Code.Call && call.OpCode.Code != Code.Callvirt)
                        {
                            continue;
                        }
                        MethodReference calledMethod = (MethodReference)call.Operand;
                        if (calledMethod.GetFullName() != baseMethod.GetFullName())
                        {
                            continue;
                        }
                        found = true;
                    }
                }
            }

            if (!found)
            {
                string s = String.Format(CultureInfo.InvariantCulture, "{0} should call base.Dispose().", method.GetFullName());
                Runner.Report(method, Severity.Medium, Confidence.High, s);
            }
        }
        private void CheckForViolation(MethodDefinition method, Instruction instruction)
        {
            if ((instruction.OpCode.Code == Code.Newobj || instruction.OpCode.Code == Code.Newarr))
            {
                MemberReference member = (instruction.Operand as MemberReference);
                if ((member != null) && !IsNewException(member))
                {
                    string s = String.Format(CultureInfo.InvariantCulture,
                                             "Unused object of type '{0}' created.", member.GetFullName());
                    Runner.Report(method, instruction, Severity.High, Confidence.Normal, s);
                }
            }

            if (instruction.OpCode.Code == Code.Call || instruction.OpCode.Code == Code.Callvirt)
            {
                MethodReference callee = instruction.Operand as MethodReference;
                if (callee != null && !callee.ReturnType.IsValueType)
                {
                    // check for some common exceptions (to reduce false positive)
                    if (!IsCallException(callee))
                    {
                        string s = String.Format(CultureInfo.InvariantCulture,
                                                 "Do not ignore method results from call to '{0}'.", callee.GetFullName());
                        Runner.Report(method, instruction, Severity.Medium, Confidence.Normal, s);
                    }
                }
            }
        }
        protected override void Report(MethodDefinition method, Instruction instruction, MethodReference prefered)
        {
            string msg = String.Format(CultureInfo.InvariantCulture,
                                       "Consider using the perfered '{0}' override.", prefered.GetFullName());

            Runner.Report(method, instruction, Severity.Medium, Confidence.High, msg);
        }
        public RuleResult CheckMethod(MethodDefinition method)
        {
            // rule doesn't apply if method has no IL
            if (!method.HasBody)
            {
                return(RuleResult.DoesNotApply);
            }

            // check if any instruction refers to methods or types that MoMA could track
            if (!mask.Intersect(OpCodeEngine.GetBitmask(method)))
            {
                return(RuleResult.DoesNotApply);
            }

            // rule applies

            foreach (Instruction ins in method.Body.Instructions)
            {
                // look for any instruction that could use something incomplete
                if (!mask.Get(ins.OpCode.Code))
                {
                    continue;
                }

                // filter calls to assemblies that MoMA likely does not include (e.g. your own code)
                MethodReference mr = (ins.Operand as MethodReference);
                if ((mr == null) || !Filter(mr.DeclaringType.Scope as AssemblyNameReference))
                {
                    continue;
                }

                // MethodReference.ToString is costly so we do it once for the three checks
                string callee = mr.GetFullName();

                // calling not implemented method is very likely not to work == High
                if ((NotImplemented != null) && NotImplementedInternal.Contains(callee))
                {
                    string message = String.Format(CultureInfo.InvariantCulture, NotImplementedMessage, callee);
                    // confidence is Normal since we can't be sure if MoMA data is up to date
                    Runner.Report(method, ins, Severity.High, Confidence.Normal, message);
                }

                // calling missing methods can't work == Critical
                if ((Missing != null) && Missing.Contains(callee))
                {
                    string message = String.Format(CultureInfo.InvariantCulture, MissingMessage, callee);
                    Runner.Report(method, ins, Severity.Critical, Confidence.Normal, message);
                }

                // calling todo methods migh work with some limitations == Medium
                if (ToDo != null)
                {
                    string value;
                    if (ToDo.TryGetValue(callee, out value))
                    {
                        string message = String.Format(CultureInfo.InvariantCulture, TodoMessage, callee, value);
                        Runner.Report(method, ins, Severity.Medium, Confidence.Normal, message);
                    }
                }
            }

            return(Runner.CurrentRuleResult);
        }