public override DynamicMetaObject FallbackGetIndex(DynamicMetaObject target, DynamicMetaObject[] indexes, DynamicMetaObject errorSuggestion)
        {
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }
            if (indexes == null)
            {
                throw new ArgumentNullException(nameof(indexes));
            }

            if (!target.HasValue || indexes.Any(x => !x.HasValue))
            {
                return(Defer(target, indexes));
            }

            if (target.Value == null)
            {
                return(BinderHelper.NullTargetResult(target, errorSuggestion));
            }

            var index        = _indexerResolver.ReadableIndexer(target, indexes);
            var restrictions = BinderHelper.CreateCommonRestrictions(target, indexes);

            if (index == null)
            {
                return(BinderHelper.UnresolveableResult(restrictions, errorSuggestion));
            }

            return(new DynamicMetaObject(VelocityExpressions.ConvertIfNeeded(index, ReturnType), restrictions));
        }
Пример #2
0
        public override DynamicMetaObject FallbackInvokeMember(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
        {
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }
            if (args == null)
            {
                throw new ArgumentNullException(nameof(args));
            }

            if (!target.HasValue || args.Any(x => !x.HasValue))
            {
                return(Defer(target, args));
            }

            if (target == null)
            {
                return(BinderHelper.NullTargetResult(target, errorSuggestion));
            }


            // If an argument has a null value, use a null type so that the resolution algorithm can do implicit null conversions
            var argTypes = args.Select(x => x.Value == null ? null : x.RuntimeType).ToImmutableList();

            OverloadResolutionData <MethodInfo> method = _methodResolver.ResolveMethod(target.LimitType.GetTypeInfo(), Name, argTypes);

            var restrictions = BinderHelper.CreateCommonRestrictions(target, args);

            if (method == null)
            {
                var log = BindingEventSource.Log;
                if (log.IsEnabled())
                {
                    var argTypeString = string.Join(",", argTypes.Select(x => x.FullName).ToArray());
                    log.InvokeMemberResolutionFailure(Name, target.LimitType.FullName, argTypeString);
                }

                return(BinderHelper.UnresolveableResult(restrictions, errorSuggestion));
            }

            var methodExpression = _methodResolver.ConvertMethodParameters(method, target.Expression, args);

            return(new DynamicMetaObject(
                       VelocityExpressions.ConvertIfNeeded(methodExpression, ReturnType),
                       restrictions
                       ));
        }
        public override DynamicMetaObject FallbackSetMember(DynamicMetaObject target, DynamicMetaObject value, DynamicMetaObject errorSuggestion)
        {
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }
            if (value == null)
            {
                throw new ArgumentNullException(nameof(target));
            }

            if (!target.HasValue || !value.HasValue)
            {
                return(Defer(target, value));
            }

            if (target.Value == null)
            {
                return(BinderHelper.NullTargetResult(target, errorSuggestion));
            }
            if (value.Value == null)
            {
                return(BinderHelper.SetNullValue(this, value));
            }


            var memberAccess = _memberResolver.MemberExpression(Name, target, MemberAccessMode.Write);

            var restrictions = BinderHelper.CreateCommonRestrictions(target);

            if (memberAccess == null || !memberAccess.Type.IsAssignableFrom(value.RuntimeType))
            {
                BindingEventSource.Log.SetMemberResolutionFailure(Name, target.RuntimeType.FullName, value.RuntimeType.FullName);
                return(BinderHelper.UnresolveableResult(restrictions, errorSuggestion));
            }

            var result = VelocityExpressions.BoxIfNeeded(
                Expression.Assign(
                    memberAccess,
                    VelocityExpressions.ConvertIfNeeded(value, memberAccess.Type)
                    )
                );

            return(new DynamicMetaObject(result, restrictions));
        }
