public static ExpressionNode AsOverload(ContextNode context, string name, ExpressionNode left, ExpressionNode right, SequencePoint point) { var methods = TypeUtils.GetOperatorMethods(context.Assembly, left, right, name); var args = Utils.Utils.Enumerate(left, right); var argsTypes = args.Select(a => a.ExpressionReturnType).ToList(); methods = methods.Where(m => MetadataHelpers.MatchesArgumentList(m, argsTypes)); var method = AssemblyRegistry.GetCompatibleMethod(methods, argsTypes); if (method != null) { return(MethodCallNode.Create(context, new MethodNode(method, null, context, point), args, point)); } else { if (methods.Count() == 0) { return(null); } else { ErrorCode.TypeMismatch.ReportAndThrow(point, "Overloaded operator {0} for operands {1} and {2} is ambiguous", name, left.ExpressionReturnType.FullName, right.ExpressionReturnType.FullName); return(null);//unreachable } } }
private static ExpressionNode CreateOverload(ContextNode context, ExpressionNode expression, InternalUnaryOperatorType op, MethodReference method) { var point = expression.SequencePoint; if (IsIncrementDecrement(op)) { TypeUtils.VerifyAccessible(method, context.GetClass().TypeReference, point); return(new IncrementDecrementOperatorNode(op, expression, method)); } else { return(MethodCallNode.Create(context, new MethodNode(method, null, context, point), expression.Enumerate(), point)); } }
private static ExpressionNode ParseSuffix(ContextNode context, IAbstractSyntaxTree lexerNode) { var opType = lexerNode.Children[1].Type; switch (opType) { case Lexer.TokenType.PlusPlus: return(Create(context, ExpressionNode.Parse(context, lexerNode.Children[0]), InternalUnaryOperatorType.PostIncrement)); case Lexer.TokenType.MinusMinus: return(Create(context, ExpressionNode.Parse(context, lexerNode.Children[0]), InternalUnaryOperatorType.PostDecrement)); case Lexer.TokenType.FunctionArgumentsList: return(MethodCallNode.Parse(context, lexerNode)); case Lexer.TokenType.IndexNode: return(ArrayAccessNode.Parse(context, lexerNode)); default: ContractsHelper.AssertUnreachable("Unknown postfix op {0}", opType); return(null); //unreachable } }