예제 #1
0
 internal NestedTypeGetter(CLRClass klass)
 {
     this.klass = klass;
 }
예제 #2
0
        internal static CLRClass Define(System.Type type, CLRClass klass)
        {
            // TODO: (writer) lock ?
            CLRClass existing;
            if (cache.TryGetValue(type, out existing))
                return existing;

            cache[type] = klass;
            return klass;
        }
예제 #3
0
        internal static CLRClass Load(System.Type type, Frame caller, bool makeConstant)
        {
            if (type == null)
                return null;

            CLRClass klass;
            if (!TryLoad(type, out klass))
            {
                System.Type baseType = type.BaseType;
                CLRClass baseClass = baseType == null 
                    ? null
                    : Load(baseType, caller, makeConstant && baseType.Assembly == type.Assembly);

                if (baseClass != null)
                {
                    klass = new CLRClass(type, baseClass, Type.Class);
                    klass.my_class = new CLRClass(type, baseClass.my_class, Type.IClass);

                    System.Type[] inherited = baseType.GetInterfaces();
                    foreach (System.Type iface in type.GetInterfaces())
                    {
                        if (0 > System.Array.IndexOf(inherited, iface))
                            Class.rb_include_module(caller, klass, Load(iface, caller, false));
                    }
                }
                else
                {
                    if (type.IsInterface)
                    {
                        klass = new CLRClass(type, null, Type.Module);
                        klass.my_class = new CLRClass(type, Init.rb_cModule, Type.IClass);
                    }
                    else
                    {
                        klass = new CLRClass(type, Init.rb_cObject, Type.Class);
                        klass.my_class = new CLRClass(type, Init.rb_cClass, Type.IClass);
                    }

                    foreach (System.Type iface in type.GetInterfaces())
                        Class.rb_include_module(caller, klass, Load(iface, caller, false));
                }

                Augmentations.Augment(type, klass, caller);
                klass = Define(type, klass);
            }

            if (makeConstant)
            {
                Class context = context = Ruby.Runtime.Init.rb_cObject;
                if (type.Namespace != null)
                {
                    foreach (string Namespace in type.Namespace.Split('.'))
                    {
                        Class innerContext;
                        string constant = FormatConstant(Namespace);

                        if (context.const_defined(constant, false) && (innerContext = context.const_get(constant, caller) as Class) != null)
                            context = innerContext;
                        else
                            context.define_const(constant, context = new CLRNamespace(Namespace));
                    }
                }

                if (type.IsNested)
                {
                    // nested types can be loaded by a getter in their owner
                    // ruby: Namespace::Type.InnerType
                }
                else if (type.IsGenericTypeDefinition)
                {
                    string name = type.Name.Substring(0, type.Name.LastIndexOf('`'));
                    string containerName =
                        type.Namespace == null
                        ? name
                        : type.Namespace + "." + name;

                    // if a non-generic type exists with the same name
                    // we can use that in the construction of a generic type
                    System.Type container = type.Assembly.GetType(containerName);

                    // otherwise we much build a GenericContainer
                    if (container == null)
                    {
                        string constant = FormatConstant(name);
                        if (!context.const_defined(constant))
                            context.define_const(constant, new GenericContainer(type.Assembly, containerName, null));
                    }
                }
                else
                {
                    context.define_const(FormatConstant(type.Name), klass);
                }
            }

            return klass;
        }
예제 #4
0
 internal static bool TryLoad(System.Type type, out CLRClass klass)
 {
     // TODO: (reader) lock ?
     return cache.TryGetValue(type, out klass);
 }