Merge() публичный Метод

Merges the set of binding restrictions with the current binding restrictions.
public Merge ( BindingRestrictions restrictions ) : BindingRestrictions
restrictions BindingRestrictions The set of restrictions with which to merge the current binding restrictions.
Результат BindingRestrictions
Пример #1
0
        /// <summary>
        /// Prepares arguments for argfull overload.
        /// </summary>
        /// <param name="routine">Routine for which arguments should be prepared</param>
        /// <param name="arguments">Arguments to be prepared for the routine</param>
        /// <param name="genericArguments">Amount of generic arguments provided by call site.</param>
        /// <param name="regularArguments">Amount of value arguments provided by call site.</param>
        /// <param name="restrictions">Type restrictions for the arguments</param>
        /// <returns>Array of prepared arguments to be called with routine</returns>
        /// <remarks>
        /// This is basically substitute for everything important that was done in argless overload (except it doesn't use PhpStack but evaluation stack).
        /// It adopts the arguments according to routine. e.g. dereference reference if value is needed, supplies default argument, etc.
        /// </remarks>
        public static Expression[] PrepareArguments(this PhpRoutine routine, DynamicMetaObject[] arguments, int genericArguments, int regularArguments, out BindingRestrictions restrictions)
        {
            const int scriptContextIndex = 0;
            DynamicMetaObject arg;
            int result_offset = 0;
            int argument_offset = 0;
            Expression[] result = new Expression[1 + routine.Signature.GenericParamCount + routine.Signature.ParamCount];//ScriptContext + all arguments = actual arguments to be passed to argfull overload
            restrictions = BindingRestrictions.Empty;

            result[scriptContextIndex] = arguments[scriptContextIndex].Expression;
            ++result_offset;
            ++argument_offset;

			// peek pseudo-generic arguments:
            for (int i = 0; i < routine.Signature.GenericParamCount; ++i)
            {
                if (i < genericArguments)
                {
                    arg = arguments[argument_offset + i];
                }
                else
                {
                    arg = null;
                }

                result[result_offset + i] = GeneratePeekPseudoGenericArgument(routine, arguments[scriptContextIndex], arg, i);

                // it isn't necessary to add restriction for type argument, it is always DTypeDesc
            }

            result_offset += routine.Signature.GenericParamCount;
            argument_offset += genericArguments;

			// peek regular arguments:
            // skip first one ScriptContext and generic parameters
            for (int i = 0; i < routine.Signature.ParamCount; ++i)
            {
                if (i < regularArguments)
                {
                    arg = arguments[argument_offset + i];

                    if (arg.RuntimeType != null)
                        restrictions = restrictions.Merge(BindingRestrictions.GetTypeRestriction(arguments[argument_offset + i].Expression, arguments[argument_offset + i].LimitType));
                    else
                        restrictions = restrictions.Merge(BindingRestrictions.GetInstanceRestriction(arguments[argument_offset + i].Expression, null));//(MB) is it necessary?
                }
                else
                {
                    arg = null;
                }
                
                result[result_offset + i] = GeneratePeekArgument(routine, arguments[scriptContextIndex], arg, i);

            }

            return result;
        }
Пример #2
0
        public static void TargetAsObject(DynamicMetaObject target, out Expression target_expr, out object target_value, ref BindingRestrictions restrictions)
        {
            target_expr = target.Expression;
            target_value = target.Value;

            if (target_value == null)
            {
                throw new NotImplementedException();    // TODO: call on NULL
            }

            for (;;)
            {
                if (target_expr.Type == typeof(PhpValue))
                {
                    // Template: target.Object // target.IsObject
                    var value = (PhpValue)target_value;
                    if (value.IsNull)
                    {
                        throw new NotImplementedException();    // TODO: call on NULL
                    }
                    else if (value.IsObject)
                    {
                        restrictions = restrictions.Merge(BindingRestrictions.GetExpressionRestriction(Expression.Property(target_expr, "IsObject")));

                        target_value = value.Object;
                        target_expr = Expression.Property(target_expr, "Object");
                        break;
                    }
                    else if (value.IsAlias)
                    {
                        restrictions = restrictions.Merge(BindingRestrictions.GetExpressionRestriction(Expression.Property(target_expr, "IsAlias")));

                        target_value = value.Alias;
                        target_expr = Expression.Property(target_expr, "Alias");
                        continue;
                    }
                    else
                    {
                        throw new NotImplementedException();    // TODO: scalar
                    }
                }
                else if (target_expr.Type == typeof(PhpAlias))
                {
                    // dereference
                    target_value = (PhpAlias)target_value;
                    target_expr = Expression.PropertyOrField(target_expr, "Value");
                    continue;
                }

                //
                break;
            }
        }
