private static void RenderInvokeOrIndex(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 target = syntaxTree.GetExpression(throwOnError: true); var arguments = syntaxTree.GetArguments(throwOnError: false); var useNullPropagation = syntaxTree.GetUseNullPropagation(throwOnError: false); Render(target, builder, false, checkedScope); builder.Append(expressionType == Constants.DELEGATE_INVOKE_NAME ? "(" : (useNullPropagation ? "?[" : "[")); RenderArguments(arguments, builder, checkedScope); builder.Append(expressionType == Constants.DELEGATE_INVOKE_NAME ? ")" : "]"); }
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(")"); } }
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 operandNode = node.GetExpression(throwOnError: true); var operand = default(Expression); var methodName = node.GetMethodName(throwOnError: false); var methodMember = default(MemberDescription); if (AnyBinder.TryBindInNewScope(operandNode, bindingContext, TypeDescription.ObjectType, out operand, out bindingError) == false) { return(false); } if (methodName != null) { bindingContext.TryResolveMember(methodName, out methodMember); } Debug.Assert(operand != null, "operand != null"); switch (expressionType) { case Constants.EXPRESSION_TYPE_NEGATE: if (ExpressionUtils.TryPromoteUnaryOperation(ref operand, ExpressionType.Negate, out boundExpression) == false) { // fixing b_u_g in mono expression compiler: Negate on float or double = exception if (operand.Type == typeof(double) || operand.Type == typeof(float)) { boundExpression = Expression.Multiply(operand, operand.Type == typeof(float) ? ExpressionUtils.NegativeSingle : ExpressionUtils.NegativeDouble); } else { boundExpression = Expression.Negate(operand, methodMember); } } break; case Constants.EXPRESSION_TYPE_NEGATE_CHECKED: if (ExpressionUtils.TryPromoteUnaryOperation(ref operand, ExpressionType.NegateChecked, out boundExpression) == false) { // fixing b_u_g in mono expression compiler: Negate on float or double = exception if (operand.Type == typeof(double) || operand.Type == typeof(float)) { boundExpression = Expression.Multiply(operand, operand.Type == typeof(float) ? ExpressionUtils.NegativeSingle : ExpressionUtils.NegativeDouble); } else { boundExpression = Expression.NegateChecked(operand, methodMember); } } break; case Constants.EXPRESSION_TYPE_COMPLEMENT: case Constants.EXPRESSION_TYPE_NOT: if (ExpressionUtils.TryPromoteUnaryOperation(ref operand, ExpressionType.Not, out boundExpression) == false) { boundExpression = Expression.Not(operand, methodMember); } break; case Constants.EXPRESSION_TYPE_UNARY_PLUS: if (ExpressionUtils.TryPromoteUnaryOperation(ref operand, ExpressionType.UnaryPlus, out boundExpression) == false) { boundExpression = Expression.UnaryPlus(operand, methodMember); } break; case Constants.EXPRESSION_TYPE_ARRAY_LENGTH: boundExpression = Expression.ArrayLength(operand); break; default: bindingError = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_UNKNOWNEXPRTYPE, expressionType), node); return(false); } return(true); }
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 left = node.GetLeftExpression(throwOnError: true); var right = node.GetRightExpression(throwOnError: true); var leftOperand = default(Expression); var rightOperand = default(Expression); if (AnyBinder.TryBindInNewScope(left, bindingContext, TypeDescription.ObjectType, out leftOperand, out bindingError) == false) { return(false); } if (AnyBinder.TryBindInNewScope(right, bindingContext, TypeDescription.ObjectType, out rightOperand, out bindingError) == false) { return(false); } Debug.Assert(leftOperand != null, "leftOperand != null"); Debug.Assert(rightOperand != null, "rightOperand != null"); switch (expressionType) { case Constants.EXPRESSION_TYPE_ADD: if (leftOperand.Type == typeof(string) || rightOperand.Type == typeof(string)) { boundExpression = Expression.Call ( StringConcat.Method, Expression.Convert(leftOperand, typeof(object)), Expression.Convert(rightOperand, typeof(object)) ); break; } else { if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.Add, out boundExpression) == false) { boundExpression = Expression.Add(leftOperand, rightOperand); } break; } case Constants.EXPRESSION_TYPE_ADD_CHECKED: if (leftOperand.Type == typeof(string) || rightOperand.Type == typeof(string)) { boundExpression = Expression.Call ( StringConcat.Method, Expression.Convert(leftOperand, typeof(object)), Expression.Convert(rightOperand, typeof(object)) ); break; } else { if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.AddChecked, out boundExpression) == false) { boundExpression = Expression.AddChecked(leftOperand, rightOperand); } break; } case Constants.EXPRESSION_TYPE_SUBTRACT: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.Subtract, out boundExpression) == false) { boundExpression = Expression.Subtract(leftOperand, rightOperand); } break; case Constants.EXPRESSION_TYPE_SUBTRACT_CHECKED: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.SubtractChecked, out boundExpression) == false) { boundExpression = Expression.SubtractChecked(leftOperand, rightOperand); } break; case Constants.EXPRESSION_TYPE_LEFTSHIFT: ExpressionUtils.TryPromoteUnaryOperation(ref leftOperand, ExpressionType.LeftShift, out boundExpression); ExpressionUtils.TryPromoteUnaryOperation(ref rightOperand, ExpressionType.LeftShift, out boundExpression); boundExpression = Expression.LeftShift(leftOperand, rightOperand); break; case Constants.EXPRESSION_TYPE_RIGHTSHIFT: ExpressionUtils.TryPromoteUnaryOperation(ref leftOperand, ExpressionType.RightShift, out boundExpression); ExpressionUtils.TryPromoteUnaryOperation(ref rightOperand, ExpressionType.RightShift, out boundExpression); boundExpression = Expression.RightShift(leftOperand, rightOperand); break; case Constants.EXPRESSION_TYPE_GREATERTHAN: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.GreaterThan, out boundExpression) == false) { boundExpression = Expression.GreaterThan(leftOperand, rightOperand); } break; case Constants.EXPRESSION_TYPE_GREATERTHAN_OR_EQUAL: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.GreaterThanOrEqual, out boundExpression) == false) { boundExpression = Expression.GreaterThanOrEqual(leftOperand, rightOperand); } break; case Constants.EXPRESSION_TYPE_LESSTHAN: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.LessThan, out boundExpression) == false) { boundExpression = Expression.LessThan(leftOperand, rightOperand); } break; case Constants.EXPRESSION_TYPE_LESSTHAN_OR_EQUAL: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.LessThanOrEqual, out boundExpression) == false) { boundExpression = Expression.LessThanOrEqual(leftOperand, rightOperand); } break; case Constants.EXPRESSION_TYPE_POWER: var resultType = TypeDescription.GetTypeDescription(leftOperand.Type); var resultTypeUnwrap = resultType.IsNullable ? resultType.UnderlyingType : resultType; if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.Power, out boundExpression) == false) { var operandsType = TypeDescription.GetTypeDescription(leftOperand.Type); var operandTypeUnwrap = operandsType.IsNullable ? operandsType.UnderlyingType : operandsType; var promoteToNullable = resultType.IsNullable || operandsType.IsNullable; if (operandTypeUnwrap != typeof(double) && leftOperand.Type == rightOperand.Type) { leftOperand = Expression.ConvertChecked(leftOperand, promoteToNullable ? typeof(double?) : typeof(double)); rightOperand = Expression.ConvertChecked(rightOperand, promoteToNullable ? typeof(double?) : typeof(double)); } boundExpression = Expression.Power(leftOperand, rightOperand); if (resultType != typeof(double)) { boundExpression = Expression.ConvertChecked(boundExpression, promoteToNullable ? resultTypeUnwrap.GetNullableType() : resultTypeUnwrap); } } break; case Constants.EXPRESSION_TYPE_DIVIDE: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.Divide, out boundExpression) == false) { boundExpression = Expression.Divide(leftOperand, rightOperand); } break; case Constants.EXPRESSION_TYPE_MULTIPLY: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.Multiply, out boundExpression) == false) { boundExpression = Expression.Multiply(leftOperand, rightOperand); } break; case Constants.EXPRESSION_TYPE_MULTIPLY_CHECKED: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.MultiplyChecked, out boundExpression) == false) { boundExpression = Expression.MultiplyChecked(leftOperand, rightOperand); } break; case Constants.EXPRESSION_TYPE_MODULO: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.Modulo, out boundExpression) == false) { boundExpression = Expression.Modulo(leftOperand, rightOperand); } break; case Constants.EXPRESSION_TYPE_EQUAL: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.Equal, out boundExpression) == false) { boundExpression = Expression.Equal(leftOperand, rightOperand); } break; case Constants.EXPRESSION_TYPE_NOTEQUAL: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.NotEqual, out boundExpression) == false) { boundExpression = Expression.NotEqual(leftOperand, rightOperand); } break; case Constants.EXPRESSION_TYPE_AND: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.And, out boundExpression) == false) { boundExpression = Expression.And(leftOperand, rightOperand); } break; case Constants.EXPRESSION_TYPE_OR: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.Or, out boundExpression) == false) { boundExpression = Expression.Or(leftOperand, rightOperand); } break; case Constants.EXPRESSION_TYPE_EXCLUSIVEOR: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.ExclusiveOr, out boundExpression) == false) { boundExpression = Expression.ExclusiveOr(leftOperand, rightOperand); } break; case Constants.EXPRESSION_TYPE_ANDALSO: boundExpression = Expression.AndAlso(leftOperand, rightOperand); break; case Constants.EXPRESSION_TYPE_ORELSE: boundExpression = Expression.OrElse(leftOperand, rightOperand); break; case Constants.EXPRESSION_TYPE_COALESCE: if (ExpressionUtils.TryPromoteBinaryOperation(ref leftOperand, ref rightOperand, ExpressionType.Coalesce, out boundExpression) == false) { boundExpression = Expression.Coalesce(leftOperand, rightOperand); } break; default: bindingError = new ExpressionParserException(string.Format(Properties.Resources.EXCEPTION_BIND_UNKNOWNEXPRTYPE, expressionType), node); return(false); } return(true); }
private static void RenderConstant(SyntaxTreeNode syntaxTree, StringBuilder builder) { if (syntaxTree == null) { throw new ArgumentNullException("syntaxTree"); } if (builder == null) { throw new ArgumentNullException("builder"); } var typeObj = default(object); var valueObj = default(object); if (syntaxTree.TryGetValue(Constants.TYPE_ATTRIBUTE, out typeObj) == false || typeObj is string == false) { throw new InvalidOperationException(string.Format(Properties.Resources.EXCEPTION_BIND_MISSINGATTRONNODE, Constants.TYPE_ATTRIBUTE, syntaxTree.GetExpressionType(throwOnError: true))); } if (syntaxTree.TryGetValue(Constants.VALUE_ATTRIBUTE, out valueObj) == false) { throw new InvalidOperationException(string.Format(Properties.Resources.EXCEPTION_BIND_MISSINGATTRONNODE, Constants.VALUE_ATTRIBUTE, syntaxTree.GetExpressionType(throwOnError: true))); } if (valueObj == null) { if (IsObjectType(typeObj)) { builder.Append("null"); return; } else { builder.Append("default("); RenderTypeName(typeObj, builder); builder.Append(")"); return; } } var type = Convert.ToString(typeObj, Constants.DefaultFormatProvider); var value = Convert.ToString(valueObj, Constants.DefaultFormatProvider) ?? ""; switch (type) { case "System.Char": case "Char": case "char": RenderTextLiteral(value, builder, isChar: true); break; case "System.String": case "String": case "string": RenderTextLiteral(value, builder, isChar: false); break; case "UInt16": case "System.UInt16": case "ushort": case "UInt32": case "System.UInt32": case "uint": builder.Append(value); builder.Append("u"); break; case "UInt64": case "System.UInt64": case "ulong": builder.Append(value); builder.Append("ul"); break; case "Int64": case "System.Int64": case "long": builder.Append(value); builder.Append("l"); break; case "Single": case "System.Single": case "float": builder.Append(value); builder.Append("f"); break; case "Double": case "System.Double": case "double": builder.Append(value); if (value.IndexOf('.') == -1) { builder.Append("d"); } break; case "Decimal": case "System.Decimal": case "decimal": builder.Append(value); builder.Append("m"); break; case "Boolean": case "System.Boolean": case "bool": builder.Append(value.ToLowerInvariant()); break; default: builder.Append(value); break; } }
private static void RenderBinary(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 leftObj = default(object); if (syntaxTree.TryGetValue(Constants.LEFT_ATTRIBUTE, out leftObj) == false || leftObj is SyntaxTreeNode == false) { throw new InvalidOperationException(string.Format(Properties.Resources.EXCEPTION_BIND_MISSINGATTRONNODE, Constants.LEFT_ATTRIBUTE, expressionType)); } var rightObj = default(object); if (syntaxTree.TryGetValue(Constants.RIGHT_ATTRIBUTE, out rightObj) == false || rightObj is SyntaxTreeNode == false) { throw new InvalidOperationException(string.Format(Properties.Resources.EXCEPTION_BIND_MISSINGATTRONNODE, Constants.RIGHT_ATTRIBUTE, expressionType)); } var left = (SyntaxTreeNode)leftObj; var right = (SyntaxTreeNode)rightObj; var checkedOperation = expressionType == Constants.EXPRESSION_TYPE_MULTIPLY_CHECKED || expressionType == Constants.EXPRESSION_TYPE_ADD_CHECKED || expressionType == Constants.EXPRESSION_TYPE_SUBTRACT_CHECKED ? true : expressionType == Constants.EXPRESSION_TYPE_MULTIPLY || expressionType == Constants.EXPRESSION_TYPE_ADD || expressionType == Constants.EXPRESSION_TYPE_SUBTRACT ? 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; } Render(left, builder, false, checkedOperation); switch (expressionType) { case Constants.EXPRESSION_TYPE_DIVIDE: builder.Append(" / "); break; case Constants.EXPRESSION_TYPE_MULTIPLY: case Constants.EXPRESSION_TYPE_MULTIPLY_CHECKED: builder.Append(" * "); break; case Constants.EXPRESSION_TYPE_MODULO: builder.Append(" % "); break; case Constants.EXPRESSION_TYPE_ADD_CHECKED: case Constants.EXPRESSION_TYPE_ADD: builder.Append(" + "); break; case Constants.EXPRESSION_TYPE_SUBTRACT: case Constants.EXPRESSION_TYPE_SUBTRACT_CHECKED: builder.Append(" - "); break; case Constants.EXPRESSION_TYPE_LEFT_SHIFT: builder.Append(" << "); break; case Constants.EXPRESSION_TYPE_RIGHT_SHIFT: builder.Append(" >> "); break; case Constants.EXPRESSION_TYPE_GREATER_THAN: builder.Append(" > "); break; case Constants.EXPRESSION_TYPE_GREATER_THAN_OR_EQUAL: builder.Append(" >= "); break; case Constants.EXPRESSION_TYPE_LESS_THAN: builder.Append(" < "); break; case Constants.EXPRESSION_TYPE_LESS_THAN_OR_EQUAL: builder.Append(" <= "); break; case Constants.EXPRESSION_TYPE_EQUAL: builder.Append(" == "); break; case Constants.EXPRESSION_TYPE_NOT_EQUAL: builder.Append(" != "); break; case Constants.EXPRESSION_TYPE_AND: builder.Append(" & "); break; case Constants.EXPRESSION_TYPE_OR: builder.Append(" | "); break; case Constants.EXPRESSION_TYPE_EXCLUSIVE_OR: builder.Append(" ^ "); break; case Constants.EXPRESSION_TYPE_POWER: builder.Append(" ** "); break; case Constants.EXPRESSION_TYPE_AND_ALSO: builder.Append(" && "); break; case Constants.EXPRESSION_TYPE_OR_ELSE: builder.Append(" || "); break; case Constants.EXPRESSION_TYPE_COALESCE: builder.Append(" ?? "); break; default: throw new InvalidOperationException(string.Format(Properties.Resources.EXCEPTION_BIND_UNKNOWNEXPRTYPE, expressionType)); } Render(right, builder, false, checkedOperation); if (closeParent) { builder.Append(")"); } }
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(")"); } }
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); }
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); } }
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); }