예제 #1
0
        public override DynamicMetaObject FallbackCreateInstance(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
        {
            BindingRestrictions restrictions;
            if (target.Value is HappyTypeTracker)
            {
                HappyTypeTracker tracker = (HappyTypeTracker)target.Value;
                OverloadResolver or = _languageContext.OverloadResolverFactory.CreateOverloadResolver(args, new CallSignature(args.Length), CallTypes.None);

                if(tracker.Constructors.Length == 0)
                    return errorSuggestion ??
                        RuntimeHelpers.CreateThrow(target, args, BindingRestrictions.GetInstanceRestriction(target.Expression, target.Value),
                            typeof(MissingMemberException), String.Format(RuntimeMessages.NoConstructorsFound_TypeName, tracker.FullName));

                BindingTarget bt = or.ResolveOverload(tracker.FullName, tracker.Constructors, NarrowingLevel.None, NarrowingLevel.All);

                restrictions = BindingRestrictions.Combine(args);
                if (!bt.Success)
                {
                    restrictions = args.Aggregate(restrictions, (current, mo) => current.Merge(BindingRestrictions.GetTypeRestriction(mo.Expression, mo.GetLimitType())));

                    return DefaultBinder.MakeError(or.MakeInvalidParametersError(bt), restrictions, typeof (object));
                }

                restrictions = BindingRestrictions.GetInstanceRestriction(target.Expression, tracker);
                restrictions.Merge(bt.RestrictedArguments.GetAllRestrictions());
                Expression callExpression = bt.MakeExpression();

                if (callExpression.Type == typeof (void))
                    callExpression = Expression.Block(new[] {callExpression, Expression.Constant(null)});
                else if (callExpression.Type != typeof (object))
                    callExpression = Expression.Convert(callExpression, typeof (object));

                return new DynamicMetaObject(callExpression, restrictions);
            }

            return errorSuggestion ??
                RuntimeHelpers.CreateThrow(target, args, null, typeof(MissingMemberException),
                    RuntimeMessages.FirstArgumentToNewMustBeInstanceOfSystemType);

            //// Defer if any object has no value so that we evaulate their
            //// Expressions and nest a CallSite for the InvokeMember.
            //if (!target.HasValue || args.Any((a) => !a.HasValue))
            //{
            //    var deferArgs = new DynamicMetaObject[args.Length + 1];
            //    for (int i = 0; i < args.Length; i++)
            //    {
            //        deferArgs[i + 1] = args[i];
            //    }
            //    deferArgs[0] = target;
            //    return Defer(deferArgs);
            //}
            //// Make sure target actually contains a Type.
            //if (!typeof(Type).IsAssignableFrom(target.LimitType))
            //{
            //    return errorSuggestion ??
            //        RuntimeHelpers.CreateThrow(
            //            target, args, BindingRestrictions.Empty,
            //            typeof(InvalidOperationException),
            //            "Type object must be used when creating instance -- " +
            //                args.ToString());
            //}
            //var type = target.Value as Type;
            //Debug.Assert(type != null);
            //var constructors = type.GetConstructors();
            //// Get constructors with right arg counts.
            //var ctors = constructors.
            //    Where(c => c.GetParameters().Length == args.Length);
            //List<ConstructorInfo> res = new List<ConstructorInfo>();
            //foreach (var c in ctors)
            //{
            //    if (RuntimeHelpers.ParametersMatchArguments(c.GetParameters(),
            //        args))
            //    {
            //        res.Add(c);
            //    }
            //}
            //// We generate an instance restriction on the target since it is a
            //// Type and the constructor is associate with the actual Type instance.
            //var restrictions =
            //    RuntimeHelpers.GetTargetArgsRestrictions(
            //        target, args, true);
            //if (res.Count == 0)
            //{
            //    return errorSuggestion ??
            //        RuntimeHelpers.CreateThrow(
            //            target, args, restrictions,
            //            typeof(MissingMemberException),
            //            "Can't bind create instance -- " + args.ToString());
            //}
            //var ctorArgs =
            //    RuntimeHelpers.ConvertArguments(
            //        args, res[0].GetParameters());
            //return new DynamicMetaObject(
            //    // Creating an object, so don't need EnsureObjectResult.
            //    Expression.New(res[0], ctorArgs),
            //    restrictions);
        }
예제 #2
0
파일: ComBinder.cs 프로젝트: 40a/PowerShell
        /// <summary>
        /// Tries to perform binding of the dynamic invoke member operation.
        /// </summary>
        /// <param name="binder">An instance of the <see cref="InvokeMemberBinder"/> that represents the details of the dynamic operation.</param>
        /// <param name="isSetProperty">True if this is for setting a property, false otherwise..</param>
        /// <param name="instance">The target of the dynamic operation. </param>
        /// <param name="args">An array of <see cref="DynamicMetaObject"/> instances - arguments to the invoke member operation.</param>
        /// <param name="result">The new <see cref="DynamicMetaObject"/> representing the result of the binding.</param>
        /// <returns>true if operation was bound successfully; otherwise, false.</returns>
        public static bool TryBindInvokeMember(InvokeMemberBinder binder, bool isSetProperty, DynamicMetaObject instance, DynamicMetaObject[] args, out DynamicMetaObject result)
        {
            if (TryGetMetaObject(ref instance))
            {
                var comInvokeMember = new ComInvokeMemberBinder(binder, isSetProperty);
                result = instance.BindInvokeMember(comInvokeMember, args);

                BindingRestrictions argRestrictions = args.Aggregate(
                    BindingRestrictions.Empty, (current, arg) => current.Merge(arg.PSGetMethodArgumentRestriction()));
                var newRestrictions = result.Restrictions.Merge(argRestrictions);

                if (result.Expression.Type.IsValueType)
                {
                    result = new DynamicMetaObject(
                        Expression.Convert(result.Expression, typeof(object)),
                        newRestrictions
                    );
                }
                else
                {
                    result = new DynamicMetaObject(result.Expression, newRestrictions);
                }

                return true;
            }
            else
            {
                result = null;
                return false;
            }
        }