Exemplo n.º 1
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");
            }

            boundExpression = null;
            bindingError    = null;

            var valueObj = node.GetValue(throwOnError: true);
            var typeName = node.GetTypeName(throwOnError: true);
            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 value = ChangeType(valueObj, type);

            boundExpression = Expression.Constant(value);
            return(true);
        }
Exemplo n.º 2
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");
            }


            if (node == null)
            {
                throw new ArgumentNullException("node");
            }

            var arguments  = node.GetArguments(throwOnError: false);
            var methodName = node.GetMethodName(throwOnError: false);

            if (methodName != null)
            {
                return(TryBindToMethod(node, methodName, arguments, bindingContext, expectedType, out boundExpression, out bindingError));
            }
            else
            {
                var typeName = node.GetTypeName(throwOnError: true);
                return(TryBindToType(node, typeName, arguments, bindingContext, expectedType, out boundExpression, out bindingError));
            }
        }
        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");
            }

            boundExpression = null;
            bindingError    = null;

            var typeName = node.GetTypeName(throwOnError: true);
            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 indexTypeDescription = TypeDescription.Int32Type;
            var arguments            = node.GetArguments(throwOnError: true);
            var argumentExpressions  = new Expression[arguments.Count];

            for (var i = 0; i < arguments.Count; i++)
            {
                var argument = default(SyntaxTreeNode);
                if (arguments.TryGetValue(i, out argument) == false)
                {
                    bindingError = new ExpressionParserException(Properties.Resources.EXCEPTION_BOUNDEXPR_ARGSDOESNTMATCHPARAMS, node);
                    return(false);
                }

                if (AnyBinder.TryBindInNewScope(argument, bindingContext, indexTypeDescription, out argumentExpressions[i], out bindingError) == false)
                {
                    return(false);
                }

                Debug.Assert(argumentExpressions[i] != null, "argumentExpressions[i] != null");
            }

            boundExpression = Expression.NewArrayBounds(type, argumentExpressions);
            return(true);
        }
Exemplo n.º 4
0
        private static void RenderTypeOf(SyntaxTreeNode syntaxTree, StringBuilder builder)
        {
            if (syntaxTree == null)
            {
                throw new ArgumentNullException("syntaxTree");
            }
            if (builder == null)
            {
                throw new ArgumentNullException("builder");
            }

            var typeName = syntaxTree.GetTypeName(throwOnError: true);

            builder.Append("typeof(");
            RenderTypeName(typeName, builder);
            builder.Append(")");
        }
Exemplo n.º 5
0
        private static void RenderNew(SyntaxTreeNode syntaxTree, StringBuilder builder, bool checkedScope)
        {
            if (syntaxTree == null)
            {
                throw new ArgumentNullException("syntaxTree");
            }
            if (builder == null)
            {
                throw new ArgumentNullException("builder");
            }

            var expressionType = syntaxTree.GetExpressionType(throwOnError: true);
            var typeName       = syntaxTree.GetTypeName(throwOnError: true);
            var arguments      = syntaxTree.GetArguments(throwOnError: false);

            builder.Append("new ");
            RenderTypeName(typeName, builder);
            if (expressionType == Constants.EXPRESSION_TYPE_NEW_ARRAY_BOUNDS)
            {
                builder.Append("[");
            }
            else
            {
                builder.Append("(");
            }

            RenderArguments(arguments, builder, checkedScope);

            if (expressionType == Constants.EXPRESSION_TYPE_NEW_ARRAY_BOUNDS)
            {
                builder.Append("]");
            }
            else
            {
                builder.Append(")");
            }
        }
