/// <summary> /// Called when the user is accessing a protected or private member on a get. /// /// The default implementation allows access to the fields or properties using reflection. /// </summary> public virtual ErrorInfo MakeNonPublicMemberGetError(OverloadResolverFactory resolverFactory, MemberTracker member, Type type, DynamicMetaObject instance) { switch (member.MemberType) { case TrackerTypes.Field: FieldTracker ft = (FieldTracker)member; return(ErrorInfo.FromValueNoError( Ast.Call( AstUtils.Convert(AstUtils.Constant(ft.Field), typeof(FieldInfo)), typeof(FieldInfo).GetMethod("GetValue"), AstUtils.Convert(instance.Expression, typeof(object)) ) )); case TrackerTypes.Property: PropertyTracker pt = (PropertyTracker)member; return(ErrorInfo.FromValueNoError( MemberTracker.FromMemberInfo(pt.GetGetMethod(true)).Call(resolverFactory, this, instance).Expression )); default: throw new InvalidOperationException(); } }
/// <summary> /// Called when a set is attempting to assign to a field or property from a derived class through the base class. /// /// The default behavior is to allow the assignment. /// </summary> public virtual ErrorInfo MakeStaticAssignFromDerivedTypeError(Type accessingType, DynamicMetaObject self, MemberTracker assigning, DynamicMetaObject assignedValue, OverloadResolverFactory context) { switch (assigning.MemberType) { case TrackerTypes.Property: PropertyTracker pt = (PropertyTracker)assigning; MethodInfo setter = pt.GetSetMethod() ?? pt.GetSetMethod(true); return(ErrorInfo.FromValueNoError( AstUtils.SimpleCallHelper( setter, ConvertExpression( assignedValue.Expression, setter.GetParameters()[0].ParameterType, ConversionResultKind.ExplicitCast, context ) ) )); case TrackerTypes.Field: FieldTracker ft = (FieldTracker)assigning; return(ErrorInfo.FromValueNoError( Expression.Assign( Expression.Field(null, ft.Field), ConvertExpression(assignedValue.Expression, ft.FieldType, ConversionResultKind.ExplicitCast, context) ) )); default: throw new InvalidOperationException(); } }
public static MemberTracker FromMemberInfo(MemberInfo member, Type extending) { ContractUtils.RequiresNotNull(member, nameof(member)); lock (_trackers) { MemberTracker res; MemberKey key = new MemberKey(member, extending); if (_trackers.TryGetValue(key, out res)) { return(res); } ConstructorInfo ctor; EventInfo evnt; FieldInfo field; MethodInfo method; TypeInfo type; PropertyInfo property; if ((method = member as MethodInfo) != null) { if (extending != null) { res = new ExtensionMethodTracker(method, member.IsDefined(typeof(StaticExtensionMethodAttribute), false), extending); } else { res = new MethodTracker(method); } } else if ((ctor = member as ConstructorInfo) != null) { res = new ConstructorTracker(ctor); } else if ((field = member as FieldInfo) != null) { res = new FieldTracker(field); } else if ((property = member as PropertyInfo) != null) { res = new ReflectedPropertyTracker(property); } else if ((evnt = member as EventInfo) != null) { res = new EventTracker(evnt); } else if ((type = member as TypeInfo) != null) { res = new NestedTypeTracker(type); } else { throw Error.UnknownMemberType(member); } _trackers[key] = res; return(res); } }
public virtual ErrorInfo MakeSetValueTypeFieldError(FieldTracker field, DynamicMetaObject instance, DynamicMetaObject value) { return(ErrorInfo.FromException( Expression.Throw( Expression.New( typeof(ArgumentException).GetConstructor(new[] { typeof(string) }), AstUtils.Constant("cannot assign to value types") ), typeof(object) ) )); }
public static MemberTracker FromMemberInfo(MemberInfo member, bool isExtension) { Contract.RequiresNotNull(member, "member"); lock (_trackers) { MemberTracker res; if (_trackers.TryGetValue(member, out res)) { return(res); } switch (member.MemberType) { case MemberTypes.Constructor: res = new ConstructorTracker((ConstructorInfo)member); break; case MemberTypes.Event: res = new EventTracker((EventInfo)member); break; case MemberTypes.Field: res = new FieldTracker((FieldInfo)member); break; case MemberTypes.Method: MethodInfo mi = (MethodInfo)member; #if FULL if (isExtension) { res = new MethodTracker(mi, member.IsDefined(typeof(StaticExtensionMethodAttribute), false)); } else { #endif res = new MethodTracker(mi); #if FULL } #endif break; case MemberTypes.TypeInfo: case MemberTypes.NestedType: res = new NestedTypeTracker((Type)member); break; case MemberTypes.Property: res = new ReflectedPropertyTracker((PropertyInfo)member); break; default: throw new InvalidOperationException("unknown type: " + member.MemberType); } _trackers[member] = res; return(res); } }
public static MemberTracker FromMemberInfo(MemberInfo member, Type extending) { ContractUtils.RequiresNotNull(member, "member"); lock (_trackers) { MemberTracker res; MemberKey key = new MemberKey(member, extending); if (_trackers.TryGetValue(key, out res)) { return(res); } switch (member.MemberType) { case MemberTypes.Constructor: res = new ConstructorTracker((ConstructorInfo)member); break; case MemberTypes.Event: res = new EventTracker((EventInfo)member); break; case MemberTypes.Field: res = new FieldTracker((FieldInfo)member); break; case MemberTypes.Method: MethodInfo mi = (MethodInfo)member; if (extending != null) { res = new ExtensionMethodTracker(mi, member.IsDefined(typeof(StaticExtensionMethodAttribute), false), extending); } else { res = new MethodTracker(mi); } break; case MemberTypes.TypeInfo: case MemberTypes.NestedType: res = new NestedTypeTracker((Type)member); break; case MemberTypes.Property: res = new ReflectedPropertyTracker((PropertyInfo)member); break; default: throw Error.UnknownMemberType(member.MemberType); } _trackers[key] = res; return(res); } }
public static MemberTracker FromMemberInfo(MemberInfo member, bool isExtension) { Contract.RequiresNotNull(member, "member"); lock (_trackers) { MemberTracker res; if (_trackers.TryGetValue(member, out res)) return res; switch (member.MemberType) { case MemberTypes.Constructor: res = new ConstructorTracker((ConstructorInfo)member); break; case MemberTypes.Event: res = new EventTracker((EventInfo)member); break; case MemberTypes.Field: res = new FieldTracker((FieldInfo)member); break; case MemberTypes.Method: MethodInfo mi = (MethodInfo)member; #if FULL if (isExtension) { res = new MethodTracker(mi, member.IsDefined(typeof(StaticExtensionMethodAttribute), false)); } else { #endif res = new MethodTracker(mi); #if FULL } #endif break; case MemberTypes.TypeInfo: case MemberTypes.NestedType: res = new NestedTypeTracker((Type)member); break; case MemberTypes.Property: res = new ReflectedPropertyTracker((PropertyInfo)member); break; default: throw new InvalidOperationException("unknown type: " + member.MemberType); } _trackers[member] = res; return res; } }
private static Expression ReturnFieldTracker(FieldTracker fieldTracker) { return Ast.Constant(PythonTypeOps.GetReflectedField(fieldTracker.Field)); }
private void MakeFieldRule(SetOrDeleteMemberInfo memInfo, DynamicMetaObject instance, DynamicMetaObject target, Type targetType, MemberGroup fields, DynamicMetaObject errorSuggestion) { FieldTracker field = (FieldTracker)fields[0]; // TODO: Tmp variable for target if (instance != null && field.DeclaringType.IsGenericType && field.DeclaringType.GetGenericTypeDefinition() == typeof(StrongBox <>)) { // work around a CLR bug where we can't access generic fields from dynamic methods. Type[] generic = field.DeclaringType.GetGenericArguments(); memInfo.Body.FinishCondition( MakeReturnValue( Ast.Assign( Ast.Field( AstUtils.Convert(instance.Expression, field.DeclaringType), field.DeclaringType.GetField("Value") ), AstUtils.Convert(target.Expression, generic[0]) ), target ) ); } else if (field.IsInitOnly || field.IsLiteral) { memInfo.Body.FinishCondition( errorSuggestion ?? MakeError( MakeReadOnlyMemberError(targetType, memInfo.Name), typeof(object) ) ); } else if (field.IsStatic && targetType != field.DeclaringType) { memInfo.Body.FinishCondition( errorSuggestion ?? MakeError( MakeStaticAssignFromDerivedTypeError(targetType, instance, field, target, memInfo.ResolutionFactory), typeof(object) ) ); } else if (field.DeclaringType.IsValueType && !field.IsStatic) { memInfo.Body.FinishCondition( errorSuggestion ?? MakeError( MakeSetValueTypeFieldError(field, instance, target), typeof(object) ) ); } else if (field.IsPublic && field.DeclaringType.IsVisible) { if (!field.IsStatic && instance == null) { memInfo.Body.FinishCondition( Ast.Throw( Ast.New( typeof(ArgumentException).GetConstructor(new Type[] { typeof(string) }), AstUtils.Constant("assignment to instance field w/o instance") ), typeof(object) ) ); } else { memInfo.Body.FinishCondition( MakeReturnValue( Ast.Assign( Ast.Field( field.IsStatic ? null : AstUtils.Convert(instance.Expression, field.DeclaringType), field.Field ), ConvertExpression(target.Expression, field.FieldType, ConversionResultKind.ExplicitCast, memInfo.ResolutionFactory) ), target ) ); } } else { Debug.Assert(field.IsStatic || instance != null); memInfo.Body.FinishCondition( MakeReturnValue( Ast.Call( AstUtils.Convert(AstUtils.Constant(field.Field), typeof(FieldInfo)), typeof(FieldInfo).GetMethod("SetValue", new Type[] { typeof(object), typeof(object) }), field.IsStatic ? AstUtils.Constant(null) : (Expression)AstUtils.Convert(instance.Expression, typeof(object)), AstUtils.Convert(target.Expression, typeof(object)) ), target ) ); } }
public virtual ErrorInfo MakeSetValueTypeFieldError(FieldTracker field, DynamicMetaObject instance, DynamicMetaObject value) { return ErrorInfo.FromException( Expression.Throw( Expression.New( typeof(ArgumentException).GetConstructor(new[] { typeof(string) }), AstUtils.Constant("cannot assign to value types") ), typeof(object) ) ); }
public static MemberTracker FromMemberInfo(MemberInfo member, Type extending) { ContractUtils.RequiresNotNull(member, "member"); lock (_trackers) { MemberTracker res; MemberKey key = new MemberKey(member, extending); if (_trackers.TryGetValue(key, out res)) return res; switch (member.MemberType) { case MemberTypes.Constructor: res = new ConstructorTracker((ConstructorInfo)member); break; case MemberTypes.Event: res = new EventTracker((EventInfo)member); break; case MemberTypes.Field: res = new FieldTracker((FieldInfo)member); break; case MemberTypes.Method: MethodInfo mi = (MethodInfo)member; if (extending != null) { res = new ExtensionMethodTracker(mi, member.IsDefined(typeof(StaticExtensionMethodAttribute), false), extending); } else { res = new MethodTracker(mi); } break; case MemberTypes.TypeInfo: case MemberTypes.NestedType: res = new NestedTypeTracker((Type)member); break; case MemberTypes.Property: res = new ReflectedPropertyTracker((PropertyInfo)member); break; default: throw Error.UnknownMemberType(member.MemberType); } _trackers[key] = res; return res; } }
private void MakeFieldRule(Type targetType, MemberGroup fields) { FieldTracker field = (FieldTracker)fields[0]; if (field.DeclaringType.IsGenericType && field.DeclaringType.GetGenericTypeDefinition() == typeof(StrongBox <>)) { // work around a CLR bug where we can't access generic fields from dynamic methods. Type[] generic = field.DeclaringType.GetGenericArguments(); AddToBody( Rule.MakeReturn(Binder, MakeReturnValue( Ast.Call( typeof(BinderOps).GetMethod("UpdateBox").MakeGenericMethod(generic), Ast.ConvertHelper(Instance, field.DeclaringType), Ast.ConvertHelper(Rule.Parameters[1], generic[0]) ) ) ) ); } else if (field.IsInitOnly || field.IsLiteral || (field.IsStatic && targetType != field.DeclaringType)) // TODO: Field static check too python specific { AddToBody(Binder.MakeReadOnlyMemberError(Rule, targetType, StringName)); } else if (field.DeclaringType.IsValueType) { AddToBody(Rule.MakeError(Ast.New(typeof(ArgumentException).GetConstructor(new Type[] { typeof(string) }), Ast.Constant("cannot assign to value types")))); } else if (field.IsPublic && field.DeclaringType.IsVisible) { AddToBody( Rule.MakeReturn( Binder, MakeReturnValue( Ast.AssignField( field.IsStatic ? null : Ast.Convert(Rule.Parameters[0], field.DeclaringType), field.Field, Binder.ConvertExpression(Rule.Parameters[1], field.FieldType) ) ) ) ); } else { AddToBody( Rule.MakeReturn( Binder, MakeReturnValue( Ast.Call( Ast.ConvertHelper(Ast.RuntimeConstant(field.Field), typeof(FieldInfo)), typeof(FieldInfo).GetMethod("SetValue", new Type[] { typeof(object), typeof(object) }), field.IsStatic ? Ast.Null() : (Expression)Ast.ConvertHelper(Instance, typeof(object)), Ast.ConvertHelper(Rule.Parameters[1], typeof(object)) ) ) ) ); } }
public static MemberTracker FromMemberInfo(MemberInfo member, Type extending) { ContractUtils.RequiresNotNull(member, "member"); lock (_trackers) { MemberTracker res; MemberKey key = new MemberKey(member, extending); if (_trackers.TryGetValue(key, out res)) { return res; } ConstructorInfo ctor; EventInfo evnt; FieldInfo field; MethodInfo method; TypeInfo type; PropertyInfo property; if ((method = member as MethodInfo) != null) { if (extending != null) { res = new ExtensionMethodTracker(method, member.IsDefined(typeof(StaticExtensionMethodAttribute), false), extending); } else { res = new MethodTracker(method); } } else if ((ctor = member as ConstructorInfo) != null) { res = new ConstructorTracker(ctor); } else if ((field = member as FieldInfo) != null) { res = new FieldTracker(field); } else if ((property = member as PropertyInfo) != null) { res = new ReflectedPropertyTracker(property); } else if ((evnt = member as EventInfo) != null) { res = new EventTracker(evnt); } else if ((type = member as TypeInfo) != null) { res = new NestedTypeTracker(type.AsType()); } else { throw Error.UnknownMemberType(member); } _trackers[key] = res; return res; } }
private void MakeFieldRule(Type targetType, MemberGroup fields) { FieldTracker field = (FieldTracker)fields[0]; if (field.DeclaringType.IsGenericType && field.DeclaringType.GetGenericTypeDefinition() == typeof(StrongBox <>)) { // work around a CLR bug where we can't access generic fields from dynamic methods. Type[] generic = field.DeclaringType.GetGenericArguments(); AddToBody( Rule.MakeReturn(Binder, MakeReturnValue( Ast.Assign( Ast.Field( AstUtils.Convert(Instance, field.DeclaringType), field.DeclaringType.GetField("Value") ), AstUtils.Convert(Rule.Parameters[1], generic[0]) ) ) ) ); } else if (field.IsInitOnly || field.IsLiteral) { AddToBody(Binder.MakeReadOnlyMemberError(Rule, targetType, StringName)); } else if (field.IsStatic && targetType != field.DeclaringType) { AddToBody(Binder.MakeStaticAssignFromDerivedTypeError(targetType, field, Rule.Parameters[1], Rule.Context).MakeErrorForRule(Rule, Binder)); } else if (field.DeclaringType.IsValueType && !field.IsStatic) { AddToBody(Rule.MakeError(Ast.New(typeof(ArgumentException).GetConstructor(new Type[] { typeof(string) }), Ast.Constant("cannot assign to value types")))); } else if (field.IsPublic && field.DeclaringType.IsVisible) { AddToBody( Rule.MakeReturn( Binder, MakeReturnValue( Ast.Assign( Ast.Field( field.IsStatic ? null : Ast.Convert(Rule.Parameters[0], field.DeclaringType), field.Field ), Binder.ConvertExpression(Rule.Parameters[1], field.FieldType, ConversionResultKind.ExplicitCast, Rule.Context) ) ) ) ); } else { AddToBody( Rule.MakeReturn( Binder, MakeReturnValue( Ast.Call( AstUtils.Convert(Ast.Constant(field.Field), typeof(FieldInfo)), typeof(FieldInfo).GetMethod("SetValue", new Type[] { typeof(object), typeof(object) }), field.IsStatic ? Ast.Constant(null) : (Expression)AstUtils.Convert(Instance, typeof(object)), AstUtils.Convert(Rule.Parameters[1], typeof(object)) ) ) ) ); } }