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); }
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); }
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(")"); }
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(")"); } }
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(")"); } }
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"); } 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); }
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); }