예제 #1
0
        private static bool TryBindToMethod(SyntaxTreeNode node, object methodName, ArgumentsTree arguments, BindingContext bindingContext, TypeDescription expectedType, out Expression boundExpression, out Exception bindingError)
        {
            boundExpression = null;
            bindingError    = null;

            var constructorDescription = default(MemberDescription);

            if (bindingContext.TryResolveMember(methodName, out constructorDescription) == false || constructorDescription.IsConstructor == false)
            {
                bindingError = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_UNABLETOBINDCONSTRUCTOR, methodName), node);
                return(false);
            }

            var typeDescription = TypeDescription.GetTypeDescription(constructorDescription.DeclaringType);

            // feature: lambda building via new Func()
            var lambdaArgument = default(SyntaxTreeNode);

            if (typeDescription.IsDelegate && arguments.Count == 1 && (lambdaArgument = arguments.Values.Single()).GetExpressionType(throwOnError: true) == Constants.EXPRESSION_TYPE_LAMBDA)
            {
                return(LambdaBinder.TryBind(lambdaArgument, bindingContext, typeDescription, out boundExpression, out bindingError));
            }

            var constructorQuality = MemberDescription.QUALITY_INCOMPATIBLE;

            if (constructorDescription.TryMakeCall(null, arguments, bindingContext, out boundExpression, out constructorQuality))
            {
                return(true);
            }

            bindingError = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_UNABLETOBINDCONSTRUCTOR, constructorDescription.DeclaringType), node);
            return(false);
        }
예제 #2
0
        private static bool TryBindToType(SyntaxTreeNode node, object typeName, ArgumentsTree arguments, BindingContext bindingContext, TypeDescription expectedType, out Expression boundExpression, out Exception bindingError)
        {
            boundExpression = null;
            bindingError    = null;

            var type = default(Type);

            if (bindingContext.TryResolveType(typeName, out type) == false)
            {
                bindingError = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_UNABLETORESOLVETYPE, typeName), node);
                return(false);
            }

            var typeDescription = TypeDescription.GetTypeDescription(type);

            // feature: lambda building via new Func()
            var lambdaArgument = default(SyntaxTreeNode);

            if (typeDescription.IsDelegate && arguments.Count == 1 && (lambdaArgument = arguments.Values.Single()).GetExpressionType(throwOnError: true) == Constants.EXPRESSION_TYPE_LAMBDA)
            {
                return(LambdaBinder.TryBind(lambdaArgument, bindingContext, typeDescription, out boundExpression, out bindingError));
            }

            var selectedConstructorQuality = MemberDescription.QUALITY_INCOMPATIBLE;

            foreach (var constructorDescription in typeDescription.Constructors)
            {
                var constructorQuality = MemberDescription.QUALITY_INCOMPATIBLE;
                var constructorCall    = default(Expression);
                if (constructorDescription.TryMakeCall(null, arguments, bindingContext, out constructorCall, out constructorQuality) == false)
                {
                    continue;
                }

                if (float.IsNaN(constructorQuality) || constructorQuality <= selectedConstructorQuality)
                {
                    continue;
                }

                boundExpression            = constructorCall;
                selectedConstructorQuality = constructorQuality;

                if (Math.Abs(constructorQuality - MemberDescription.QUALITY_EXACT_MATCH) < float.Epsilon)
                {
                    break;                     // best match
                }
            }

            if (boundExpression == null)
            {
                bindingError = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_UNABLETOBINDCONSTRUCTOR, type), node);
                return(false);
            }

            return(true);
        }