Exemplo n.º 6
0
        private static void RenderCondition(SyntaxTreeNode syntaxTree, StringBuilder builder, bool wrapped, bool checkedScope)
        {
            if (syntaxTree == null)
            {
                throw new ArgumentNullException("syntaxTree");
            }
            if (builder == null)
            {
                throw new ArgumentNullException("builder");
            }

            var testObj = default(object);

            if (syntaxTree.TryGetValue(Constants.TEST_ATTRIBUTE, out testObj) == false || testObj is SyntaxTreeNode == false)
            {
                throw new InvalidOperationException(string.Format(Properties.Resources.EXCEPTION_BIND_MISSINGATTRONNODE, Constants.TEST_ATTRIBUTE, syntaxTree.GetTypeName(throwOnError: true)));
            }

            var ifTrueObj = default(object);

            if (syntaxTree.TryGetValue(Constants.IF_TRUE_ATTRIBUTE, out ifTrueObj) == false || ifTrueObj is SyntaxTreeNode == false)
            {
                throw new InvalidOperationException(string.Format(Properties.Resources.EXCEPTION_BIND_MISSINGATTRONNODE, Constants.IF_TRUE_ATTRIBUTE, syntaxTree.GetTypeName(throwOnError: true)));
            }

            var ifFalseObj = default(object);

            if (syntaxTree.TryGetValue(Constants.IF_FALSE_ATTRIBUTE, out ifFalseObj) == false || ifFalseObj is SyntaxTreeNode == false)
            {
                throw new InvalidOperationException(string.Format(Properties.Resources.EXCEPTION_BIND_MISSINGATTRONNODE, Constants.IF_FALSE_ATTRIBUTE, syntaxTree.GetTypeName(throwOnError: true)));
            }

            var test    = (SyntaxTreeNode)testObj;
            var ifTrue  = (SyntaxTreeNode)ifTrueObj;
            var ifFalse = (SyntaxTreeNode)ifFalseObj;

            if (!wrapped)
            {
                builder.Append("(");
            }
            Render(test, builder, true, checkedScope);
            builder.Append(" ? ");
            Render(ifTrue, builder, true, checkedScope);
            builder.Append(" : ");
            Render(ifFalse, builder, true, checkedScope);
            if (!wrapped)
            {
                builder.Append(")");
            }
        }
Exemplo n.º 7
0
        private static void RenderTypeBinary(SyntaxTreeNode syntaxTree, StringBuilder builder, bool wrapped, bool checkedScope)
        {
            if (syntaxTree == null)
            {
                throw new ArgumentNullException("syntaxTree");
            }
            if (builder == null)
            {
                throw new ArgumentNullException("builder");
            }

            var expressionType = syntaxTree.GetExpressionType(throwOnError: true);
            var typeName       = syntaxTree.GetTypeName(throwOnError: true);
            var target         = syntaxTree.GetExpression(throwOnError: true);

            var checkedOperation = expressionType == Constants.EXPRESSION_TYPE_CONVERT_CHECKED ? true :
                                   expressionType == Constants.EXPRESSION_TYPE_CONVERT ? false : checkedScope;

            var closeParent = false;

            if (checkedOperation && !checkedScope)
            {
                builder.Append("checked(");
                checkedScope = true;
                closeParent  = true;
            }
            else if (!checkedOperation && checkedScope)
            {
                builder.Append("unchecked(");
                checkedScope = false;
                closeParent  = true;
            }
            else if (!wrapped)
            {
                builder.Append("(");
                closeParent = true;
            }

            switch (expressionType)
            {
            case Constants.EXPRESSION_TYPE_CONVERT:
            case Constants.EXPRESSION_TYPE_CONVERT_CHECKED:
                builder.Append("(");
                RenderTypeName(typeName, builder);
                builder.Append(")");
                Render(target, builder, false, checkedOperation);
                break;

            case Constants.EXPRESSION_TYPE_TYPE_IS:
                Render(target, builder, false, checkedScope);
                builder.Append(" is ");
                RenderTypeName(typeName, builder);
                break;

            case Constants.EXPRESSION_TYPE_TYPE_AS:
                Render(target, builder, false, checkedScope);
                builder.Append(" as ");
                RenderTypeName(typeName, builder);
                break;

            default: throw new InvalidOperationException(string.Format(Properties.Resources.EXCEPTION_BIND_UNKNOWNEXPRTYPE, expressionType));
            }

            if (closeParent)
            {
                builder.Append(")");
            }
        }
