예제 #1
0
 internal MSAst.Expression AddOuterProfiling(MSAst.Expression /*!*/ body, MSAst.ParameterExpression /*!*/ tick, int profileIndex)
 {
     return(Ast.Block(
                Ast.Assign(
                    tick,
                    Ast.Call(
                        Ast.Constant(this, typeof(Profiler)),
                        typeof(Profiler).GetMethod(nameof(Profiler.StartCall)),
                        AstUtils.Constant(profileIndex)
                        )
                    ),
                AstUtils.Try(
                    body
                    ).Finally(
                    Ast.Call(
                        Ast.Constant(this, typeof(Profiler)),
                        typeof(Profiler).GetMethod(nameof(Profiler.FinishCall)),
                        AstUtils.Constant(profileIndex),
                        tick
                        )
                    )
                ));
 }
예제 #2
0
        internal static MethodCallExpression /*!*/ CheckTypeVersion(Expression /*!*/ tested, int version)
        {
            FieldInfo fi = tested.Type.GetField(NewTypeMaker.ClassFieldName);

            if (fi == null)
            {
                return(Ast.Call(
                           typeof(PythonOps).GetMethod("CheckTypeVersion"),
                           AstUtils.Convert(tested, typeof(object)),
                           AstUtils.Constant(version)
                           ));
            }

            Debug.Assert(tested.Type != typeof(object));
            return(Ast.Call(
                       typeof(PythonOps).GetMethod("CheckSpecificTypeVersion"),
                       Ast.Field(
                           tested,
                           fi
                           ),
                       AstUtils.Constant(version)
                       ));
        }
예제 #3
0
        private DynamicMetaObject /*!*/ MakeAbstractInstantiationError(DynamicMetaObjectBinder /*!*/ call, ArgumentValues /*!*/ ai, ValidationInfo /*!*/ valInfo)
        {
            CodeContext context = PythonContext.GetPythonContext(call).SharedContext;
            string      message = Value.GetAbstractErrorMessage(context);

            Debug.Assert(message != null);

            return(BindingHelpers.AddDynamicTestAndDefer(
                       call,
                       new DynamicMetaObject(
                           Ast.Throw(
                               Ast.New(
                                   typeof(ArgumentTypeException).GetConstructor(new Type[] { typeof(string) }),
                                   AstUtils.Constant(message)
                                   ),
                               typeof(object)
                               ),
                           GetErrorRestrictions(ai)
                           ),
                       ai.Arguments,
                       valInfo
                       ));
        }
예제 #4
0
        private static DynamicMetaObject /*!*/ GetPythonType(DynamicMetaObject /*!*/ self)
        {
            Assert.NotNull(self);

            PythonType pt = DynamicHelpers.GetPythonType(self.Value);

            if (pt.IsSystemType)
            {
                return(new DynamicMetaObject(
                           AstUtils.Constant(pt),
                           BindingRestrictions.Empty,
                           pt
                           ));
            }

            return(new DynamicMetaObject(
                       Ast.Property(
                           Ast.Convert(self.Expression, typeof(IPythonObject)),
                           PythonTypeInfo._IPythonObject.PythonType
                           ),
                       BindingRestrictions.Empty,
                       pt
                       ));
        }
예제 #5
0
        private MSA.Expression /*!*/ TransformStatementsToExpression(Statements statements, bool toBoolean, bool positive)
        {
            if (statements == null || statements.Count == 0)
            {
                return(toBoolean ? AstUtils.Constant(!positive) : AstUtils.Constant(null));
            }

            var last = toBoolean ? statements.Last.TransformCondition(this, positive) : statements.Last.TransformReadStep(this);

            if (statements.Count == 1)
            {
                return(last);
            }

            var result = new AstBlock();

            foreach (var statement in statements.AllButLast)
            {
                result.Add(statement.Transform(this));
            }
            result.Add(last);

            return(result);
        }
            protected override bool AddMetaSlotAccess(PythonType metaType, PythonTypeSlot pts)
            {
                ParameterExpression tmp = Ast.Variable(typeof(object), "slotRes");

                pts.MakeGetExpression(
                    _state.Binder,
                    _codeContext,
                    _type,
                    new DynamicMetaObject(
                        AstUtils.Constant(metaType),
                        BindingRestrictions.Empty,
                        metaType
                        ),
                    _cb
                    );

                if (!pts.IsAlwaysVisible)
                {
                    _cb.AddCondition(Ast.Call(typeof(PythonOps).GetMethod("IsClsVisible"), _codeContext));
                    return(false);
                }

                return(pts.GetAlwaysSucceeds);
            }