Пример #3
0
 string ResolveName(DynamicMetaObject[] args, ref BindingRestrictions restrictions)
 {
     if (_name != null)
     {
         return _name;
     }
     else
     {
         Debug.Assert(args.Length >= 1 && args[0].LimitType == typeof(string));
         restrictions = restrictions.Merge(BindingRestrictions.GetExpressionRestriction(Expression.Equal(args[0].Expression, Expression.Constant(args[0].Value)))); // args[0] == "VALUE"
         return (string)args[0].Value;
     }
 }
Пример #4
0
 void ResolveArgs(DynamicMetaObject[] args, ref BindingRestrictions restrictions, out string fieldName, out Expression valueExpr)
 {
     if (_name != null)
     {
         fieldName = _name;
         valueExpr = (args.Length > 0) ? args[0].Expression : null;
     }
     else
     {
         Debug.Assert(args.Length >= 1 && args[0].LimitType == typeof(string));
         restrictions = restrictions.Merge(BindingRestrictions.GetExpressionRestriction(Expression.Equal(args[0].Expression, Expression.Constant(args[0].Value)))); // args[0] == "VALUE"
         fieldName = (string)args[0].Value;
         valueExpr = (args.Length > 1) ? args[1].Expression : null;
     }
 }
 private static BindingRestrictions AddRemoteObjectRestrictions(BindingRestrictions restrictions, object[] args, ReadOnlyCollection<ParameterExpression> parameters)
 {
     for (int i = 0; i < parameters.Count; i++)
     {
         ParameterExpression left = parameters[i];
         MarshalByRefObject obj2 = args[i] as MarshalByRefObject;
         if ((obj2 != null) && !IsComObject(obj2))
         {
             BindingRestrictions expressionRestriction;
             if (RemotingServices.IsObjectOutOfAppDomain(obj2))
             {
                 expressionRestriction = BindingRestrictions.GetExpressionRestriction(Expression.AndAlso(Expression.NotEqual(left, Expression.Constant(null)), Expression.Call(typeof(RemotingServices).GetMethod("IsObjectOutOfAppDomain"), left)));
             }
             else
             {
                 expressionRestriction = BindingRestrictions.GetExpressionRestriction(Expression.AndAlso(Expression.NotEqual(left, Expression.Constant(null)), Expression.Not(Expression.Call(typeof(RemotingServices).GetMethod("IsObjectOutOfAppDomain"), left))));
             }
             restrictions = restrictions.Merge(expressionRestriction);
         }
     }
     return restrictions;
 }
Пример #6
0
        /// <summary>
        /// Performs binding against a set of overloaded methods using the specified arguments.  The arguments are
        /// consumed as specified by the CallSignature object.
        /// </summary>
        /// <param name="minLevel">TODO.</param>
        /// <param name="maxLevel">TODO.</param>
        /// <param name="resolver">Overload resolver.</param>
        /// <param name="targets">The methods to be called</param>
        /// <param name="restrictions">Additional restrictions which should be applied to the resulting MetaObject.</param>
        /// <param name="target">The resulting binding target which can be used for producing error information.</param>
        /// <param name="name">The name of the method or null to use the name from targets.</param>
        /// <returns>A meta object which results from the call.</returns>
        public DynamicMetaObject CallMethod(DefaultOverloadResolver resolver, IList<MethodBase> targets, BindingRestrictions restrictions, string name, 
            NarrowingLevel minLevel, NarrowingLevel maxLevel, out BindingTarget target) {
            ContractUtils.RequiresNotNull(resolver, "resolver");
            ContractUtils.RequiresNotNullItems(targets, "targets");
            ContractUtils.RequiresNotNull(restrictions, "restrictions");

            // attempt to bind to an individual method
            target = resolver.ResolveOverload(name ?? GetTargetName(targets), targets, minLevel, maxLevel);

            if (target.Success) {
                // if we succeed make the target for the rule
                return new DynamicMetaObject(
                    target.MakeExpression(),
                    restrictions.Merge(
                        MakeSplatTests(resolver.CallType, resolver.Signature, resolver.Arguments).
                            Merge(target.RestrictedArguments.GetAllRestrictions())
                    )
                );
            }

            // make an error rule
            return MakeInvalidParametersRule(resolver, restrictions, target);
        }