Exemplo n.º 8
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");
            }

            boundExpression = null;
            bindingError    = null;

            // try get type of lambda from node
            var lambdaTypeName = node.GetTypeName(throwOnError: false);
            var lambdaType     = default(Type);

            if (lambdaTypeName != null)
            {
                if (bindingContext.TryResolveType(lambdaTypeName, out lambdaType) == false)
                {
                    bindingError = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_UNABLETORESOLVETYPE, lambdaTypeName), node);
                    return(false);
                }
                else
                {
                    expectedType = TypeDescription.GetTypeDescription(lambdaType);
                }
            }

            if (expectedType.HasGenericParameters || !expectedType.IsDelegate)
            {
                bindingError = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_VALIDDELEGATETYPEISEXPECTED, expectedType.ToString()));
                return(false);
            }

            var expressionType     = node.GetExpressionType(throwOnError: true);
            var bodyNode           = node.GetExpression(throwOnError: true);
            var argumentsTree      = node.GetArguments(throwOnError: false);
            var lambdaInvokeMethod = expectedType.GetMembers(Constants.DELEGATE_INVOKE_NAME).FirstOrDefault(m => m.IsMethod && !m.IsStatic);

            if (lambdaInvokeMethod == null)
            {
                bindingError = new MissingMethodException(string.Format(Resources.EXCEPTION_BIND_MISSINGMETHOD, expectedType.ToString(), Constants.DELEGATE_INVOKE_NAME));
                return(false);
            }

            if (lambdaInvokeMethod.GetParametersCount() != argumentsTree.Count)
            {
                bindingError = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_INVALIDLAMBDAARGUMENTS, expectedType));
                return(false);
            }

            var argumentNames = new string[argumentsTree.Count];

            for (var i = 0; i < argumentNames.Length; i++)
            {
                var argumentNameTree     = default(SyntaxTreeNode);
                var argumentNameTreeType = default(string);
                if (argumentsTree.TryGetValue(i, out argumentNameTree) == false ||
                    argumentNameTree == null ||
                    (argumentNameTreeType = argumentNameTree.GetExpressionType(throwOnError: true)) == null ||
                    (argumentNameTreeType == Constants.EXPRESSION_TYPE_PROPERTY_OR_FIELD ||
                     argumentNameTreeType == Constants.EXPRESSION_TYPE_MEMBER_RESOLVE ||
                     argumentNameTreeType == Constants.EXPRESSION_TYPE_PARAMETER) == false)
                {
                    bindingError = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_MISSINGATTRONNODE, Constants.EXPRESSION_ATTRIBUTE, expressionType), node);
                    return(false);
                }
                argumentNames[i] = argumentNameTree.GetMemberName(throwOnError: true);
            }

            var lambdaParameters = new ParameterExpression[argumentsTree.Count];

            for (var i = 0; i < argumentsTree.Count; i++)
            {
                lambdaParameters[i] = Expression.Parameter(lambdaInvokeMethod.GetParameter(i).ParameterType, argumentNames[i]);
            }

            var currentParameters = bindingContext.Parameters;
            var newParameters     = new List <ParameterExpression>(lambdaParameters.Length + currentParameters.Count);

            // add all lambda's parameters
            newParameters.AddRange(lambdaParameters);
            // add closure parameters
            foreach (var parameterExpr in currentParameters)
            {
                if (Array.IndexOf(argumentNames, parameterExpr.Name) < 0)
                {
                    newParameters.Add(parameterExpr);
                }
            }

            var nestedBindingContext = bindingContext.CreateNestedContext(newParameters.AsReadOnly(), lambdaInvokeMethod.ResultType);
            var body = default(Expression);

            if (AnyBinder.TryBindInNewScope(bodyNode, nestedBindingContext, TypeDescription.GetTypeDescription(lambdaInvokeMethod.ResultType), out body, out bindingError) == false)
            {
                return(false);
            }

            Debug.Assert(body != null, "body != null");

            boundExpression = Expression.Lambda(expectedType, body, lambdaParameters);
            return(true);
        }
Exemplo n.º 9
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");
            }

            boundExpression = null;
            bindingError    = null;

            var expressionType = node.GetExpressionType(throwOnError: true);
            var targetNode     = node.GetExpression(throwOnError: true);
            var typeName       = node.GetTypeName(throwOnError: true);
            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 target = default(Expression);

            if (AnyBinder.TryBindInNewScope(targetNode, bindingContext, TypeDescription.ObjectType, out target, out bindingError) == false)
            {
                return(false);
            }

            Debug.Assert(target != null, "target != null");

            switch (expressionType)
            {
            case Constants.EXPRESSION_TYPE_TYPE_IS:
                boundExpression = Expression.TypeIs(target, type);
                break;

            case Constants.EXPRESSION_TYPE_TYPE_AS:
                boundExpression = Expression.TypeAs(target, type);
                break;

            case Constants.EXPRESSION_TYPE_CONVERT:
                boundExpression = Expression.Convert(target, type);
                break;

            case Constants.EXPRESSION_TYPE_CONVERT_CHECKED:
                boundExpression = Expression.ConvertChecked(target, type);
                break;

            default:
                boundExpression = null;
                bindingError    = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_UNKNOWNEXPRTYPE, expressionType), node);
                return(false);
            }
            return(true);
        }
Exemplo n.º 10
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");
            }

            boundExpression = null;
            bindingError    = null;

            if (node == null)
            {
                throw new ArgumentNullException("node");
            }

            var arguments = node.GetArguments(throwOnError: false);
            var typeName  = node.GetTypeName(throwOnError: true);
            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);
        }