예제 #7
0
        private static DynamicMetaObject MakeGetItemIterable(DynamicMetaObject metaUserObject, PythonContext state, PythonTypeSlot pts, string method)
        {
            ParameterExpression tmp = Ast.Parameter(typeof(object), "getitemVal");

            return(new DynamicMetaObject(
                       Expression.Block(
                           new[] { tmp },
                           Expression.Call(
                               typeof(PythonOps).GetMethod(method),
                               AstUtils.Convert(metaUserObject.Expression, typeof(object)),
                               Ast.Block(
                                   MetaPythonObject.MakeTryGetTypeMember(
                                       state,
                                       pts,
                                       tmp,
                                       metaUserObject.Expression,
                                       Ast.Call(
                                           typeof(DynamicHelpers).GetMethod(nameof(DynamicHelpers.GetPythonType)),
                                           AstUtils.Convert(
                                               metaUserObject.Expression,
                                               typeof(object)
                                               )
                                           )
                                       ),
                                   tmp
                                   ),
                               AstUtils.Constant(
                                   CallSite <Func <CallSite, CodeContext, object, int, object> > .Create(
                                       new PythonInvokeBinder(state, new CallSignature(1))
                                       )
                                   )
                               )
                           ),
                       metaUserObject.Restrictions
                       ));
        }
예제 #8
0
        private DynamicMetaObject /*!*/ MakeIncorrectArgumentsForCallError(DynamicMetaObjectBinder /*!*/ call, ArgumentValues /*!*/ ai, ValidationInfo /*!*/ valInfo)
        {
            string message;

            if (Value.IsSystemType)
            {
                if (Value.UnderlyingSystemType.GetConstructors().Length == 0)
                {
                    // this is a type we can't create ANY instances of, give the user a half-way decent error message
                    message = "cannot create instances of " + Value.Name;
                }
                else
                {
                    message = InstanceOps.ObjectNewNoParameters;
                }
            }
            else
            {
                message = InstanceOps.ObjectNewNoParameters;
            }

            return(BindingHelpers.AddDynamicTestAndDefer(
                       call,
                       new DynamicMetaObject(
                           call.Throw(
                               Ast.New(
                                   typeof(TypeErrorException).GetConstructor(new Type[] { typeof(string) }),
                                   AstUtils.Constant(message)
                                   )
                               ),
                           GetErrorRestrictions(ai)
                           ),
                       ai.Arguments,
                       valInfo
                       ));
        }
예제 #9
0
 public void SetWrongNumberOfArgumentsError(int actual, int expected)
 {
     SetError(Methods.MakeWrongNumberOfArgumentsError.OpCall(AstUtils.Constant(actual), AstUtils.Constant(expected)));
 }
