TypeDescription captures the minimal information required by TypeDispenser to define a distinct CLS type
        internal static Type/*!*/ GetOrCreateType(Type/*!*/ baseType, IList<Type/*!*/>/*!*/ interfaces, bool noOverrides) {
            Assert.NotNull(baseType);
            Assert.NotNull(interfaces);

            ITypeFeature[] features;
            if (interfaces.Count == 0) {
                features = _defaultFeatures;
            } else {
                features = new ITypeFeature[2] {
                    RubyTypeBuilder.Feature,
                    InterfacesBuilder.MakeFeature(interfaces)
                };
            }
            noOverrides |= typeof(IRubyType).IsAssignableFrom(baseType);

            TypeDescription typeInfo = new TypeDescription(baseType, features, noOverrides);
            Type type = _newTypes.GetOrCreateValue(typeInfo,
                delegate() {
                    if (TypeImplementsFeatures(baseType, features)) {
                        return baseType;
                    }
                    return CreateType(typeInfo);
                });

            Debug.Assert(typeof(IRubyObject).IsAssignableFrom(type));
            return type;
        }
        private static Type CreateType(TypeDescription/*!*/ typeInfo) {
            Type baseType = typeInfo.BaseType;
            if (baseType.IsSealed) {
                throw new NotSupportedException("Can't inherit from a sealed type.");
            }

            string typeName = GetName(baseType);
            TypeBuilder tb = Snippets.Shared.DefinePublicType(typeName, baseType);
            Utils.Log(typeName, "TYPE_BUILDER");

            IFeatureBuilder[] features = new IFeatureBuilder[typeInfo.Features.Count];
            RubyTypeEmitter emitter = new RubyTypeEmitter(tb);

            for (int i = 0; i < typeInfo.Features.Count; i++) {
                features[i] = typeInfo.Features[i].MakeBuilder(tb);
            }

            foreach (IFeatureBuilder feature in features) {
                feature.Implement(emitter);
            }

            if (!typeInfo.NoOverrides) {
                emitter.OverrideMethods(baseType);
            }

            Type result = emitter.FinishType();
            lock (_typeFeatures) {
                _typeFeatures.Add(result, typeInfo.Features);
            }
            return result;
        }
Exemple #3
0
        private static Type CreateType(TypeDescription/*!*/ typeInfo)
        {
            Type baseType = typeInfo.BaseType;
            if (baseType.IsSealed()) {
                throw new NotSupportedException(
                    String.Format(CultureInfo.InvariantCulture, "Can't inherit from a sealed type {0}.",
                    RubyContext.GetQualifiedNameNoLock(baseType, null, false))
                );
            }

            #if FEATURE_REFEMIT
            string typeName = GetName(baseType);
            TypeBuilder tb = Snippets.Shared.DefinePublicType(typeName, baseType);
            Utils.Log(typeName, "TYPE_BUILDER");

            IFeatureBuilder[] features = new IFeatureBuilder[typeInfo.Features.Count];
            RubyTypeEmitter emitter = new RubyTypeEmitter(tb);

            for (int i = 0; i < typeInfo.Features.Count; i++) {
                features[i] = typeInfo.Features[i].MakeBuilder(tb);
            }

            foreach (IFeatureBuilder feature in features) {
                feature.Implement(emitter);
            }

            if (!typeInfo.NoOverrides) {
                emitter.OverrideMethods(baseType);
            }

            Type result = emitter.FinishType();
            lock (_typeFeatures) {
                _typeFeatures.Add(result, typeInfo.Features);
            }
            return result;
            #else
            throw new NotSupportedException("Creating new CLR types is not supported on this platform.");
            #endif
        }