public static bool TryGetTranslation(DynamicTranslationArgs args, out ITranslation translation)
            {
                if (!args.IsMatch(_matcher, out var match))
                {
                    translation = null;
                    return(false);
                }

                var subjectObject      = args.FirstArgument;
                var subjectTranslation = args.Context.GetTranslationFor(subjectObject);
                var methodName         = match.Groups["MethodName"].Value;
                var methodInfo         = subjectObject.Type.GetPublicMethod(methodName);
                var methodArguments    = args.Arguments.Skip(1).ToArray();

                var method = GetMethod(
                    methodName,
                    methodInfo,
                    methodArguments,
                    args.ExpressionType);

                translation = MethodCallTranslation.ForDynamicMethodCall(
                    subjectTranslation,
                    method,
                    methodArguments,
                    args.Context);

                return(true);
            }
Exemple #2
0
        public static ITranslation For(UnaryExpression cast, ITranslationContext context)
        {
            var castValueTranslation = context.GetTranslationFor(cast.Operand);

            switch (cast.NodeType)
            {
            case ExpressionType.Convert:
            case ConvertChecked:
                if (cast.Type == typeof(object))
                {
                    // Don't bother to show a boxing cast:
                    return(castValueTranslation);
                }

                if (cast.Method != null)
                {
                    var isImplicitOperator = cast.Method.IsImplicitOperator();

                    if (isImplicitOperator)
                    {
                        return(castValueTranslation.ShouldWriteInParentheses()
                                ? castValueTranslation.WithParentheses()
                                : castValueTranslation);
                    }

                    if (cast.Method.IsExplicitOperator())
                    {
                        break;
                    }

                    return(MethodCallTranslation.ForCustomMethodCast(
                               context.GetTranslationFor(cast.Type),
                               new BclMethodWrapper(cast.Method),
                               castValueTranslation,
                               context));
                }

                if (IsDelegateCast(cast, out var createDelegateCall))
                {
                    return(MethodGroupTranslation.ForCreateDelegateCall(cast.NodeType, createDelegateCall, context));
                }

                break;

            case TypeAs:
                return(new TypeTestedTranslation(TypeAs, castValueTranslation, " as ", cast.Type, context));
            }

            return(new StandardCastTranslation(cast, castValueTranslation, context));
        }
        public ITranslation GetTranslationFor(Expression expression)
        {
            if (expression == null)
            {
                return(null);
            }

            switch (expression.NodeType)
            {
            case Decrement:
            case Increment:
            case IsFalse:
            case IsTrue:
            case OnesComplement:
            case PostDecrementAssign:
            case PostIncrementAssign:
            case PreDecrementAssign:
            case PreIncrementAssign:
            case UnaryPlus:
                return(new UnaryTranslation((UnaryExpression)expression, this));

            case Add:
            case AddChecked:
            case And:
            case AndAlso:
            case Coalesce:
            case Divide:
            case Equal:
            case ExclusiveOr:
            case GreaterThan:
            case GreaterThanOrEqual:
            case LeftShift:
            case LessThan:
            case LessThanOrEqual:
            case Modulo:
            case Multiply:
            case MultiplyChecked:
            case NotEqual:
            case Or:
            case OrElse:
            case Power:
            case RightShift:
            case Subtract:
            case SubtractChecked:
                return(BinaryTranslation.For((BinaryExpression)expression, this));

            case AddAssign:
            case AddAssignChecked:
            case AndAssign:
            case Assign:
            case DivideAssign:
            case ExclusiveOrAssign:
            case LeftShiftAssign:
            case ModuloAssign:
            case MultiplyAssign:
            case MultiplyAssignChecked:
            case OrAssign:
            case PowerAssign:
            case RightShiftAssign:
            case SubtractAssign:
            case SubtractAssignChecked:
                return(new AssignmentTranslation((BinaryExpression)expression, this));

            case ArrayIndex:
                return(new IndexAccessTranslation((BinaryExpression)expression, this));

            case ArrayLength:
                return(new ArrayLengthTranslation((UnaryExpression)expression, this));

            case Block:
                return(new BlockTranslation((BlockExpression)expression, this));

            case Call:
                return(MethodCallTranslation.For((MethodCallExpression)expression, this));

            case Conditional:
                return(ConditionalTranslation.For((ConditionalExpression)expression, this));

            case Constant:
                return(ConstantTranslation.For((ConstantExpression)expression, this));

            case ExpressionType.Convert:
            case ConvertChecked:
            case TypeAs:
            case Unbox:
                return(CastTranslation.For((UnaryExpression)expression, this));

            case DebugInfo:
                return(DebugInfoTranslation.For((DebugInfoExpression)expression, this));

            case Default:
                return(new DefaultValueTranslation(expression, this));

            case Dynamic:
                return(DynamicTranslation.For((DynamicExpression)expression, this));

            case Extension:
                return(new FixedValueTranslation(expression, this));

            case Goto:
                return(GotoTranslation.For((GotoExpression)expression, this));

            case Index:
                return(new IndexAccessTranslation((IndexExpression)expression, this));

            case Invoke:
                return(MethodCallTranslation.For((InvocationExpression)expression, this));

            case Label:
                return(new LabelTranslation((LabelExpression)expression, this));

            case Lambda:
                return(new LambdaTranslation((LambdaExpression)expression, this));

            case ListInit:
                return(ListInitialisationTranslation.For((ListInitExpression)expression, this));

            case Loop:
                return(new LoopTranslation((LoopExpression)expression, this));

            case MemberAccess:
                return(new MemberAccessTranslation((MemberExpression)expression, this));

            case MemberInit:
                return(MemberInitialisationTranslation.For((MemberInitExpression)expression, this));

            case Negate:
            case NegateChecked:
            case Not:
                return(new NegationTranslation((UnaryExpression)expression, this));

            case New:
                return(NewingTranslation.For((NewExpression)expression, this));

            case NewArrayBounds:
                return(new NewArrayTranslation((NewArrayExpression)expression, this));

            case NewArrayInit:
                return(ArrayInitialisationTranslation.For((NewArrayExpression)expression, this));

            case Parameter:
                return(ParameterTranslation.For((ParameterExpression)expression, this));

            case Quote:
                return(QuotedLambdaTranslation.For((UnaryExpression)expression, this));

            case RuntimeVariables:
                return(RuntimeVariablesTranslation.For((RuntimeVariablesExpression)expression, this));

            case Switch:
                return(new SwitchTranslation((SwitchExpression)expression, this));

            case Throw:
                return(new ThrowTranslation((UnaryExpression)expression, this));

            case Try:
                return(new TryCatchTranslation((TryExpression)expression, this));

            case TypeEqual:
                return(TypeEqualTranslation.For((TypeBinaryExpression)expression, this));

            case TypeIs:
                return(CastTranslation.For((TypeBinaryExpression)expression, this));
            }

            return(new FixedValueTranslation(expression, this));
        }