Beispiel #1
0
        public static bool TryBindMethodCall(SyntaxTreeNode node, BindingContext bindingContext, TypeDescription expectedType, out Expression boundExpression, out Exception bindingError)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }
            if (bindingContext == null)
            {
                throw new ArgumentNullException("bindingContext");
            }
            if (expectedType == null)
            {
                throw new ArgumentNullException("expectedType");
            }

            // bindingError could return null from this method
            bindingError    = null;
            boundExpression = null;

            var methodNameNode     = node.GetExpression(throwOnError: true);
            var methodNameNodeType = methodNameNode.GetExpressionType(throwOnError: true);

            if (methodNameNodeType != Constants.EXPRESSION_TYPE_PROPERTY_OR_FIELD &&
                methodNameNodeType != Constants.EXPRESSION_TYPE_MEMBER_RESOLVE)
            {
                return(false);
            }
            var methodTargetNode = methodNameNode.GetExpression(throwOnError: false);
            var methodTarget     = default(Expression);

            var type          = default(Type);
            var typeReference = default(TypeReference);
            var isStatic      = false;

            if (methodTargetNode == null && bindingContext.Global != null)
            {
                methodTarget = bindingContext.Global;
                type         = methodTarget.Type;
                isStatic     = false;
            }
            else if (methodTargetNode == null)
            {
                var methodName = methodNameNode.GetMemberName(throwOnError: false);
                bindingError = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_UNABLETORESOLVENAME, methodName ?? "<unknown>"), node);
                return(false);
            }
            else if (BindingContext.TryGetTypeReference(methodTargetNode, out typeReference) && bindingContext.TryResolveType(typeReference, out type))
            {
                isStatic = true;
            }
            else if (AnyBinder.TryBind(methodTargetNode, bindingContext, TypeDescription.ObjectType, out methodTarget, out bindingError))
            {
                Debug.Assert(methodTarget != null, "methodTarget != null");

                isStatic = false;
                type     = methodTarget.Type;
            }
            else
            {
                if (typeReference != null && bindingError == null)
                {
                    bindingError = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_UNABLETORESOLVETYPE, typeReference), node);
                }
                return(false);
            }

            var methodRef = default(TypeReference);

            if (type == null || BindingContext.TryGetMethodReference(methodNameNode, out methodRef) == false)
            {
                return(false);
            }

            var typeDescription = TypeDescription.GetTypeDescription(type);

            foreach (var member in typeDescription.GetMembers(methodRef.Name))
            {
                if (member.IsMethod == false || member.IsStatic != isStatic)
                {
                    continue;
                }

                var callNode = new SyntaxTreeNode(new Dictionary <string, object>
                {
                    { Constants.EXPRESSION_ATTRIBUTE, methodTarget ?? (object)type },
                    { Constants.ARGUMENTS_ATTRIBUTE, node.GetValueOrDefault(Constants.ARGUMENTS_ATTRIBUTE, default(object)) },
                    { Constants.METHOD_ATTRIBUTE, methodRef },
                    { Constants.USE_NULL_PROPAGATION_ATTRIBUTE, methodNameNode.GetValueOrDefault(Constants.USE_NULL_PROPAGATION_ATTRIBUTE, default(object)) },
                    { Constants.EXPRESSION_POSITION, methodNameNode.GetPosition(throwOnError: false) }
                });

                return(CallBinder.TryBind(callNode, bindingContext, expectedType, out boundExpression, out bindingError));
            }

            return(false);
        }