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