Пример #7
0
        public override DYN.DynamicMetaObject FallbackInvoke(DYN.DynamicMetaObject target, DYN.DynamicMetaObject[] args, DYN.DynamicMetaObject errorSuggestion)
        {
            if (target.HasValue && target.Value is AReference &&
                ((AReference)target.Value).Data is AFunc)
            {
                DLR.Expression dataExpression =
                    DLR.Expression.PropertyOrField(
                        DLR.Expression.Convert(target.Expression, typeof(AType)),
                        "Data"
                        );

                DYN.BindingRestrictions baseRestriction = DYN.BindingRestrictions.GetTypeRestriction(
                    target.Expression, target.LimitType
                    );

                DYN.BindingRestrictions builtinRestriction;
                DYN.BindingRestrictions restriction;

                DLR.Expression targetExpression = DLR.Expression.Convert(dataExpression, typeof(AFunc));

                // Func<..> types (argument types + return type)
                Type[] callTypes;

                // Convert every function parameters to AType
                DLR.Expression[] callArguments;

                DLR.Expression codeBlock = null;

                if (((AFunc)((AReference)target.Value).Data).IsBuiltin)
                {
                    switch (this.CallInfo.ArgumentCount)
                    {
                    case 2:
                        callTypes     = new Type[args.Length + 2];
                        callArguments = new DLR.Expression[args.Length + 1];
                        BuildArguments(args, callTypes, callArguments);
                        // Add the missing infos:
                        callTypes[2]     = typeof(AType);
                        callArguments[2] = DLR.Expression.Constant(null, typeof(AType));
                        // Build the codeblock for the method invoke
                        codeBlock = BuildInvoke(targetExpression, callTypes, callArguments);
                        break;

                    case 3:
                        callTypes     = new Type[args.Length + 1];
                        callArguments = new DLR.Expression[args.Length];
                        BuildArguments(args, callTypes, callArguments);
                        // Build the codeblock for the method invoke
                        codeBlock = BuildInvoke(targetExpression, callTypes, callArguments);
                        break;

                    default:
                        // Every other case is invalid...
                        codeBlock = DLR.Expression.Block(
                            DLR.Expression.Throw(
                                DLR.Expression.New(
                                    typeof(Error.Valence).GetConstructor(new Type[] { typeof(string) }),
                                    DLR.Expression.Property(targetExpression, "Name")
                                    )
                                ),
                            DLR.Expression.Default(typeof(AType))
                            );
                        break;
                    }

                    builtinRestriction = DYN.BindingRestrictions.GetExpressionRestriction(
                        DLR.Expression.IsTrue(DLR.Expression.Property(targetExpression, "IsBuiltin"))
                        );
                }
                else
                {
                    callTypes     = new Type[args.Length + 1];
                    callArguments = new DLR.Expression[args.Length];

                    BuildArguments(args, callTypes, callArguments);

                    codeBlock = DLR.Expression.Block(
                        // Check if the function we are calling have the correct valence
                        DLR.Expression.IfThen(
                            DLR.Expression.NotEqual(
                                DLR.Expression.Property(targetExpression, "Valence"),
                                DLR.Expression.Constant(this.CallInfo.ArgumentCount)
                                ),
                            // Function's valence is incorrect throw error
                            DLR.Expression.Throw(
                                DLR.Expression.New(
                                    typeof(Error.Valence).GetConstructor(new Type[] { typeof(string) }),
                                    DLR.Expression.Property(targetExpression, "Name")
                                    )
                                )
                            ),
                        // Function's valence is OK
                        // Call the function
                        BuildInvoke(targetExpression, callTypes, callArguments)
                        );

                    builtinRestriction = DYN.BindingRestrictions.GetExpressionRestriction(
                        DLR.Expression.IsFalse(DLR.Expression.Property(targetExpression, "IsBuiltin"))
                        );
                }

                restriction = baseRestriction.Merge(builtinRestriction);

                DYN.DynamicMetaObject dynobj = new DYN.DynamicMetaObject(codeBlock, restriction);

                return(dynobj);
            }

            // Throw a non-function error
            return(new DYN.DynamicMetaObject(
                       DLR.Expression.Throw(
                           DLR.Expression.New(
                               typeof(Error.NonFunction).GetConstructor(new Type[] { typeof(string) }),
                               DLR.Expression.Call(
                                   target.Expression,
                                   typeof(object).GetMethod("ToString")
                                   )
                               ),
                           typeof(Error.NonFunction)
                           ),
                       DYN.BindingRestrictions.GetTypeRestriction(target.Expression, target.RuntimeType)
                       ));
        }
        private DynamicMetaObject TryMakeBindingTarget(MethodInfo[] targets, DynamicMetaObject[] args, Expression codeContext, BindingRestrictions restrictions) {
            MethodBinder mb = MethodBinder.MakeBinder(this, targets[0].Name, targets);

            BindingTarget target = mb.MakeBindingTarget(CallTypes.None, args);
            if (target.Success) {
                return new DynamicMetaObject(
                    target.MakeExpression(new ParameterBinderWithCodeContext(this, codeContext)),
                    restrictions.Merge(BindingRestrictions.Combine(target.RestrictedArguments))
                );
            }

            return null;
        }