예제 #10
0
        private DynamicMetaObject TryToCharConversion(DynamicMetaObject /*!*/ self)
        {
            DynamicMetaObject res;
            // we have an implicit conversion to char if the
            // string length == 1, but we can only represent
            // this is implicit via a rule.
            string     strVal  = self.Value as string;
            Expression strExpr = self.Expression;

            if (strVal == null)
            {
                Extensible <string> extstr = self.Value as Extensible <string>;
                if (extstr != null)
                {
                    strVal  = extstr.Value;
                    strExpr =
                        Ast.Property(
                            AstUtils.Convert(
                                strExpr,
                                typeof(Extensible <string>)
                                ),
                            typeof(Extensible <string>).GetProperty("Value")
                            );
                }
            }

            // we can only produce a conversion if we have a string value...
            if (strVal != null)
            {
                self = self.Restrict(self.GetRuntimeType());

                Expression getLen = Ast.Property(
                    AstUtils.Convert(
                        strExpr,
                        typeof(string)
                        ),
                    typeof(string).GetProperty("Length")
                    );

                if (strVal.Length == 1)
                {
                    res = new DynamicMetaObject(
                        Ast.Call(
                            AstUtils.Convert(strExpr, typeof(string)),
                            typeof(string).GetMethod("get_Chars"),
                            AstUtils.Constant(0)
                            ),
                        self.Restrictions.Merge(BindingRestrictions.GetExpressionRestriction(Ast.Equal(getLen, AstUtils.Constant(1))))
                        );
                }
                else
                {
                    res = new DynamicMetaObject(
                        Ast.Throw(
                            Ast.Call(
                                typeof(PythonOps).GetMethod("TypeError"),
                                AstUtils.Constant("expected string of length 1 when converting to char, got '{0}'"),
                                Ast.NewArrayInit(typeof(object), self.Expression)
                                ),
                            ReturnType
                            ),
                        self.Restrictions.Merge(BindingRestrictions.GetExpressionRestriction(Ast.NotEqual(getLen, AstUtils.Constant(1))))
                        );
                }
            }
            else
            {
                // let the base class produce the rule
                res = null;
            }

            return(res);
        }
예제 #11
0
        internal DynamicMetaObject FallbackConvert(Type returnType, DynamicMetaObject self, DynamicMetaObject errorSuggestion)
        {
            Type type             = Type;
            DynamicMetaObject res = null;

            switch (Type.GetTypeCode(type))
            {
            case TypeCode.Boolean:
                res = MakeToBoolConversion(self);
                break;

            case TypeCode.Char:
                res = TryToCharConversion(self);
                break;

            case TypeCode.String:
                if (self.GetLimitType() == typeof(Bytes) && !_context.PythonOptions.Python30)
                {
                    res = new DynamicMetaObject(
                        Ast.Call(
                            typeof(PythonOps).GetMethod("MakeString"),
                            AstUtils.Convert(self.Expression, typeof(IList <byte>))
                            ),
                        BindingRestrictionsHelpers.GetRuntimeTypeRestriction(self.Expression, typeof(Bytes))
                        );
                }
                break;

            case TypeCode.Object:
                // !!! Deferral?
                if (type.IsArray && self.Value is PythonTuple && type.GetArrayRank() == 1)
                {
                    res = MakeToArrayConversion(self, type);
                }
                else if (type.IsGenericType && !type.IsAssignableFrom(CompilerHelpers.GetType(self.Value)))
                {
                    Type genTo = type.GetGenericTypeDefinition();

                    // Interface conversion helpers...
                    if (genTo == typeof(IList <>))
                    {
                        if (self.LimitType == typeof(string))
                        {
                            res = new DynamicMetaObject(
                                Ast.Call(
                                    typeof(PythonOps).GetMethod("MakeByteArray"),
                                    AstUtils.Convert(self.Expression, typeof(string))
                                    ),
                                BindingRestrictions.GetTypeRestriction(
                                    self.Expression,
                                    typeof(string)
                                    )
                                );
                        }
                        else
                        {
                            res = TryToGenericInterfaceConversion(self, type, typeof(IList <object>), typeof(ListGenericWrapper <>));
                        }
                    }
                    else if (genTo == typeof(IDictionary <,>))
                    {
                        res = TryToGenericInterfaceConversion(self, type, typeof(IDictionary <object, object>), typeof(DictionaryGenericWrapper <,>));
                    }
                    else if (genTo == typeof(IEnumerable <>))
                    {
                        res = TryToGenericInterfaceConversion(self, type, typeof(IEnumerable), typeof(IEnumerableOfTWrapper <>));
                    }
                }
                else if (type == typeof(IEnumerable))
                {
                    if (!typeof(IEnumerable).IsAssignableFrom(self.GetLimitType()) && IsIndexless(self))
                    {
                        res = ConvertToIEnumerable(this, self.Restrict(self.GetLimitType()));
                    }
                }
                else if (type == typeof(IEnumerator))
                {
                    if (!typeof(IEnumerator).IsAssignableFrom(self.GetLimitType()) &&
                        !typeof(IEnumerable).IsAssignableFrom(self.GetLimitType()) &&
                        IsIndexless(self))
                    {
                        res = ConvertToIEnumerator(this, self.Restrict(self.GetLimitType()));
                    }
                }
                break;
            }

            if (type.IsEnum && Enum.GetUnderlyingType(type) == self.GetLimitType())
            {
                // numeric type to enum, this is ok if the value is zero
                object value = Activator.CreateInstance(type);

                return(new DynamicMetaObject(
                           Ast.Condition(
                               Ast.Equal(
                                   AstUtils.Convert(self.Expression, Enum.GetUnderlyingType(type)),
                                   AstUtils.Constant(Activator.CreateInstance(self.GetLimitType()))
                                   ),
                               AstUtils.Constant(value),
                               Ast.Call(
                                   typeof(PythonOps).GetMethod("TypeErrorForBadEnumConversion").MakeGenericMethod(type),
                                   AstUtils.Convert(self.Expression, typeof(object))
                                   )
                               ),
                           self.Restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(self.Expression, self.GetLimitType())),
                           value
                           ));
            }

            return(res ?? EnsureReturnType(returnType, Context.Binder.ConvertTo(Type, ResultKind, self, _context.SharedOverloadResolverFactory, errorSuggestion)));
        }
