Represents a logical Property as a member of a Type. This Property can either be a real concrete Property on a type (implemented with a ReflectedPropertyTracker) or an extension property (implemented with an ExtensionPropertyTracker).
Inheritance: MemberTracker
Exemple #1
0
        /// <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();
            }
        }
Exemple #2
0
        /// <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();
            }
        }
Exemple #3
0
        /// <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)
                           )
                       ));
        }
Exemple #4
0
 public ErrorInfo MakeStaticPropertyInstanceAccessError(PropertyTracker tracker, bool isAssignment, params DynamicMetaObject[] parameters)
 {
     return(MakeStaticPropertyInstanceAccessError(tracker, isAssignment, (IList <DynamicMetaObject>)parameters));
 }
Exemple #5
0
 private static Expression ReturnPropertyTracker(PropertyTracker propertyTracker, bool privateBinding) {
     return Ast.Constant(PythonTypeOps.GetReflectedProperty(propertyTracker, null, privateBinding));
 }
Exemple #6
0
 private static bool IsPropertyDefaultMember(PropertyTracker pt) {
     foreach (MemberInfo mem in pt.DeclaringType.GetDefaultMembers()) {
         if (mem.Name == pt.Name) {
             return true;
         }
     }
     return false;
 }
Exemple #7
0
        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)
                        )
                    );
            }
        }
Exemple #8
0
        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)
                )
            );
        }
Exemple #9
0
 public ErrorInfo MakeStaticPropertyInstanceAccessError(PropertyTracker tracker, bool isAssignment, params DynamicMetaObject[] parameters) {
     return MakeStaticPropertyInstanceAccessError(tracker, isAssignment, (IList<DynamicMetaObject>)parameters);
 }
Exemple #10
0
        /// <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;
            }            
        }
Exemple #12
0
 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));
            }
        }
Exemple #14
0
 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));
            }
        }