Пример #9
0
 internal MetaObject GetMetaObject(Expression expression, BindingRestrictions restrictions, object value)
 {
     return new MetaObject(this, expression, restrictions.Merge(Restrict(expression)), value);
 }
Пример #10
0
        /// <summary>
        /// This core method determines the class of an object.
        /// </summary>
        /// <param name="runtime">Required: SmalltalkRuntime containing the Smalltalk classes.</param>
        /// <param name="receiver">Optional: Object whos class is to be determined.</param>
        /// <param name="self">Required: Expression for the receiver.</param>
        /// <param name="arguments">Required: Currently not used.</param>
        /// <param name="restrictions">Restrictions for the given receiver.</param>
        /// <returns>The SmalltalkClass for the given receiver. This always returns an object (unless the given SmalltalkRuntime is inconsistent).</returns>
        public static SmalltalkClass GetClassAndRestrictions(SmalltalkRuntime runtime, 
            object receiver,
            DynamicMetaObject self,
            DynamicMetaObject[] arguments,
            out BindingRestrictions restrictions)
        {
            SmalltalkClass cls;
            // Special case handling of null, so it acts like first-class-object.
            if (receiver == null)
            {
                cls = runtime.NativeTypeClassMap.UndefinedObject;
                // If not explicitely mapped to a ST Class, fallback to the generic .Net mapping class.
                if (cls == null)
                    cls = runtime.NativeTypeClassMap.Native;
                if (cls == null)
                    cls = runtime.NativeTypeClassMap.Object;
                restrictions = BindingRestrictions.GetInstanceRestriction(self.Expression, null);
            }
            // Smalltalk objects ... almost every objects ends up here.
            else if (receiver is SmalltalkObject)
            {
                SmalltalkObject obj = (SmalltalkObject)receiver;
                cls = obj.Class;
                if (cls.Runtime == runtime)
                {
                    FieldInfo field = typeof(SmalltalkObject).GetField("Class", BindingFlags.GetField | BindingFlags.Instance | BindingFlags.Public);
                    if (field == null)
                        throw new InvalidOperationException();
                    restrictions = BindingRestrictions.GetTypeRestriction(self.Expression, typeof(SmalltalkObject));
                    restrictions = restrictions.Merge(BindingRestrictions.GetExpressionRestriction(
                        Expression.ReferenceEqual(Expression.Field(Expression.Convert(self.Expression, typeof(SmalltalkObject)), field), Expression.Constant(cls))));
                }
                else
                {
                    // A smalltalk object, but from different runtime
                    cls = null; // Let block below handle this.
                    restrictions = null;
                }
            }
            else if (receiver is Symbol)
            {
                Symbol symbol = (Symbol)receiver;
                SymbolTable manager = symbol.Manager;
                if (manager.Runtime == runtime)
                {
                    cls = runtime.NativeTypeClassMap.Symbol;
                    FieldInfo field = typeof(Symbol).GetField("Manager", BindingFlags.GetField | BindingFlags.Instance | BindingFlags.Public);
                    if (field == null)
                        throw new InvalidOperationException();
                    restrictions = BindingRestrictions.GetTypeRestriction(self.Expression, typeof(Symbol));
                    restrictions = restrictions.Merge(BindingRestrictions.GetExpressionRestriction(
                        Expression.ReferenceEqual(Expression.Field(Expression.Convert(self.Expression, typeof(Symbol)), field), Expression.Constant(manager))));
                }
                else
                {
                    // A smalltalk object, but from different runtime
                    cls = null; // Let block below handle this.
                    restrictions = null;
                }
            }
            else if (receiver is Pool)
            {
                Pool pool = (Pool)receiver;

                if (pool.Runtime == runtime)
                {
                    cls = runtime.NativeTypeClassMap.Pool;
                    PropertyInfo prop = typeof(Pool).GetProperty("Runtime", BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.GetProperty,
                        null, typeof(SmalltalkRuntime), new Type[0], null);
                    if (prop == null)
                        throw new InvalidOperationException();
                    restrictions = BindingRestrictions.GetTypeRestriction(self.Expression, typeof(Pool));
                    restrictions = restrictions.Merge(BindingRestrictions.GetExpressionRestriction(
                        Expression.ReferenceEqual(Expression.Property(Expression.Convert(self.Expression, typeof(Pool)), prop), Expression.Constant(runtime))));
                }
                else
                {
                    // A smalltalk object, but from different runtime
                    cls = null; // Let block below handle this.
                    restrictions = null;
                }
            }
            // Common FCL type mapping (bool, int, string, etc) to first-class-object.
            else if (receiver is bool)
            {
                Expression restrictionTest;
                if ((bool)receiver)
                {
                    cls = runtime.NativeTypeClassMap.True;
                    restrictionTest = Expression.IsTrue(Expression.Convert(self.Expression, typeof(bool)));
                }
                else
                {
                    cls = runtime.NativeTypeClassMap.False;
                    restrictionTest = Expression.IsFalse(Expression.Convert(self.Expression, typeof(bool)));
                }
                restrictions = BindingRestrictions.GetTypeRestriction(self.Expression, typeof(bool))
                    .Merge(BindingRestrictions.GetExpressionRestriction(restrictionTest));
            }
            else if (receiver is int)
            {
                cls = runtime.NativeTypeClassMap.SmallInteger;
                restrictions = BindingRestrictions.GetTypeRestriction(self.Expression, typeof(int));
            }
            else if (receiver is string)
            {
                cls = runtime.NativeTypeClassMap.String;
                restrictions = BindingRestrictions.GetTypeRestriction(self.Expression, typeof(string));
            }
            else if (receiver is char)
            {
                cls = runtime.NativeTypeClassMap.Character;
                restrictions = BindingRestrictions.GetTypeRestriction(self.Expression, typeof(char));
            }
            else if (receiver is double)
            {
                cls = runtime.NativeTypeClassMap.Float;
                restrictions = BindingRestrictions.GetTypeRestriction(self.Expression, typeof(double));
            }
            else if (receiver is decimal)
            {
                cls = runtime.NativeTypeClassMap.SmallDecimal;
                restrictions = BindingRestrictions.GetTypeRestriction(self.Expression, typeof(decimal));
            }
            else if (receiver is System.Numerics.BigInteger)
            {
                cls = runtime.NativeTypeClassMap.BigInteger;
                restrictions = BindingRestrictions.GetTypeRestriction(self.Expression, typeof(System.Numerics.BigInteger));
            }
            else if (receiver is IronSmalltalk.Common.BigDecimal)
            {
                cls = runtime.NativeTypeClassMap.BigDecimal;
                restrictions = BindingRestrictions.GetTypeRestriction(self.Expression, typeof(IronSmalltalk.Common.BigDecimal));
            }
            // Special case for Smalltalk classes, because we want the class behavior ...
            else if (receiver is SmalltalkClass)
            {
                cls = (SmalltalkClass)receiver;
                if (cls.Runtime == runtime)
                {
                    cls = runtime.NativeTypeClassMap.Class;
                    if (cls == null)
                        cls = runtime.NativeTypeClassMap.Object;

                    if (cls == null)
                        restrictions = null;
                    else
                        // NB: Restriction below are no good for For class behavior.
                        restrictions = BindingRestrictions.GetTypeRestriction(self.Expression, typeof(SmalltalkClass));
                }
                else
                {
                    // A smalltalk object, but from different runtime
                    cls = null; // Let block below handle this.
                    restrictions = null;
                }
            }
            // Some .Net type that's neither IronSmalltalk object nor any on the known (hardcoded) types.
            else
            {
                cls = null; // Let block below handle this.
                restrictions = null;
            }

            // In case of any of the known (hardcoded) types has no registered Smalltalk class,
            // fallback to the generic .Net type to Smalltalk class mapping.
            if (cls != null)
            {
                return cls;
            }
            else
            {
                Type type = receiver.GetType();
                cls = runtime.NativeTypeClassMap.GetSmalltalkClass(type);
                // If not explicitely mapped to a ST Class, fallback to the generic .Net mapping class.
                if (cls == null)
                    cls = runtime.NativeTypeClassMap.Native;
                if (restrictions == null)
                    restrictions = BindingRestrictions.GetTypeRestriction(self.Expression, type);
                return cls;
            }
        }