예제 #12
0
        internal static DynamicMetaObject TranslateArguments(DynamicMetaObjectBinder call, Expression codeContext, DynamicMetaObject function, DynamicMetaObject /*!*/[] args, bool hasSelf, string name)
        {
            if (hasSelf)
            {
                args = ArrayUtils.RemoveFirst(args);
            }

            CallSignature sig = BindingHelpers.GetCallSignature(call);

            if (sig.HasDictionaryArgument())
            {
                int index = sig.IndexOf(ArgumentType.Dictionary);

                DynamicMetaObject dict = args[index];

                if (!(dict.Value is IDictionary) && dict.Value != null)
                {
                    // The DefaultBinder only handles types that implement IDictionary.  Here we have an
                    // arbitrary user-defined mapping type.  We'll convert it into a PythonDictionary
                    // and then have an embedded dynamic site pass that dictionary through to the default
                    // binder.
                    DynamicMetaObject[] dynamicArgs = ArrayUtils.Insert(function, args);

                    dynamicArgs[index + 1] = new DynamicMetaObject(
                        Expression.Call(
                            typeof(PythonOps).GetMethod(nameof(PythonOps.UserMappingToPythonDictionary)),
                            codeContext,
                            args[index].Expression,
                            AstUtils.Constant(name)
                            ),
                        BindingRestrictionsHelpers.GetRuntimeTypeRestriction(dict.Expression, dict.GetLimitType()),
                        PythonOps.UserMappingToPythonDictionary(PythonContext.GetPythonContext(call).SharedContext, dict.Value, name)
                        );

                    if (call is IPythonSite)
                    {
                        dynamicArgs = ArrayUtils.Insert(
                            new DynamicMetaObject(codeContext, BindingRestrictions.Empty),
                            dynamicArgs
                            );
                    }

                    return(new DynamicMetaObject(
                               DynamicExpression.Dynamic(
                                   call,
                                   typeof(object),
                                   DynamicUtils.GetExpressions(dynamicArgs)
                                   ),
                               BindingRestrictions.Combine(dynamicArgs).Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(dict.Expression, dict.GetLimitType()))
                               ));
                }
            }

            if (sig.HasListArgument())
            {
                int index             = sig.IndexOf(ArgumentType.List);
                DynamicMetaObject str = args[index];

                // TODO: ANything w/ __iter__ that's not an IList<object>
                if (!(str.Value is IList <object>) && str.Value is IEnumerable)
                {
                    // The DefaultBinder only handles types that implement IList<object>.  Here we have a
                    // string.  We'll convert it into a tuple
                    // and then have an embedded dynamic site pass that tuple through to the default
                    // binder.
                    DynamicMetaObject[] dynamicArgs = ArrayUtils.Insert(function, args);

                    dynamicArgs[index + 1] = new DynamicMetaObject(
                        Expression.Call(
                            typeof(PythonOps).GetMethod(nameof(PythonOps.MakeTupleFromSequence)),
                            Expression.Convert(args[index].Expression, typeof(object))
                            ),
                        BindingRestrictions.Empty
                        );

                    if (call is IPythonSite)
                    {
                        dynamicArgs = ArrayUtils.Insert(
                            new DynamicMetaObject(codeContext, BindingRestrictions.Empty),
                            dynamicArgs
                            );
                    }

                    return(new DynamicMetaObject(
                               DynamicExpression.Dynamic(
                                   call,
                                   typeof(object),
                                   DynamicUtils.GetExpressions(dynamicArgs)
                                   ),
                               function.Restrictions.Merge(
                                   BindingRestrictions.Combine(args).Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(str.Expression, str.GetLimitType()))
                                   )
                               ));
                }
            }
            return(null);
        }