예제 #3
0
        public static bool TryBind(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");
            }

            try
            {
                var expressionType = node.GetExpressionType(throwOnError: true);
                switch (expressionType)
                {
                case Constants.EXPRESSION_TYPE_PROPERTY_OR_FIELD:
                    return(PropertyOrFieldBinder.TryBind(node, bindingContext, expectedType, out boundExpression, out bindingError));

                case Constants.EXPRESSION_TYPE_CONSTANT:
                    return(ConstantBinder.TryBind(node, bindingContext, expectedType, out boundExpression, out bindingError));

                case Constants.EXPRESSION_TYPE_CALL:
                    return(CallBinder.TryBind(node, bindingContext, expectedType, out boundExpression, out bindingError));

                case "Enclose":
                case Constants.EXPRESSION_TYPE_UNCHECKED_SCOPE:
                case Constants.EXPRESSION_TYPE_CHECKED_SCOPE:
                case Constants.EXPRESSION_TYPE_GROUP:
                    return(GroupBinder.TryBind(node, bindingContext, expectedType, out boundExpression, out bindingError));

                case Constants.EXPRESSION_TYPE_INVOKE:
                    return(InvokeBinder.TryBind(node, bindingContext, expectedType, out boundExpression, out bindingError));

                case Constants.EXPRESSION_TYPE_LAMBDA:
                    return(LambdaBinder.TryBind(node, bindingContext, expectedType, out boundExpression, out bindingError));

                case Constants.EXPRESSION_TYPE_INDEX:
                    return(IndexBinder.TryBind(node, bindingContext, expectedType, out boundExpression, out bindingError));

                case Constants.EXPRESSION_TYPE_TYPEOF:
                    return(TypeOfBinder.TryBind(node, bindingContext, expectedType, out boundExpression, out bindingError));

                case Constants.EXPRESSION_TYPE_CONVERT:
                case Constants.EXPRESSION_TYPE_CONVERTCHECKED:
                case Constants.EXPRESSION_TYPE_TYPEIS:
                case Constants.EXPRESSION_TYPE_TYPEAS:
                    return(TypeBinaryBinder.TryBind(node, bindingContext, expectedType, out boundExpression, out bindingError));

                case Constants.EXPRESSION_TYPE_DEFAULT:
                    return(DefaultBinder.TryBind(node, bindingContext, expectedType, out boundExpression, out bindingError));

                case Constants.EXPRESSION_TYPE_NEW:
                    return(NewBinder.TryBind(node, bindingContext, expectedType, out boundExpression, out bindingError));

                case Constants.EXPRESSION_TYPE_NEW_ARRAY_BOUNDS:
                    return(NewArrayBoundsBinder.TryBind(node, bindingContext, expectedType, out boundExpression, out bindingError));

                case Constants.EXPRESSION_TYPE_ADD:
                case Constants.EXPRESSION_TYPE_ADD_CHECKED:
                case Constants.EXPRESSION_TYPE_SUBTRACT:
                case Constants.EXPRESSION_TYPE_SUBTRACT_CHECKED:
                case Constants.EXPRESSION_TYPE_LEFTSHIFT:
                case Constants.EXPRESSION_TYPE_RIGHTSHIFT:
                case Constants.EXPRESSION_TYPE_GREATERTHAN:
                case Constants.EXPRESSION_TYPE_GREATERTHAN_OR_EQUAL:
                case Constants.EXPRESSION_TYPE_LESSTHAN:
                case Constants.EXPRESSION_TYPE_LESSTHAN_OR_EQUAL:
                case Constants.EXPRESSION_TYPE_POWER:
                case Constants.EXPRESSION_TYPE_DIVIDE:
                case Constants.EXPRESSION_TYPE_MULTIPLY:
                case Constants.EXPRESSION_TYPE_MULTIPLY_CHECKED:
                case Constants.EXPRESSION_TYPE_MODULO:
                case Constants.EXPRESSION_TYPE_EQUAL:
                case Constants.EXPRESSION_TYPE_NOTEQUAL:
                case Constants.EXPRESSION_TYPE_AND:
                case Constants.EXPRESSION_TYPE_OR:
                case Constants.EXPRESSION_TYPE_EXCLUSIVEOR:
                case Constants.EXPRESSION_TYPE_ANDALSO:
                case Constants.EXPRESSION_TYPE_ORELSE:
                case Constants.EXPRESSION_TYPE_COALESCE:
                    return(BinaryBinder.TryBind(node, bindingContext, expectedType, out boundExpression, out bindingError));

                case Constants.EXPRESSION_TYPE_NEGATE:
                case Constants.EXPRESSION_TYPE_NEGATE_CHECKED:
                case Constants.EXPRESSION_TYPE_COMPLEMENT:
                case Constants.EXPRESSION_TYPE_NOT:
                case Constants.EXPRESSION_TYPE_UNARYPLUS:
                    return(UnaryBinder.TryBind(node, bindingContext, expectedType, out boundExpression, out bindingError));

                case Constants.EXPRESSION_TYPE_CONDITION:
                    return(ConditionBinder.TryBind(node, bindingContext, expectedType, out boundExpression, out bindingError));

                default:
                    boundExpression = null;
                    bindingError    = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_UNKNOWNEXPRTYPE, expressionType), node);
                    return(false);
                }
            }
            catch (ExpressionParserException error)
            {
                boundExpression = null;
                bindingError    = error;
                return(false);
            }
            catch (Exception error)
            {
                boundExpression = null;
                bindingError    = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_FAILEDTOBIND, node.GetExpressionType(throwOnError: false) ?? "<unknown>", error.Message), error, node);
                return(false);
            }
        }