Пример #11
0
        private static BindingRestrictions AddRemoteObjectRestrictions(BindingRestrictions restrictions, object[] args, ReadOnlyCollection<ParameterExpression> parameters) {
#if !SILVERLIGHT

            for (int i = 0; i < parameters.Count; i++) {
                var expr = parameters[i];
                var value = args[i] as MarshalByRefObject;

                // special case for MBR objects.
                // when MBR objects are remoted they can have different conversion behavior
                // so bindings created for local and remote objects should not be mixed.
                if (value != null && !IsComObject(value)) {
                    BindingRestrictions remotedRestriction;
                    if (RemotingServices.IsObjectOutOfAppDomain(value)) {
                        remotedRestriction = BindingRestrictions.GetExpressionRestriction(
                            Expression.AndAlso(
                                Expression.NotEqual(expr, Expression.Constant(null)),
                                Expression.Call(
                                    typeof(RemotingServices).GetMethod("IsObjectOutOfAppDomain"),
                                    expr
                                )
                            )
                        );
                    } else {
                        remotedRestriction = BindingRestrictions.GetExpressionRestriction(
                            Expression.AndAlso(
                                Expression.NotEqual(expr, Expression.Constant(null)),
                                Expression.Not(
                                    Expression.Call(
                                        typeof(RemotingServices).GetMethod("IsObjectOutOfAppDomain"),
                                        expr
                                    )
                                )
                            )
                        );
                    }
                    restrictions = restrictions.Merge(remotedRestriction);
                }
            }

#endif
            return restrictions;
        }