예제 #13
0
 protected virtual Expression /*!*/ MakeErrorExpression(CallArguments /*!*/ args, Expression /*!*/ targetClassNameConstant, Type /*!*/ resultType)
 {
     return(Ast.Throw(
                Methods.CreateTypeConversionError.OpCall(targetClassNameConstant, AstUtils.Constant(TargetTypeName)),
                resultType
                ));
 }
예제 #14
0
 internal override MSA.Expression /*!*/ TransformRead(AstGenerator /*!*/ gen)
 {
     return(Methods.CreateMutableStringL.OpCall(StringConstructor.MakeConstant(_value), AstUtils.Constant(gen.Encoding)));
 }
예제 #15
0
 // return null if the object doesn't handle the conversion:
 protected override Expression /*!*/ MakeErrorExpression(CallArguments /*!*/ args, Expression /*!*/ targetClassNameConstant, Type /*!*/ resultType)
 {
     return(AstUtils.Constant(null, resultType));
 }
예제 #16
0
 public override DynamicMetaObject SetValue(OverloadResolverFactory resolverFactory, ActionBinder binder, Type type, DynamicMetaObject value)
 {
     return(SetBoundValue(resolverFactory, binder, type, value, new DynamicMetaObject(AstUtils.Constant(null), BindingRestrictions.Empty)));
 }
예제 #17
0
 public override DynamicMetaObject GetValue(OverloadResolverFactory factory, ActionBinder binder, Type instanceType)
 {
     return(GetBoundValue(factory, binder, instanceType, new DynamicMetaObject(AstUtils.Constant(null), BindingRestrictions.Empty)));
 }
예제 #18
0
        internal void AddSplattedArgumentTest(IList /*!*/ value, Expression /*!*/ expression, out int listLength, out ParameterExpression /*!*/ listVariable)
        {
            Expression assignment;

            listVariable = expression as ParameterExpression;
            if (listVariable != null && typeof(IList).IsAssignableFrom(expression.Type))
            {
                assignment = expression;
            }
            else
            {
                listVariable = GetTemporary(typeof(IList), "#list");
                assignment   = Ast.Assign(listVariable, AstUtils.Convert(expression, typeof(IList)));
            }

            listLength = value.Count;
            AddCondition(Ast.Equal(Ast.Property(assignment, typeof(ICollection).GetDeclaredProperty("Count")), AstUtils.Constant(value.Count)));
        }
예제 #19
0
        internal protected override bool TryImplicitConversion(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args)
        {
            if (args.Target == null)
            {
                metaBuilder.SetError(Methods.CreateTypeConversionError.OpCall(AstUtils.Constant("nil"), AstUtils.Constant(TargetTypeName)));
                return(true);
            }

            metaBuilder.Result =
                ImplicitConvert(typeof(int), args) ??
                ImplicitConvert(typeof(BigInteger), args);

            return(metaBuilder.Result != null);
        }
