/// <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(); } }
/// <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> /// Creates an ErrorInfo object when a static property is accessed from an instance member. The default behavior is throw /// an exception indicating that static members properties be accessed via an instance. Languages can override this to /// customize the exception, message, or to produce an ErrorInfo object which reads or writes to the property being accessed. /// </summary> /// <param name="tracker">The static property being accessed through an instance</param> /// <param name="isAssignment">True if the user is assigning to the property, false if the user is reading from the property</param> /// <param name="parameters">The parameters being used to access the property. This includes the instance as the first entry, any index parameters, and the /// value being assigned as the last entry if isAssignment is true.</param> /// <returns></returns> public virtual ErrorInfo MakeStaticPropertyInstanceAccessError(PropertyTracker tracker, bool isAssignment, IList <DynamicMetaObject> parameters) { ContractUtils.RequiresNotNull(tracker, "tracker"); ContractUtils.Requires(tracker.IsStatic, "tracker", Strings.ExpectedStaticProperty); ContractUtils.RequiresNotNull(parameters, "parameters"); ContractUtils.RequiresNotNullItems(parameters, "parameters"); string message = isAssignment ? Strings.StaticAssignmentFromInstanceError(tracker.Name, tracker.DeclaringType.Name) : Strings.StaticAccessFromInstanceError(tracker.Name, tracker.DeclaringType.Name); return(ErrorInfo.FromException( Expression.New( typeof(MissingMemberException).GetConstructor(new[] { typeof(string) }), AstUtils.Constant(message) ) )); }
public ErrorInfo MakeStaticPropertyInstanceAccessError(PropertyTracker tracker, bool isAssignment, params DynamicMetaObject[] parameters) { return(MakeStaticPropertyInstanceAccessError(tracker, isAssignment, (IList <DynamicMetaObject>)parameters)); }
private static Expression ReturnPropertyTracker(PropertyTracker propertyTracker, bool privateBinding) { return Ast.Constant(PythonTypeOps.GetReflectedProperty(propertyTracker, null, privateBinding)); }
private static bool IsPropertyDefaultMember(PropertyTracker pt) { foreach (MemberInfo mem in pt.DeclaringType.GetDefaultMembers()) { if (mem.Name == pt.Name) { return true; } } return false; }
private void MakePropertyRule(SetOrDeleteMemberInfo memInfo, DynamicMetaObject instance, DynamicMetaObject target, Type targetType, MemberGroup properties, DynamicMetaObject errorSuggestion) { PropertyTracker info = (PropertyTracker)properties[0]; MethodInfo setter = info.GetSetMethod(true); // Allow access to protected getters TODO: this should go, it supports IronPython semantics. if (setter != null && !setter.IsPublic && !setter.IsProtected()) { if (!PrivateBinding) { setter = null; } } if (setter != null) { setter = CompilerHelpers.GetCallableMethod(setter, PrivateBinding); if (info.IsStatic != (instance == null)) { memInfo.Body.FinishCondition( errorSuggestion ?? MakeError( MakeStaticPropertyInstanceAccessError( info, true, instance, target ), typeof(object) ) ); } else if (info.IsStatic && info.DeclaringType != targetType) { memInfo.Body.FinishCondition( errorSuggestion ?? MakeError( MakeStaticAssignFromDerivedTypeError(targetType, instance, info, target, memInfo.ResolutionFactory), typeof(object) ) ); } else if (setter.ContainsGenericParameters) { memInfo.Body.FinishCondition( MakeGenericPropertyExpression(memInfo) ); } else if (setter.IsPublic && !setter.DeclaringType.IsValueType) { if (instance == null) { memInfo.Body.FinishCondition( Ast.Block( AstUtils.SimpleCallHelper( setter, ConvertExpression( target.Expression, setter.GetParameters()[0].ParameterType, ConversionResultKind.ExplicitCast, memInfo.ResolutionFactory ) ), Ast.Constant(null) ) ); } else { memInfo.Body.FinishCondition( MakeReturnValue( MakeCallExpression(memInfo.ResolutionFactory, setter, instance, target), target ) ); } } else { // TODO: Should be able to do better w/ value types. memInfo.Body.FinishCondition( MakeReturnValue( Ast.Call( AstUtils.Constant(((ReflectedPropertyTracker)info).Property), // TODO: Private binding on extension properties typeof(PropertyInfo).GetMethod("SetValue", new Type[] { typeof(object), typeof(object), typeof(object[]) }), instance == null ? AstUtils.Constant(null) : AstUtils.Convert(instance.Expression, typeof(object)), AstUtils.Convert( ConvertExpression( target.Expression, setter.GetParameters()[0].ParameterType, ConversionResultKind.ExplicitCast, memInfo.ResolutionFactory ), typeof(object) ), Ast.NewArrayInit(typeof(object)) ), target ) ); } } else { memInfo.Body.FinishCondition( errorSuggestion ?? MakeError( MakeMissingMemberErrorForAssignReadOnlyProperty(targetType, instance, memInfo.Name), typeof(object) ) ); } }
public override ErrorInfo/*!*/ MakeStaticPropertyInstanceAccessError(PropertyTracker/*!*/ tracker, bool isAssignment, IList<Expression/*!*/>/*!*/ parameters) { ContractUtils.RequiresNotNull(tracker, "tracker"); ContractUtils.RequiresNotNull(parameters, "parameters"); ContractUtils.RequiresNotNullItems(parameters, "parameters"); if (isAssignment) { return ErrorInfo.FromException( Ast.Call( typeof(PythonOps).GetMethod("StaticAssignmentFromInstanceError"), Ast.Constant(tracker), Ast.Constant(isAssignment) ) ); } return ErrorInfo.FromValue( Ast.Property( null, tracker.GetGetMethod(DomainManager.Configuration.PrivateBinding) ) ); }
public ErrorInfo MakeStaticPropertyInstanceAccessError(PropertyTracker tracker, bool isAssignment, params DynamicMetaObject[] parameters) { return MakeStaticPropertyInstanceAccessError(tracker, isAssignment, (IList<DynamicMetaObject>)parameters); }
/// <summary> /// Creates an ErrorInfo object when a static property is accessed from an instance member. The default behavior is throw /// an exception indicating that static members properties be accessed via an instance. Languages can override this to /// customize the exception, message, or to produce an ErrorInfo object which reads or writes to the property being accessed. /// </summary> /// <param name="tracker">The static property being accessed through an instance</param> /// <param name="isAssignment">True if the user is assigning to the property, false if the user is reading from the property</param> /// <param name="parameters">The parameters being used to access the property. This includes the instance as the first entry, any index parameters, and the /// value being assigned as the last entry if isAssignment is true.</param> /// <returns></returns> public virtual ErrorInfo MakeStaticPropertyInstanceAccessError(PropertyTracker tracker, bool isAssignment, IList<DynamicMetaObject> parameters) { ContractUtils.RequiresNotNull(tracker, "tracker"); ContractUtils.Requires(tracker.IsStatic, "tracker", Strings.ExpectedStaticProperty); ContractUtils.RequiresNotNull(parameters, "parameters"); ContractUtils.RequiresNotNullItems(parameters, "parameters"); string message = isAssignment ? Strings.StaticAssignmentFromInstanceError(tracker.Name, tracker.DeclaringType.Name) : Strings.StaticAccessFromInstanceError(tracker.Name, tracker.DeclaringType.Name); return ErrorInfo.FromException( Expression.New( typeof(MissingMemberException).GetConstructor(new[] { typeof(string) }), AstUtils.Constant(message) ) ); }
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 && getter.IsDefined(typeof(PythonHiddenAttribute), true)) || setter != null && setter.IsDefined(typeof(PythonHiddenAttribute), 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) || rpt.Property.IsDefined(typeof(PythonHiddenAttribute), 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; } }
public ErrorInfo MakeStaticPropertyInstanceAccessError(PropertyTracker tracker, bool isAssignment, params Expression[] parameters) { return MakeStaticPropertyInstanceAccessError(tracker, isAssignment, (IList<Expression>)parameters); }
private void MakePropertyRule(Type targetType, MemberGroup properties) { PropertyTracker info = (PropertyTracker)properties[0]; MethodInfo setter = info.GetSetMethod(true); // Allow access to protected getters TODO: this should go, it supports IronPython semantics. if (setter != null && !setter.IsPublic && !(setter.IsFamily || setter.IsFamilyOrAssembly)) { if (!ScriptDomainManager.Options.PrivateBinding) { setter = null; } } if (setter != null) { setter = CompilerHelpers.GetCallableMethod(setter); if (info.IsStatic != _isStatic) { // TODO: Too python specific AddToBody(Binder.MakeReadOnlyMemberError(Rule, targetType, StringName)); } else if (setter.ContainsGenericParameters) { AddToBody(Rule.MakeError(MakeGenericPropertyExpression())); } else if (setter.IsPublic && !setter.DeclaringType.IsValueType) { if (_isStatic) { AddToBody( Rule.MakeReturn( Binder, Ast.SimpleCallHelper( setter, Binder.ConvertExpression( Rule.Parameters[1], setter.GetParameters()[0].ParameterType ) ) ) ); } else { AddToBody(Rule.MakeReturn(Binder, MakeReturnValue(Binder.MakeCallExpression(setter, Rule.Parameters)))); } } else { // TODO: Should be able to do better w/ value types. AddToBody( Rule.MakeReturn( Binder, MakeReturnValue( Ast.Call( Ast.RuntimeConstant(((ReflectedPropertyTracker)info).Property), // TODO: Private binding on extension properties typeof(PropertyInfo).GetMethod("SetValue", new Type[] { typeof(object), typeof(object), typeof(object[]) }), Ast.ConvertHelper(Instance, typeof(object)), Ast.ConvertHelper(Rule.Parameters[1], typeof(object)), Ast.NewArray(typeof(object[])) ) ) ) ); } } else { AddToBody(Binder.MakeMissingMemberError(Rule, targetType, StringName)); } }
public ErrorInfo MakeStaticPropertyInstanceAccessError(PropertyTracker tracker, bool isAssignment, params Expression[] parameters) { return(MakeStaticPropertyInstanceAccessError(tracker, isAssignment, (IList <Expression>)parameters)); }
private void MakePropertyRule(Type targetType, MemberGroup properties) { PropertyTracker info = (PropertyTracker)properties[0]; MethodInfo setter = info.GetSetMethod(true); // Allow access to protected getters TODO: this should go, it supports IronPython semantics. if (setter != null && !setter.IsPublic && !(setter.IsFamily || setter.IsFamilyOrAssembly)) { if (!PrivateBinding) { setter = null; } } if (setter != null) { setter = CompilerHelpers.GetCallableMethod(setter, Binder.PrivateBinding); if (info.IsStatic != _isStatic) { AddToBody(Binder.MakeStaticPropertyInstanceAccessError(info, true, Rule.Parameters).MakeErrorForRule(Rule, Binder)); } else if (info.IsStatic && info.DeclaringType != targetType) { AddToBody(Binder.MakeStaticAssignFromDerivedTypeError(targetType, info, Rule.Parameters[1], Rule.Context).MakeErrorForRule(Rule, Binder)); } else if (setter.ContainsGenericParameters) { AddToBody(Rule.MakeError(MakeGenericPropertyExpression())); } else if (setter.IsPublic && !setter.DeclaringType.IsValueType) { if (_isStatic) { AddToBody( Rule.MakeReturn( Binder, AstUtils.SimpleCallHelper( setter, Binder.ConvertExpression( Rule.Parameters[1], setter.GetParameters()[0].ParameterType, ConversionResultKind.ExplicitCast, Rule.Context ) ) ) ); } else { AddToBody(Rule.MakeReturn(Binder, MakeReturnValue(Binder.MakeCallExpression(Rule.Context, setter, Rule.Parameters)))); } } else { // TODO: Should be able to do better w/ value types. AddToBody( Rule.MakeReturn( Binder, MakeReturnValue( Ast.Call( Ast.Constant(((ReflectedPropertyTracker)info).Property), // TODO: Private binding on extension properties typeof(PropertyInfo).GetMethod("SetValue", new Type[] { typeof(object), typeof(object), typeof(object[]) }), AstUtils.Convert(Instance, typeof(object)), AstUtils.Convert(Rule.Parameters[1], typeof(object)), Ast.NewArrayInit(typeof(object)) ) ) ) ); } } else { AddToBody(Binder.MakeMissingMemberError(targetType, StringName).MakeErrorForRule(Rule, Binder)); } }