Пример #12
0
        protected override MethodBase[] ResolveMethods(DynamicMetaObject ctx, ref DynamicMetaObject target, IList<DynamicMetaObject> args, ref BindingRestrictions restrictions)
        {
            if (target.Value == null)
            {
                Combine(ref restrictions, BindingRestrictions.GetInstanceRestriction(target.Expression, Expression.Constant(null)));
                // TODO: Err instance is null
                return null;
            }

            // resolve target expression:
            Expression target_expr;
            object target_value;
            BinderHelpers.TargetAsObject(target, out target_expr, out target_value, ref restrictions);

            // target restrictions
            if (!target_expr.Type.GetTypeInfo().IsSealed)
            {
                restrictions = restrictions.Merge(BindingRestrictions.GetTypeRestriction(target_expr, target_value.GetType()));
                target_expr = Expression.Convert(target_expr, target_value.GetType());
            }

            target = new DynamicMetaObject(target_expr, target.Restrictions, target_value);

            string name = _name;

            if (_name == null)
            {
                // indirect function name

                Debug.Assert(args.Count >= 1 && args[0].LimitType == typeof(string));
                Debug.Assert(args[0].Value is string);

                restrictions = restrictions.Merge(BindingRestrictions.GetExpressionRestriction(Expression.Equal(args[0].Expression, Expression.Constant(args[0].Value)))); // args[0] == "VALUE"

                name = (string)args[0].Value;
                args.RemoveAt(0);
            }

            // candidates:
            var candidates = target.RuntimeType.SelectCandidates().SelectByName(name).SelectVisible(_classCtx).ToList();
            return candidates.ToArray();
        }
Пример #13
0
        private static DynamicMetaObject MakeInvalidParametersRule(CallTypes callType, CallSignature signature, DefaultBinder binder, IList<DynamicMetaObject> args, BindingRestrictions restrictions, BindingTarget bt) {
            BindingRestrictions restriction = MakeSplatTests(callType, signature, true, args);

            // restrict to the exact type of all parameters for errors
            for (int i = 0; i < args.Count; i++) {
                args[i] = args[i].Restrict(args[i].GetLimitType());
            }

            return MakeError(
                binder.MakeInvalidParametersError(bt),
                restrictions.Merge(BindingRestrictions.Combine(args).Merge(restriction))
            );
        }
Пример #14
0
        private DynamicMetaObject CallWorker(ParameterBinder parameterBinder, IList<MethodBase> targets, IList<DynamicMetaObject> args, CallSignature signature, CallTypes callType, BindingRestrictions restrictions, NarrowingLevel minLevel, NarrowingLevel maxLevel, string name, out BindingTarget target) {
            ContractUtils.RequiresNotNull(parameterBinder, "parameterBinder");
            ContractUtils.RequiresNotNullItems(args, "args");
            ContractUtils.RequiresNotNullItems(targets, "targets");
            ContractUtils.RequiresNotNull(restrictions, "restrictions");

            DynamicMetaObject[] finalArgs;
            SymbolId[] argNames;

            if (callType == CallTypes.ImplicitInstance) {
                GetArgumentNamesAndTypes(signature, ArrayUtils.RemoveFirst(args), out argNames, out finalArgs);
                finalArgs = ArrayUtils.Insert(args[0], finalArgs);
            } else {
                GetArgumentNamesAndTypes(signature, args, out argNames, out finalArgs);
            }

            // attempt to bind to an individual method
            MethodBinder binder = MethodBinder.MakeBinder(
                this,
                name ?? GetTargetName(targets),
                targets,
                argNames,
                minLevel,
                maxLevel);
            target = binder.MakeBindingTarget(callType, finalArgs);

            if (target.Success) {
                // if we succeed make the target for the rule
                return new DynamicMetaObject(
                    target.MakeExpression(parameterBinder),
                    restrictions.Merge(MakeSplatTests(callType, signature, args).Merge(BindingRestrictions.Combine(target.RestrictedArguments)))
                );
            }
            // make an error rule
            return MakeInvalidParametersRule(callType, signature, this, args, restrictions, target);
        }
Пример #15
0
        void ExpandLastArg(List<Argument> arguments, DynamicMetaObject[] args, ref BindingRestrictions restrictions)
        {
            if (args.Length == 0)
                return;

            var lastArg = args.Last();

            if (lastArg.LimitType != typeof(Varargs))
                return;

            // TODO: Use custom restriction (checks length and types) and add arguments by indexing into Varargs value
            restrictions = restrictions.Merge(RuntimeHelpers.MergeInstanceRestrictions(lastArg));

            var varargs = (Varargs)lastArg.Value;
            arguments.RemoveAt(arguments.Count - 1);
            arguments.AddRange(varargs.Select(value => new Argument(Expr.Constant(value), value.GetType())));
        }