예제 #20
0
 // return null if the object doesn't handle the conversion:
 protected override void SetError(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args, Expression /*!*/ targetClassNameConstant, Type /*!*/ resultType)
 {
     metaBuilder.Result = AstUtils.Constant(null, resultType);
 }
예제 #21
0
        public void AddTargetTypeTest(object target, RubyClass /*!*/ targetClass, Expression /*!*/ targetParameter, DynamicMetaObject /*!*/ metaContext,
                                      IEnumerable <string> /*!*/ resolvedNames)
        {
            // no changes to the module's class hierarchy while building the test:
            targetClass.Context.RequiresClassHierarchyLock();

            // initialization changes the version number, so ensure that the module is initialized:
            targetClass.InitializeMethodsNoLock();

            var context = (RubyContext)metaContext.Value;

            if (target is IRubyObject)
            {
                Type type = target.GetType();
                AddTypeRestriction(type, targetParameter);

                // Ruby objects (get the method directly to prevent interface dispatch):
                MethodInfo classGetter = type.GetMethod(Methods.IRubyObject_get_ImmediateClass.Name, BindingFlags.Public | BindingFlags.Instance);
                if (type.IsVisible() && classGetter != null && classGetter.ReturnType == typeof(RubyClass))
                {
                    AddCondition(
                        // (#{type})target.ImmediateClass.Version.Method == #{immediateClass.Version.Method}
                        Ast.Equal(
                            Ast.Field(
                                Ast.Field(
                                    Ast.Call(Ast.Convert(targetParameter, type), classGetter),
                                    Fields.RubyModule_Version
                                    ),
                                Fields.VersionHandle_Method
                                ),
                            AstUtils.Constant(targetClass.Version.Method)
                            )
                        );
                    return;
                }

                // TODO: explicit iface-implementation
                throw new NotSupportedException("Type implementing IRubyObject should be visible and have ImmediateClass getter");
            }

            AddRuntimeTest(metaContext);

            // singleton nil:
            if (target == null)
            {
                AddRestriction(Ast.Equal(targetParameter, AstUtils.Constant(null)));
                AddVersionTest(context.NilClass);
                return;
            }

            // singletons true, false:
            if (target is bool)
            {
                AddRestriction(Ast.AndAlso(
                                   Ast.TypeIs(targetParameter, typeof(bool)),
                                   Ast.Equal(Ast.Convert(targetParameter, typeof(bool)), AstUtils.Constant(target))
                                   ));

                AddVersionTest((bool)target ? context.TrueClass : context.FalseClass);
                return;
            }

            var nominalClass = targetClass.NominalClass;

            Debug.Assert(!nominalClass.IsSingletonClass);
            Debug.Assert(!nominalClass.IsRubyClass);

            // Do we need a singleton check?
            if (nominalClass.ClrSingletonMethods == null ||
                CollectionUtils.TrueForAll(resolvedNames, (methodName) => !nominalClass.ClrSingletonMethods.ContainsKey(methodName)))
            {
                // no: there is no singleton subclass of target class that defines any method being called:
                AddTypeRestriction(target.GetType(), targetParameter);
                AddVersionTest(targetClass);
            }
            else if (targetClass.IsSingletonClass)
            {
                // yes: check whether the incoming object is a singleton and the singleton has the right version:
                AddTypeRestriction(target.GetType(), targetParameter);
                AddCondition(Methods.IsClrSingletonRuleValid.OpCall(
                                 metaContext.Expression,
                                 targetParameter,
                                 AstUtils.Constant(targetClass.Version.Method)
                                 ));
            }
            else
            {
                // yes: check whether the incoming object is NOT a singleton and the class has the right version:
                AddTypeRestriction(target.GetType(), targetParameter);
                AddCondition(Methods.IsClrNonSingletonRuleValid.OpCall(
                                 metaContext.Expression,
                                 targetParameter,
                                 Ast.Constant(targetClass.Version),
                                 AstUtils.Constant(targetClass.Version.Method)
                                 ));
            }
        }
