Esempio n. 1
0
        public override void VisitMethodCall(MethodCall call)
        {
            MemberBinding mb = call.Callee as MemberBinding;

            if (mb == null)
            {
                return;
            }

            Method calledMethod = mb.BoundMember as Method;

            if (calledMethod == null)
            {
                return;
            }

            Method template = calledMethod.Template;

            if (template != null && template.Name.Name == "get_Result" && template.DeclaringType.Name.Name == "Task`1")
            {
                // check if callee is result
                var innercall = mb.TargetObject as MethodCall;
                if (innercall != null)
                {
                    MemberBinding mb2 = innercall.Callee as MemberBinding;
                    if (mb2 != null)
                    {
                        Method calledMethod2 = mb2.BoundMember as Method;
                        if (calledMethod2 != null)
                        {
                            Method template2 = calledMethod2.Template;
                            if (contractNodes.IsResultMethod(template2))
                            {
                                this.foundReturnValueTaskResult = true;
                                //return new ReturnValue(calledMethod.DeclaringType.TemplateArguments[0]);
                                return;
                            }
                        }
                    }
                }
            }

            // For async methods calledMethod (Contract.Result) would be called in the generated generic state machine,
            // and calledMethod.ReturnType would be generic type argument and actualResultType can be generic method argument
            // (if async postcondition declared in the generic method from non-generic class).
            // In this case calledMethod.ReturnType would be != this.actualResultType
            // and different comparison logic should be used (reflected in EquivalentGenercTypes method).
            if (this.actualResultType != null && contractNodes.IsResultMethod(template) &&
                (calledMethod.ReturnType == this.actualResultType || EquivalentGenericTypes(calledMethod, actualResultType)))
            {
                // using Contract.Result<T>() in a Task<T> returning method, this is a shorthand for
                // Contract.Result<Task<T>>().Result
                this.foundReturnValueTaskResult = true;
                return;
            }

            base.VisitMethodCall(call);
        }
Esempio n. 2
0
        public override void VisitMethodCall(MethodCall call)
        {
            MemberBinding mb = call.Callee as MemberBinding;

            if (mb == null)
            {
                return;
            }

            Method calledMethod = mb.BoundMember as Method;

            if (calledMethod == null)
            {
                return;
            }

            Method template = calledMethod.Template;

            if (template != null && template.Name.Name == "get_Result" && template.DeclaringType.Name.Name == "Task`1")
            {
                // check if callee is result
                var innercall = mb.TargetObject as MethodCall;
                if (innercall != null)
                {
                    MemberBinding mb2 = innercall.Callee as MemberBinding;
                    if (mb2 != null)
                    {
                        Method calledMethod2 = mb2.BoundMember as Method;
                        if (calledMethod2 != null)
                        {
                            Method template2 = calledMethod2.Template;
                            if (contractNodes.IsResultMethod(template2))
                            {
                                this.foundReturnValueTaskResult = true;
                                //return new ReturnValue(calledMethod.DeclaringType.TemplateArguments[0]);
                                return;
                            }
                        }
                    }
                }
            }

            if (this.actualResultType != null && contractNodes.IsResultMethod(template) &&
                calledMethod.ReturnType == this.actualResultType)
            {
                // using Contract.Result<T>() in a Task<T> returning method, this is a shorthand for
                // Contract.Result<Task<T>>().Result
                this.foundReturnValueTaskResult = true;
                return;
            }

            base.VisitMethodCall(call);
        }
        public override Expression VisitMethodCall(MethodCall call)
        {
            MemberBinding mb = call.Callee as MemberBinding;

            if (mb == null)
            {
                return(call);
            }

            Method calledMethod = mb.BoundMember as Method;

            if (calledMethod == null)
            {
                return(call);
            }

            Method template = calledMethod.Template;

            if (contractNodes.IsOldMethod(template))
            {
                OldExpression oe = new OldExpression(ExtractOldExpression(call));
                oe.Type = call.Type;
                return(oe);
            }

            if (contractNodes.IsValueAtReturnMethod(template))
            {
                return(new AddressDereference(call.Operands[0], calledMethod.TemplateArguments[0], call.SourceContext));
            }

            if (contractNodes.IsResultMethod(template))
            {
                // check if we are in an Task returning method
                if (this.declaringMethod != null && this.declaringMethod.ReturnType != null)
                {
                    var rt    = this.declaringMethod.ReturnType;
                    var templ = rt.Template;

                    if (templ != null && templ.Name.Name == "Task`1" && rt.TemplateArguments != null &&
                        rt.TemplateArguments.Count == 1)
                    {
                        var targ = rt.TemplateArguments[0];
                        if (calledMethod.TemplateArguments[0] == targ)
                        {
                            // use of ReturnValue<T>() instead of ReturnValue<Task<T>>().Result
                            var retExp     = new ReturnValue(rt, call.SourceContext);
                            var resultProp = rt.GetProperty(Identifier.For("Result"));
                            if (resultProp != null && resultProp.Getter != null)
                            {
                                return(new MethodCall(new MemberBinding(retExp, resultProp.Getter), new ExpressionList()));
                            }
                        }
                    }
                }

                return(new ReturnValue(calledMethod.ReturnType, call.SourceContext));
            }

            return(base.VisitMethodCall(call));
        }