Пример #16
0
        // TODO: revisit
        private DynamicMetaObject MakeInvalidParametersRule(DefaultOverloadResolver binder, BindingRestrictions restrictions, BindingTarget bt) {
            var args = binder.Arguments;
            
            BindingRestrictions restriction = MakeSplatTests(binder.CallType, binder.Signature, true, args);

            // restrict to the exact type of all parameters for errors
            for (int i = 0; i < args.Count; i++) {
                args[i] = args[i].Restrict(args[i].GetLimitType());
            }

            return MakeError(
                binder.MakeInvalidParametersError(bt),
                restrictions.Merge(BindingRestrictions.Combine(args).Merge(restriction)),
                typeof(object)
            );
        }
Пример #17
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="target">The <see cref="CallbackItem"/> to use.</param>
        /// <param name="args"></param>
        /// <remarks>
        /// Order of items in the <see cref="args"/> array:
        /// <list type="number">
        ///  <item><see cref="Aplus"/></item>
        ///  <item>New value for the global variable</item>
        /// </list>
        /// </remarks>
        /// <returns></returns>
        public override DYN.DynamicMetaObject Bind(DYN.DynamicMetaObject target, DYN.DynamicMetaObject[] args)
        {
            ContractUtils.RequiresNotNull(target, "target");
            ContractUtils.RequiresNotNullItems(args, "args");

            if (target.HasValue && target.Value is CallbackItem)
            {
                CallbackItem callbackItem      = (CallbackItem)target.Value;
                AFunc        callbackAFunction = (AFunc)callbackItem.CallbackFunction.Data;

                DLR.Expression callbackItemExpression = DLR.Expression.Convert(
                    target.Expression, typeof(CallbackItem)
                    );


                DYN.BindingRestrictions baseRestriction = DYN.BindingRestrictions.GetTypeRestriction(
                    target.Expression, target.LimitType
                    );

                DLR.Expression callbackAFunctionExpression = DLR.Expression.Convert(
                    DLR.Expression.Convert(target.Expression, typeof(CallbackItem))
                    .Property("CallbackFunction").Property("Data"),
                    typeof(AFunc)
                    );

                DYN.BindingRestrictions valenceRestriction =
                    DYN.BindingRestrictions.GetExpressionRestriction(
                        DLR.Expression.Equal(
                            callbackAFunctionExpression.Property("Valence"),
                            DLR.Expression.Constant(callbackAFunction.Valence)
                            )
                        );

                // TODO: refactor the argument generation, something similar is in the InvokeBinder

                IEnumerable <DLR.Expression> callbackBaseArguments = new DLR.Expression[] {
                    callbackItemExpression.Property("StaticData"),             // static data
                    DLR.Expression.Convert(args[1].Expression, typeof(AType)), // new value
                    DLR.Expression.Convert(args[2].Expression, typeof(AType)), // index/set of indices
                    DLR.Expression.Convert(args[3].Expression, typeof(AType)), // path (left argument of pick)
                    callbackItemExpression.Property("Context"),                // context of the global variable
                    callbackItemExpression.Property("UnqualifiedName")         // name of the global variable
                }.Where((item, i) => i < callbackAFunction.Valence - 1).Reverse();
                List <DLR.Expression> callbackArguments = new List <DLR.Expression>();

                // Aplus
                callbackArguments.Add(DLR.Expression.Convert(args[0].Expression, args[0].RuntimeType));
                callbackArguments.AddRange(callbackBaseArguments);


                Type[] callTypes = new Type[callbackAFunction.Valence + 1];
                callTypes[0] = typeof(Aplus);

                for (int i = 1; i < callbackAFunction.Valence; i++)
                {
                    callTypes[i] = typeof(AType);
                }

                // return type
                callTypes[callbackAFunction.Valence] = typeof(AType);


                DLR.Expression codeBlock = DLR.Expression.Invoke(
                    DLR.Expression.Convert(
                        callbackAFunctionExpression.Property("Method"),
                        DLR.Expression.GetFuncType(callTypes)
                        ),
                    callbackArguments
                    );

                DYN.DynamicMetaObject dynobj =
                    new DYN.DynamicMetaObject(codeBlock, baseRestriction.Merge(valenceRestriction));

                return(dynobj);
            }

            // Throw a non-function error
            return(new DYN.DynamicMetaObject(
                       DLR.Expression.Throw(
                           DLR.Expression.New(
                               typeof(Error.NonFunction).GetConstructor(new Type[] { typeof(string) }),
                               DLR.Expression.Call(
                                   target.Expression,
                                   typeof(object).GetMethod("ToString")
                                   )
                               ),
                           typeof(Error.NonFunction)
                           ),
                       DYN.BindingRestrictions.GetTypeRestriction(target.Expression, target.RuntimeType)
                       ));
        }