예제 #22
0
 protected virtual void SetError(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args, Expression /*!*/ targetClassNameConstant, Type /*!*/ resultType)
 {
     metaBuilder.SetError(Methods.CreateTypeConversionError.OpCall(targetClassNameConstant, AstUtils.Constant(TargetTypeName)));
 }
예제 #23
0
        internal void AddVersionTest(RubyClass /*!*/ cls)
        {
            cls.Context.RequiresClassHierarchyLock();

            // check for module version (do not burn a module reference to the rule):
            AddCondition(Ast.Equal(Ast.Field(AstUtils.Constant(cls.Version), Fields.VersionHandle_Method), AstUtils.Constant(cls.Version.Method)));
        }
예제 #24
0
        internal protected override bool TryImplicitConversion(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args)
        {
            object target = args.Target;

            if (target == null)
            {
                metaBuilder.SetError(Methods.CreateTypeConversionError.OpCall(AstUtils.Constant("nil"), AstUtils.Constant(TargetTypeName)));
                return(true);
            }

            return((metaBuilder.Result = Convert(ReturnType, args)) != null);
        }
예제 #25
0
 public override DynamicMetaObject BindCreateInstance(CreateInstanceBinder create, params DynamicMetaObject[] args)
 {
     return(InvokeWorker(create, args, AstUtils.Constant(PythonContext.GetPythonContext(create).SharedContext)));
 }
예제 #26
0
        private DynamicMetaObject /*!*/ MakeGetMember(DynamicMetaObjectBinder /*!*/ member, DynamicMetaObject codeContext)
        {
            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldClass GetMember");
            PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "OldClass GetMember");
            DynamicMetaObject self = Restrict(typeof(OldClass));

            Expression target;
            string     memberName = GetGetMemberName(member);

            switch (memberName)
            {
            case "__dict__":
                target = Ast.Block(
                    Ast.Call(
                        typeof(PythonOps).GetMethod("OldClassDictionaryIsPublic"),
                        self.Expression
                        ),
                    Ast.Call(
                        typeof(PythonOps).GetMethod("OldClassGetDictionary"),
                        self.Expression
                        )
                    );
                break;

            case "__bases__":
                target = Ast.Call(
                    typeof(PythonOps).GetMethod("OldClassGetBaseClasses"),
                    self.Expression
                    );
                break;

            case "__name__":
                target = Ast.Call(
                    typeof(PythonOps).GetMethod("OldClassGetName"),
                    self.Expression
                    );
                break;

            default:
                ParameterExpression tmp = Ast.Variable(typeof(object), "lookupVal");
                return(new DynamicMetaObject(
                           Ast.Block(
                               new ParameterExpression[] { tmp },
                               Ast.Condition(
                                   Expression.Not(
                                       Expression.TypeIs(
                                           Expression.Assign(
                                               tmp,
                                               Ast.Call(
                                                   typeof(PythonOps).GetMethod("OldClassTryLookupValue"),
                                                   AstUtils.Constant(PythonContext.GetPythonContext(member).SharedContext),
                                                   self.Expression,
                                                   AstUtils.Constant(memberName)
                                                   )
                                               ),
                                           typeof(OperationFailed)
                                           )
                                       ),
                                   tmp,
                                   AstUtils.Convert(
                                       GetMemberFallback(this, member, codeContext).Expression,
                                       typeof(object)
                                       )
                                   )
                               ),
                           self.Restrictions
                           ));
            }

            return(new DynamicMetaObject(
                       target,
                       self.Restrictions
                       ));
        }
예제 #27
0
 public override DynamicMetaObject GetValue(OverloadResolverFactory resolverFactory, ActionBinder binder, Type type)
 {
     return(new DynamicMetaObject(AstUtils.Constant(GetSlot(), typeof(PythonTypeSlot)), BindingRestrictions.Empty));
 }
예제 #28
0
 public override DynamicMetaObject /*!*/ BindInvoke(InvokeBinder /*!*/ call, params DynamicMetaObject /*!*/[] /*!*/ args)
 {
     return(MakeCallRule(call, AstUtils.Constant(PythonContext.GetPythonContext(call).SharedContext), args));
 }
