private static void MakeSlotsDeleteTarget(MemberBindingInfo/*!*/ info, ReflectedSlotProperty/*!*/ rsp) { MakeSlotsSetTarget(info, rsp, Ast.Field(null, typeof(Uninitialized).GetField("Instance"))); }
private static void MakeSlotsSetTarget(MemberBindingInfo/*!*/ info, ReflectedSlotProperty/*!*/ rsp, Expression/*!*/ value) { // type has __slots__ defined for this member, call the setter directly ParameterExpression tmp = Ast.Variable(typeof(object), "res"); info.Body.AddVariable(tmp); info.Body.FinishCondition( Ast.Block( Ast.Assign( tmp, Ast.Convert( Ast.Assign( Ast.ArrayAccess( Ast.Call( Ast.Convert(info.Args[0].Expression, typeof(IObjectWithSlots)), typeof(IObjectWithSlots).GetMethod("GetSlots") ), Ast.Constant(rsp.Index) ), AstUtils.Convert(value, typeof(object)) ), tmp.Type ) ), tmp ) ); }
public static Type GetNewType(string typeName, Tuple bases, IDictionary<object, object> dict) { // we're really only interested in the "correct" base type pulled out of bases // and any slot information contained in dict // other info might be used for future optimizations Debug.Assert(bases != null); NewTypeInfo typeInfo = GetTypeInfo(typeName, bases, GetSlots(dict)); if (typeInfo.BaseType.IsSealed || typeInfo.BaseType.IsValueType) throw Ops.TypeError("cannot derive from sealed or value types"); Type ret = newTypes.GetOrCreateValue(typeInfo, delegate() { // creation code return GetTypeMaker(bases, typeName, typeInfo).CreateNewType(); }); if (typeInfo.Slots != null) { // update dict w/ slots that point at the correct fields. for (int i = 0; i < typeInfo.Slots.Count; i++) { PropertyInfo pi = ret.GetProperty(typeInfo.Slots[i]); string name = typeInfo.Slots[i]; if (name.StartsWith("__") && !name.EndsWith("__")) { name = "_" + typeName + name; } dict[name] = new ReflectedSlotProperty(pi, pi.GetGetMethod(), pi.GetSetMethod(), NameType.PythonProperty); } } return ret; }