Пример #18
0
 protected void Combine(ref BindingRestrictions restrictions, BindingRestrictions restriction)
 {
     restrictions = restrictions.Merge(restriction);
 }
Пример #19
0
        private DynamicMetaObject TryMakeBindingTarget(OverloadResolverFactory resolverFactory, MethodInfo[] targets, DynamicMetaObject[] args, BindingRestrictions restrictions) {
            var resolver = resolverFactory.CreateOverloadResolver(args, new CallSignature(args.Length), CallTypes.None);
            BindingTarget target = resolver.ResolveOverload(targets[0].Name, targets, NarrowingLevel.None, NarrowingLevel.All);
            if (target.Success) {
                return new DynamicMetaObject(
                    target.MakeExpression(),
                    restrictions.Merge(target.RestrictedArguments.GetAllRestrictions())
                );
            }

            return null;
        }
Пример #20
0
        /// <summary>
        /// This method binds rules for PhpMethod
        /// </summary>
        private void InvokePhpMethod(DynamicMetaObject/*!*/ target, DynamicMetaObject[]/*!!*/ args, /*object targetObj,*/ PhpRoutine/*!*/ routine, out BindingRestrictions restrictions, out Expression invokeMethodExpr)
        {
            Debug.Assert(target != null && target.Value != null);
            Debug.Assert(!(target.Value is IClrValue), "PhpRoutine should not be declared on CLR value type!");

            /*if (target.Value is PhpObject)
            {
                // Restriction: typeof(target) == |target.TypeDesc.RealType|
                var targetPhpObj = (PhpObject)target.Value;
                Debug.Assert(targetPhpObj.TypeDesc.RealType == target.LimitType);
                Debug.Assert(target.Value.GetType() == target.LimitType);
                restrictions = BindingRestrictions.GetTypeRestriction(target.Expression, targetPhpObj.TypeDesc.RealType);
            }
            else*/
            Debug.Assert(typeof(ClrObject).IsSealed);   // just to ensure following condition is correct
            if (target.Value.GetType() == typeof(ClrObject))
            {
                target = new ClrDynamicMetaObject(target);  // unwrap the real object, get restrictions
                restrictions = target.Restrictions;
            }
            else
            {
                Debug.Assert(target.Value.GetType() == target.LimitType);   // just for sure
                Debug.Assert(!(target.Value is PhpObject) || ((PhpObject)target.Value).TypeDesc.RealType == target.LimitType);

                restrictions = BindingRestrictions.GetTypeRestriction(target.Expression, target.LimitType);
            }

            BindingRestrictions argumentsRestrictions;
            Expression[] arguments;

            if (routine.Name != Name.SpecialMethodNames.Call)
            {
                args = GetArgumentsRange(args, 0, RealMethodArgumentCount);// This can't be done when _call method is invoked

                //Check if method has ArgAware attribute
                if ((routine.Properties & RoutineProperties.IsArgsAware) != 0 ||
                    routine.IsStatic)// this is because of hack in PHP.Library.XML library static methods that can be also called like instance methods
                {
                    DynamicMetaObject scriptContext = args[0];

                    //Select arguments without scriptContext
                    DynamicMetaObject[] realArgs = GetArgumentsRange(args, 1, RealMethodArgumentCount - 1);

                    InvokeArgLess(target, scriptContext, routine.RoutineDesc, realArgs, out argumentsRestrictions, out invokeMethodExpr);
                    restrictions = restrictions.Merge(argumentsRestrictions);
                    return;
                }

                arguments = routine.PrepareArguments(args, _genericParamsCount, _paramsCount, out argumentsRestrictions);
                restrictions = restrictions.Merge(argumentsRestrictions);
            }
            else
            {
                arguments = BinderHelper.PackToExpressions(args);
            }

            //((PhpObject)target))
            var realObjEx = Expression.Convert(target.Expression, routine.ArgFullInfo.DeclaringType);//targetObj.TypeDesc.RealType);

            //ArgFull( ((PhpObject)target), ScriptContext, args, ... )
            invokeMethodExpr = Expression.Call(BinderHelper.WrapInstanceMethodCall(routine.ArgFullInfo),
                                     BinderHelper.CombineArguments(realObjEx, arguments));

            invokeMethodExpr = ReturnArgumentHelpers.ReturnValueConversion(routine.ArgFullInfo, invokeMethodExpr);

            invokeMethodExpr = HandleResult(invokeMethodExpr, routine.ArgFullInfo.ReturnType, false);

        }