예제 #29
0
        /// <summary>
        /// Tries to get a MethodBinder associated with the slot for the specified type.
        ///
        /// If a method is found the binder is set and true is returned.
        /// If nothing is found binder is null and true is returned.
        /// If something other than a method is found false is returned.
        ///
        /// TODO: Remove rop
        /// </summary>
        internal static bool TryGetBinder(PythonContext /*!*/ state, DynamicMetaObject /*!*/[] /*!*/ types, string op, string rop, out SlotOrFunction /*!*/ res, out PythonType declaringType)
        {
            declaringType = null;

            DynamicMetaObject xType = types[0];
            BuiltinFunction   xBf;

            if (!BindingHelpers.TryGetStaticFunction(state, op, xType, out xBf))
            {
                res = SlotOrFunction.Empty;
                return(false);
            }

            xBf = CheckAlwaysNotImplemented(xBf);

            BindingTarget     bt;
            DynamicMetaObject binder;
            DynamicMetaObject yType = null;
            BuiltinFunction   yBf   = null;

            if (types.Length > 1)
            {
                yType = types[1];
                if (!BindingHelpers.IsSubclassOf(xType, yType) && !BindingHelpers.TryGetStaticFunction(state, rop, yType, out yBf))
                {
                    res = SlotOrFunction.Empty;
                    return(false);
                }

                yBf = CheckAlwaysNotImplemented(yBf);
            }

            if (yBf == xBf)
            {
                yBf = null;
            }
            else if (yBf != null && BindingHelpers.IsSubclassOf(yType, xType))
            {
                xBf = null;
            }

            var mc = new PythonOverloadResolver(
                state.Binder,
                types,
                new CallSignature(types.Length),
                AstUtils.Constant(state.SharedContext)
                );

            if (xBf == null)
            {
                if (yBf == null)
                {
                    binder = null;
                    bt     = null;
                }
                else
                {
                    declaringType = DynamicHelpers.GetPythonTypeFromType(yBf.DeclaringType);
                    binder        = state.Binder.CallMethod(mc, yBf.Targets, BindingRestrictions.Empty, null, PythonNarrowing.None, PythonNarrowing.BinaryOperator, out bt);
                }
            }
            else
            {
                if (yBf == null)
                {
                    declaringType = DynamicHelpers.GetPythonTypeFromType(xBf.DeclaringType);
                    binder        = state.Binder.CallMethod(mc, xBf.Targets, BindingRestrictions.Empty, null, PythonNarrowing.None, PythonNarrowing.BinaryOperator, out bt);
                }
                else
                {
                    List <MethodBase> targets = new List <MethodBase>();
                    targets.AddRange(xBf.Targets);
                    foreach (MethodBase mb in yBf.Targets)
                    {
                        if (!ContainsMethodSignature(targets, mb))
                        {
                            targets.Add(mb);
                        }
                    }

                    binder = state.Binder.CallMethod(mc, targets.ToArray(), BindingRestrictions.Empty, null, PythonNarrowing.None, PythonNarrowing.BinaryOperator, out bt);

                    foreach (MethodBase mb in yBf.Targets)
                    {
                        if (bt.Overload.ReflectionInfo == mb)
                        {
                            declaringType = DynamicHelpers.GetPythonTypeFromType(yBf.DeclaringType);
                            break;
                        }
                    }

                    if (declaringType == null)
                    {
                        declaringType = DynamicHelpers.GetPythonTypeFromType(xBf.DeclaringType);
                    }
                }
            }

            if (binder != null)
            {
                res = new SlotOrFunction(bt, binder);
            }
            else
            {
                res = SlotOrFunction.Empty;
            }

            Debug.Assert(res != null);
            return(true);
        }
예제 #30
0
 public override DynamicMetaObject /*!*/ BindCreateInstance(CreateInstanceBinder /*!*/ create, params DynamicMetaObject /*!*/[] /*!*/ args)
 {
     return(MakeCallRule(create, AstUtils.Constant(PythonContext.GetPythonContext(create).SharedContext), args));
 }