/// <summary> /// Gets an expression which is used for accessing this slot. If the slot lookup fails the error expression /// is used again. /// /// The default implementation just calls the TryGetValue method. Subtypes of PythonTypeSlot can override /// this and provide a more optimal implementation. /// </summary> internal virtual void MakeGetExpression(PythonBinder /*!*/ binder, Expression /*!*/ codeContext, DynamicMetaObject instance, DynamicMetaObject /*!*/ owner, ConditionalBuilder /*!*/ builder) { ParameterExpression tmp = Ast.Variable(typeof(object), "slotTmp"); Expression call = Ast.Call( typeof(PythonOps).GetMethod("SlotTryGetValue"), codeContext, AstUtils.Convert(AstUtils.WeakConstant(this), typeof(PythonTypeSlot)), instance != null ? instance.Expression : AstUtils.Constant(null), owner.Expression, tmp ); builder.AddVariable(tmp); if (!GetAlwaysSucceeds) { builder.AddCondition( call, tmp ); } else { builder.FinishCondition(Ast.Block(call, tmp)); } }
/// <summary> /// Checks to see if the provided members are always visible for the given type. /// /// This filters out methods such as GetHashCode and Equals on standard .NET /// types that we expose directly as Python types (e.g. object, string, etc...). /// /// It also filters out the base helper overrides that are added for supporting /// super calls on user defined types. /// </summary> private static bool IsMethodAlwaysVisible(Type /*!*/ type, MemberInfo /*!*/[] /*!*/ methods) { bool alwaysVisible = true; if (PythonBinder.IsPythonType(type)) { // only show methods defined outside of the system types (object, string) foreach (MethodInfo mi in methods) { if (PythonBinder.IsExtendedType(mi.DeclaringType) || PythonBinder.IsExtendedType(mi.GetBaseDefinition().DeclaringType) || PythonHiddenAttribute.IsHidden(mi)) { alwaysVisible = false; break; } } } else if (typeof(IPythonObject).IsAssignableFrom(type)) { // check if this is a virtual override helper, if so we // may need to filter it out. foreach (MethodInfo mi in methods) { if (PythonBinder.IsExtendedType(mi.DeclaringType)) { alwaysVisible = false; break; } } } return(alwaysVisible); }
internal static string GetModuleName(CodeContext /*!*/ context, Type type) { if (IsRuntimeAssembly(type.Assembly) || PythonBinder.IsPythonType(type)) { Type curType = type; while (curType != null) { string moduleName; if (PythonContext.GetContext(context).BuiltinModuleNames.TryGetValue(curType, out moduleName)) { return(moduleName); } curType = curType.DeclaringType; } FieldInfo modField = type.GetField("__module__"); if (modField != null && modField.IsLiteral && modField.FieldType == typeof(string)) { return((string)modField.GetRawConstantValue()); } return("__builtin__"); } return(type.Namespace + " in " + type.Assembly.FullName); }
internal override void MakeGetExpression(PythonBinder/*!*/ binder, Expression/*!*/ codeContext, DynamicMetaObject instance, DynamicMetaObject/*!*/ owner, ConditionalBuilder/*!*/ builder) { if (instance != null) { builder.FinishCondition( Ast.Call( typeof(PythonOps).GetMethod(nameof(PythonOps.MakeBoundBuiltinFunction)), AstUtils.Constant(_template), instance.Expression ) ); } else { builder.FinishCondition(AstUtils.Constant(this)); } }
internal static PythonTypeSlot GetReflectedField(FieldInfo info) { PythonTypeSlot res; NameType nt = NameType.Field; if (!PythonBinder.IsExtendedPythonType(info.DeclaringType) && !PythonBinder.IsPythonSupportingType(info.DeclaringType) && !PythonHiddenAttribute.IsHidden(info)) { nt |= NameType.PythonField; } lock (_fieldCache) { if (!_fieldCache.TryGetValue(info, out res)) { if (nt == NameType.PythonField && info.IsLiteral) { if (info.FieldType == typeof(int)) { res = new PythonTypeUserDescriptorSlot( ScriptingRuntimeHelpers.Int32ToObject((int)info.GetRawConstantValue()), true ); } else if (info.FieldType == typeof(bool)) { res = new PythonTypeUserDescriptorSlot( ScriptingRuntimeHelpers.BooleanToObject((bool)info.GetRawConstantValue()), true ); } else { res = new PythonTypeUserDescriptorSlot( info.GetValue(null), true ); } } else { res = new ReflectedField(info, nt); } _fieldCache[info] = res; } } return(res); }
internal override void MakeGetExpression(PythonBinder /*!*/ binder, Expression /*!*/ codeContext, DynamicMetaObject instance, DynamicMetaObject /*!*/ owner, ConditionalBuilder /*!*/ builder) { if (Getter.Length != 0 && !Getter[0].IsPublic) { // fallback to runtime call base.MakeGetExpression(binder, codeContext, instance, owner, builder); } else if (NeedToReturnProperty(instance, Getter)) { builder.FinishCondition(AstUtils.Constant(this)); } else if (Getter[0].ContainsGenericParameters) { builder.FinishCondition( DefaultBinder.MakeError( binder.MakeContainsGenericParametersError( MemberTracker.FromMemberInfo(_info) ), typeof(object) ).Expression ); } else if (instance != null) { builder.FinishCondition( AstUtils.Convert( binder.MakeCallExpression( new PythonOverloadResolverFactory(binder, codeContext), Getter[0], instance ).Expression, typeof(object) ) ); } else { builder.FinishCondition( AstUtils.Convert( binder.MakeCallExpression( new PythonOverloadResolverFactory(binder, codeContext), Getter[0] ).Expression, typeof(object) ) ); } }
internal static ReflectedEvent GetReflectedEvent(EventTracker tracker) { ReflectedEvent res; lock (_eventCache) { if (!_eventCache.TryGetValue(tracker, out res)) { if (PythonBinder.IsExtendedType(tracker.DeclaringType)) { _eventCache[tracker] = res = new ReflectedEvent(tracker, true); } else { _eventCache[tracker] = res = new ReflectedEvent(tracker, false); } } } return(res); }
public static string GetTypeName(Type t) { if (t.IsArray) { return("Array[" + GetTypeName(t.GetElementType()) + "]"); } string name = PythonBinder.GetTypeNameInternal(t); if (name != t.Name) { return(name); } int backtickIndex; if ((backtickIndex = name.IndexOf(ReflectionUtils.GenericArityDelimiter)) != -1) { name = name.Substring(0, backtickIndex); Type[] typeOf = t.GetGenericArguments(); StringBuilder sb = new StringBuilder(name); sb.Append('['); bool first = true; foreach (Type tof in typeOf) { if (first) { first = false; } else { sb.Append(", "); } sb.Append(GetTypeName(tof)); } sb.Append(']'); name = sb.ToString(); } return(name); }
internal override void MakeGetExpression(PythonBinder /*!*/ binder, Expression /*!*/ codeContext, DynamicMetaObject instance, DynamicMetaObject /*!*/ owner, ConditionalBuilder /*!*/ builder) { if (!_info.IsPublic || _info.DeclaringType.ContainsGenericParameters) { // fallback to reflection base.MakeGetExpression(binder, codeContext, instance, owner, builder); } else if (instance == null) { if (_info.IsStatic) { builder.FinishCondition(AstUtils.Convert(Ast.Field(null, _info), typeof(object))); } else { builder.FinishCondition(Ast.Constant(this)); } } else { builder.FinishCondition( AstUtils.Convert( Ast.Field( binder.ConvertExpression( instance.Expression, _info.DeclaringType, ConversionResultKind.ExplicitCast, new PythonOverloadResolverFactory(binder, codeContext) ), _info ), typeof(object) ) ); } }
internal static ReflectedGetterSetter GetReflectedProperty(PropertyTracker pt, MemberGroup allProperties, bool privateBinding) { ReflectedGetterSetter rp; lock (_propertyCache) { if (_propertyCache.TryGetValue(pt, out rp)) { return(rp); } NameType nt = NameType.PythonProperty; MethodInfo getter = FilterProtectedGetterOrSetter(pt.GetGetMethod(true), privateBinding); MethodInfo setter = FilterProtectedGetterOrSetter(pt.GetSetMethod(true), privateBinding); if ((getter != null && PythonHiddenAttribute.IsHidden(getter, true)) || (setter != null && PythonHiddenAttribute.IsHidden(setter, true))) { nt = NameType.Property; } ExtensionPropertyTracker ept = pt as ExtensionPropertyTracker; if (ept == null) { ReflectedPropertyTracker rpt = pt as ReflectedPropertyTracker; Debug.Assert(rpt != null); if (PythonBinder.IsExtendedType(pt.DeclaringType) || PythonHiddenAttribute.IsHidden(rpt.Property, true)) { nt = NameType.Property; } if (pt.GetIndexParameters().Length == 0) { List <MethodInfo> getters = new List <MethodInfo>(); List <MethodInfo> setters = new List <MethodInfo>(); IList <ExtensionPropertyTracker> overriddenProperties = NewTypeMaker.GetOverriddenProperties((getter ?? setter).DeclaringType, pt.Name); foreach (ExtensionPropertyTracker tracker in overriddenProperties) { MethodInfo method = tracker.GetGetMethod(privateBinding); if (method != null) { getters.Add(method); } method = tracker.GetSetMethod(privateBinding); if (method != null) { setters.Add(method); } } foreach (PropertyTracker propTracker in allProperties) { MethodInfo method = propTracker.GetGetMethod(privateBinding); if (method != null) { getters.Add(method); } method = propTracker.GetSetMethod(privateBinding); if (method != null) { setters.Add(method); } } rp = new ReflectedProperty(rpt.Property, getters.ToArray(), setters.ToArray(), nt); } else { rp = new ReflectedIndexer(((ReflectedPropertyTracker)pt).Property, NameType.Property, privateBinding); } } else { rp = new ReflectedExtensionProperty(new ExtensionPropertyInfo(pt.DeclaringType, getter ?? setter), nt); } _propertyCache[pt] = rp; return(rp); } }
internal override void MakeGetExpression(PythonBinder /*!*/ binder, Expression /*!*/ codeContext, DynamicMetaObject instance, DynamicMetaObject /*!*/ owner, ConditionalBuilder /*!*/ builder) { builder.FinishCondition(Ast.Constant(this)); }
/// <summary> /// target is the newly initialized value. /// args are the arguments to be passed to __init__ /// </summary> public override DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args) { DynamicMetaObject codeContext = target; CodeContext context = (CodeContext)codeContext.Value; target = args[0]; args = ArrayUtils.RemoveFirst(args); ValidationInfo valInfo = BindingHelpers.GetValidationInfo(target); Expression res; PythonType instType = DynamicHelpers.GetPythonType(target.Value); BindingRestrictions initRestrictions = BindingRestrictions.Empty; if (IronPython.Modules.Builtin.isinstance(target.Value, _newType) && NeedsInitCall((CodeContext)codeContext.Value, instType, args.Length)) { // resolve __init__ PythonTypeSlot init; instType.TryResolveSlot(context, "__init__", out init); if (init is PythonFunction) { // avoid creating the bound method, just invoke it directly Expression[] allArgs = new Expression[args.Length + 3]; allArgs[0] = codeContext.Expression; allArgs[1] = AstUtils.WeakConstant(init); allArgs[2] = target.Expression; for (int i = 0; i < args.Length; i++) { allArgs[3 + i] = args[i].Expression; } res = DynamicExpression.Dynamic( context.LanguageContext.Invoke(_signature.InsertArgument(Argument.Simple)), typeof(object), allArgs ); } else if (init is BuiltinMethodDescriptor || init is BuiltinFunction) { IList <MethodBase> targets; if (init is BuiltinMethodDescriptor) { targets = ((BuiltinMethodDescriptor)init).Template.Targets; } else { targets = ((BuiltinFunction)init).Targets; } PythonBinder binder = context.LanguageContext.Binder; DynamicMetaObject initInvoke = binder.CallMethod( new PythonOverloadResolver( binder, target, args, _signature, codeContext.Expression ), targets, BindingRestrictions.Empty ); res = initInvoke.Expression; initRestrictions = initInvoke.Restrictions; } else { // some weird descriptor has been put in place for __init__, we need // to call __get__ on it each time. res = MakeDynamicInitInvoke( context, args, Expression.Call( typeof(PythonOps).GetMethod("GetInitSlotMember"), codeContext.Expression, Expression.Convert(AstUtils.WeakConstant(_newType), typeof(PythonType)), Expression.Convert(AstUtils.WeakConstant(init), typeof(PythonTypeSlot)), AstUtils.Convert(target.Expression, typeof(object)) ), codeContext.Expression ); } } else { // returned something that isn't a subclass of the creating type // __init__ will not be run. res = AstUtils.Empty(); } // check for __del__ PythonTypeSlot delSlot; if (instType.TryResolveSlot(context, "__del__", out delSlot)) { res = Expression.Block( res, Expression.Call( typeof(PythonOps).GetMethod("InitializeForFinalization"), codeContext.Expression, AstUtils.Convert(target.Expression, typeof(object)) ) ); } return(BindingHelpers.AddDynamicTestAndDefer( this, new DynamicMetaObject( Expression.Block( res, target.Expression ), target.Restrict(target.LimitType).Restrictions.Merge(initRestrictions) ), args, valInfo )); }