Пример #4
0
        public override DynamicMetaObject FallbackSetIndex(DynamicMetaObject target, DynamicMetaObject[] indexes, DynamicMetaObject value, DynamicMetaObject errorSuggestion)
        {
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }
            if (indexes == null)
            {
                throw new ArgumentNullException(nameof(indexes));
            }
            if (indexes == null)
            {
                throw new ArgumentNullException(nameof(indexes));
            }

            if (!target.HasValue || !value.HasValue || indexes.Any(x => !x.HasValue))
            {
                return(Defer(target, indexes.Concat(new[] { value }).ToArray()));
            }

            if (target.Value == null)
            {
                return(BinderHelper.NullTargetResult(target, errorSuggestion));
            }
            if (value.Value == null)
            {
                return(BinderHelper.SetNullValue(this, value));
            }

            var restrictions = BinderHelper.CreateCommonRestrictions(target, indexes)
                               .Merge(BinderHelper.CreateCommonRestrictions(value));

            var index = _indexerResolver.WriteableIndexer(target, indexes);

            if (index == null || !index.Type.IsAssignableFrom(value.RuntimeType))
            {
                return(BinderHelper.UnresolveableResult(restrictions, errorSuggestion));
            }

            var assignment = Expression.Assign(index, VelocityExpressions.ConvertIfNeeded(value.Expression, index.Type));

            return(new DynamicMetaObject(VelocityExpressions.ConvertIfNeeded(assignment, ReturnType), restrictions));
        }
Пример #5
0
        public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
        {
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }

            if (!target.HasValue)
            {
                return(Defer(target));
            }

            if (target.Value == null)
            {
                return(BinderHelper.NullTargetResult(target, errorSuggestion));
            }

            Expression result       = null;
            var        restrictions = BinderHelper.CreateCommonRestrictions(target);

            try
            {
                result = _memberResolver.MemberExpression(Name, target, MemberAccessMode.Read);
            }
            catch (AmbiguousMatchException)
            {
                BindingEventSource.Log.GetMemberResolutionAmbiguous(Name, target.RuntimeType.FullName);
                return(BinderHelper.UnresolveableResult(restrictions, errorSuggestion));
            }


            if (result == null)
            {
                BindingEventSource.Log.GetMemberResolutionFailure(Name, target.RuntimeType.FullName);
                return(BinderHelper.UnresolveableResult(restrictions, errorSuggestion));
            }

            return(new DynamicMetaObject(
                       VelocityExpressions.ConvertIfNeeded(result, ReturnType),
                       restrictions
                       ));
        }
Пример #6
0
        public override DynamicMetaObject FallbackBinaryOperation(DynamicMetaObject target, DynamicMetaObject arg, DynamicMetaObject errorSuggestion)
        {
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }
            if (arg == null)
            {
                throw new ArgumentNullException(nameof(arg));
            }

            if (!target.HasValue || !arg.HasValue)
            {
                return(Defer(target, arg));
            }

            DynamicMetaObject result;

            switch (Operation)
            {
            case ExpressionType.Add:
                result = AddSubtractMultiply(VelocityOperator.Add, target, arg);
                break;

            case ExpressionType.Subtract:
                result = AddSubtractMultiply(VelocityOperator.Subtract, target, arg);
                break;

            case ExpressionType.Multiply:
                result = AddSubtractMultiply(VelocityOperator.Multiply, target, arg);
                break;

            case ExpressionType.Divide:
                result = Division(VelocityOperator.Divide, target, arg);
                break;

            case ExpressionType.Modulo:
                result = Division(VelocityOperator.Modulo, target, arg);
                break;

            case ExpressionType.Equal:
                result = Equality(VelocityOperator.Equal, target, arg, errorSuggestion);
                break;

            case ExpressionType.NotEqual:
                result = Equality(VelocityOperator.NotEqual, target, arg, errorSuggestion);
                break;

            case ExpressionType.GreaterThan:
                result = Relational(VelocityOperator.GreaterThan, target, arg, errorSuggestion);
                break;

            case ExpressionType.GreaterThanOrEqual:
                result = Relational(VelocityOperator.GreaterThanOrEqual, target, arg, errorSuggestion);
                break;

            case ExpressionType.LessThan:
                result = Relational(VelocityOperator.LessThan, target, arg, errorSuggestion);
                break;

            case ExpressionType.LessThanOrEqual:
                result = Relational(VelocityOperator.LessThanOrEqual, target, arg, errorSuggestion);
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(Operation));
            }

            if (result == null)
            {
                var restrictions = BinderHelper.CreateCommonRestrictions(target, arg);
                BindingEventSource.Log.BinaryOperationResolutionFailure(Operation, target.LimitType.FullName, arg.LimitType.FullName);
                result = BinderHelper.UnresolveableResult(restrictions, errorSuggestion);
            }
            return(result);
        }