private bool TryGetLazyValue(string name, bool publish, out object value)
        {
            if (!_cleared)
            {
                MemberInfo[] members = NonHiddenMembers(GetMember(name));
                if (members.Length > 0)
                {
                    // we only support fields, methods, and nested types in modules.
                    switch (members[0].MemberType)
                    {
                    case MemberTypes.Field:
                        Debug.Assert(members.Length == 1);

                        var fieldInfo = (FieldInfo)members[0];
                        if (fieldInfo.IsStatic)
                        {
                            value = ((FieldInfo)members[0]).GetValue(null);
                        }
                        else
                        {
                            throw new InvalidOperationException("instance field declared on module.  Fields should stored as PythonGlobals, should be static readonly, or marked as PythonHidden.");
                        }

                        if (publish)
                        {
                            LazyAdd(name, value);
                        }
                        return(true);

                    case MemberTypes.Method:
                        if (!((MethodInfo)members[0]).IsSpecialName)
                        {
                            var          methods = new MethodInfo[members.Length];
                            FunctionType ft      = FunctionType.ModuleMethod | FunctionType.AlwaysVisible;
                            for (int i = 0; i < members.Length; i++)
                            {
                                var method = (MethodInfo)members[i];
                                if (method.IsStatic)
                                {
                                    ft |= FunctionType.Function;
                                }
                                else
                                {
                                    ft |= FunctionType.Method;
                                }

                                methods[i] = method;
                            }

                            var builtinFunc = BuiltinFunction.MakeMethod(
                                name,
                                methods,
                                members[0].DeclaringType,
                                ft
                                );

                            if ((ft & FunctionType.Method) != 0 && Instance != null)
                            {
                                value = builtinFunc.BindToInstance(Instance);
                            }
                            else
                            {
                                value = builtinFunc;
                            }

                            if (publish)
                            {
                                LazyAdd(name, value);
                            }
                            return(true);
                        }
                        break;

                    case MemberTypes.Property:
                        Debug.Assert(members.Length == 1);

                        var propInfo = (PropertyInfo)members[0];
                        if ((propInfo.GetGetMethod() ?? propInfo.GetSetMethod()).IsStatic)
                        {
                            value = ((PropertyInfo)members[0]).GetValue(null, ArrayUtils.EmptyObjects);
                        }
                        else
                        {
                            throw new InvalidOperationException("instance property declared on module.  Propreties should be declared as static, marked as PythonHidden, or you should use a PythonGlobal.");
                        }

                        if (publish)
                        {
                            LazyAdd(name, value);
                        }

                        return(true);

                    case MemberTypes.NestedType:
                        if (members.Length == 1)
                        {
                            value = DynamicHelpers.GetPythonTypeFromType((Type)members[0]);
                        }
                        else
                        {
                            TypeTracker tt = (TypeTracker)MemberTracker.FromMemberInfo(members[0]);
                            for (int i = 1; i < members.Length; i++)
                            {
                                tt = TypeGroup.UpdateTypeEntity(tt, (TypeTracker)MemberTracker.FromMemberInfo(members[i]));
                            }

                            value = tt;
                        }

                        if (publish)
                        {
                            LazyAdd(name, value);
                        }
                        return(true);
                    }
                }
            }

            value = null;
            return(false);
        }
示例#2
0
 static bool IsTrackerApplicableForType(Type type, MemberTracker mt)
 {
     return(mt.DeclaringType == type || type.IsSubclassOf(mt.DeclaringType));
 }
示例#3
0
        private bool TryGetLazyValue(string name, bool publish, out object value)
        {
            if (!_cleared)
            {
                MemberInfo[] members = NonHiddenMembers(GetMember(name));
                if (members.Length > 0)
                {
                    // we only support fields, methods, and nested types in modules.
                    switch (members[0].MemberType)
                    {
                    case MemberTypes.Field:
                        Debug.Assert(members.Length == 1);

                        value = ((FieldInfo)members[0]).GetValue(null);
                        if (publish)
                        {
                            LazyAdd(name, value);
                        }
                        return(true);

                    case MemberTypes.Method:
                        if (!((MethodInfo)members[0]).IsSpecialName)
                        {
                            value = BuiltinFunction.MakeFunction(
                                name,
                                ArrayUtils.ConvertAll <MemberInfo, MethodInfo>(members, delegate(MemberInfo mi) { return((MethodInfo)mi); }),
                                members[0].DeclaringType
                                );

                            if (publish)
                            {
                                LazyAdd(name, value);
                            }
                            return(true);
                        }
                        break;

                    case MemberTypes.Property:
                        Debug.Assert(members.Length == 1);

                        value = ((PropertyInfo)members[0]).GetValue(null, ArrayUtils.EmptyObjects);

                        if (publish)
                        {
                            LazyAdd(name, value);
                        }

                        return(true);

                    case MemberTypes.NestedType:
                        if (members.Length == 1)
                        {
                            value = DynamicHelpers.GetPythonTypeFromType((Type)members[0]);
                        }
                        else
                        {
                            TypeTracker tt = (TypeTracker)MemberTracker.FromMemberInfo(members[0]);
                            for (int i = 1; i < members.Length; i++)
                            {
                                tt = TypeGroup.UpdateTypeEntity(tt, (TypeTracker)MemberTracker.FromMemberInfo(members[i]));
                            }

                            value = tt;
                        }

                        if (publish)
                        {
                            LazyAdd(name, value);
                        }
                        return(true);
                    }
                }
            }

            value = null;
            return(false);
        }