Beispiel #1
0
        private Type InternalEmitType(TypeInfo typeInfo)
        {
            var fullName = CreateUniqueClassName();

            var propertyInfos = typeInfo.Properties.ToArray();

            // define type
            var type = _module.DefineType(fullName, TypeAttributes.Public | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.Sealed, typeof(object));

            type.SetCustomAttribute(new CustomAttributeBuilder(typeof(EmittedTypeAttribute).GetConstructor(new Type[0]), new object[0]));
            type.SetCustomAttribute(new CustomAttributeBuilder(typeof(CompilerGeneratedAttribute).GetConstructor(new Type[0]), new object[0]));

            // define fields
            var fields = propertyInfos
                         .Select(x => type.DefineField($"_{x.Name}", x.PropertyType.Type, FieldAttributes.Private))
                         .ToArray();

            // define default constructor
            var constructor = type.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, null);
            var objectCtor  = typeof(object).GetConstructor(Type.EmptyTypes);
            var il          = constructor.GetILGenerator();

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Call, objectCtor);
            il.Emit(OpCodes.Ret);

            // define properties
            var properties = propertyInfos
                             .Select((x, i) =>
            {
                var property = type.DefineProperty(x.Name, PropertyAttributes.HasDefault, x.PropertyType.Type, null);

                var propertyGetter = type.DefineMethod($"get_{x.Name}", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, x.PropertyType.Type, null);
                var getterPil      = propertyGetter.GetILGenerator();
                getterPil.Emit(OpCodes.Ldarg_0);
                getterPil.Emit(OpCodes.Ldfld, fields[i]);
                getterPil.Emit(OpCodes.Ret);

                property.SetGetMethod(propertyGetter);

                var propertySetter = type.DefineMethod($"set_{x.Name}", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null, new[] { x.PropertyType.Type });
                var setterPil      = propertySetter.GetILGenerator();
                setterPil.Emit(OpCodes.Ldarg_0);
                setterPil.Emit(OpCodes.Ldarg_1);
                setterPil.Emit(OpCodes.Stfld, fields[i]);
                setterPil.Emit(OpCodes.Ret);

                property.SetSetMethod(propertySetter);

                return(property);
            })
                             .ToArray();

            // create type
            var t1 = type.CreateTypeInfo();

            return(t1.AsType());
        }
Beispiel #2
0
        private Type InternalEmitType(TypeInfo typeInfo)
        {
            var fullName = CreateUniqueClassName();

            var propertyInfos = typeInfo.Properties?
                                .Select(x => new
            {
                Name = x.Name ?? throw new ArgumentException($"Property name must not be empty for type {typeInfo}."),
                Type = x.PropertyType.ResolveType(_typeResolver) ?? throw new ArgumentException($"Property type must not be null for type {typeInfo}."),
            })
Beispiel #3
0
 public Type EmitType(TypeInfo typeInfo)
 {
     if (typeInfo.IsAnonymousType)
     {
         var properties = typeInfo.Properties.Select(x => x.Name).ToList();
         return(_typeCache.GetOrCreate(properties, InternalEmitAnonymousType));
     }
     else
     {
         return(_typeCache.GetOrCreate(typeInfo, InternalEmitType));
     }
 }
Beispiel #4
0
 public Type EmitType(TypeInfo typeInfo)
 {
     if (typeInfo.IsAnonymousType)
     {
         var properties = typeInfo.Properties.Select(x => x.Name).ToList();
         return _typeCache.GetOrCreate(properties, InternalEmitAnonymousType);
     }
     else
     {
         return _typeCache.GetOrCreate(typeInfo, InternalEmitType);
     }
 }
        public void Should_throw()
        {
            var typeInfo = new TypeInfo
            {
                Name      = "TestClass",
                Namespace = "TestNamespace",
            };

            typeInfo.Properties = new List <PropertyInfo>
            {
                new PropertyInfo("CircularReference", typeInfo, typeInfo),
            };

            var ex = Should.Throw <TypeEmitterException>(() => new TypeEmitter().EmitType(typeInfo));

            ex.Message.ShouldBe("Cannot emit type with circular reference: 'TestNamespace.TestClass'");
        }
Beispiel #6
0
        public Type EmitType(TypeInfo type)
        {
            Func <Type> emit;

            if (type.CheckNotNull(nameof(type)).IsAnonymousType)
            {
                Exception CreateException(string reason) => throw new ArgumentException($"Cannot emit anonymous type '{type}' {reason}.");

                var properties = type.Properties?
                                 .Select(x => x.Name ?? throw new ArgumentException("with unnamed property contained"))
                                 .ToList();
                if (properties is null)
                {
                    throw CreateException("with not proeprties declared");
                }

                emit = () => _typeCache.GetOrCreate(properties, InternalEmitAnonymousType);
            }
            else
            {
                emit = () => _typeCache.GetOrCreate(type, InternalEmitType);
            }

            try
            {
                return(emit());
            }
            catch (Exception ex)
            {
                var innerException = ex;
                while (innerException is not null)
                {
                    if (innerException is TypeEmitterException typeEmitterException)
                    {
                        throw typeEmitterException;
                    }

                    innerException = innerException.InnerException;
                }

                throw new TypeEmitterException($"Failed to emit type {type}", ex);
            }
        }
Beispiel #7
0
        public Type EmitType(TypeInfo typeInfo)
        {
            if (typeInfo.IsAnonymousType)
            {
                Exception CreateException(string reason) => throw new ArgumentException($"Cannot emit anonymous type '{typeInfo}' {reason}.");

                var properties = typeInfo.Properties?
                                 .Select(x => x.Name ?? throw new ArgumentException("with unnamed property contained"))
                                 .ToList();
                if (properties is null)
                {
                    throw CreateException("with not proeprties declared");
                }

                return(_typeCache.GetOrCreate(properties, InternalEmitAnonymousType));
            }

            return(_typeCache.GetOrCreate(typeInfo, InternalEmitType));
        }
Beispiel #8
0
        public When_emitting_type()
        {
            var typeInfo = new TypeInfo
            {
                Name       = "TestClass",
                Namespace  = "TestNamespace",
                Properties = new List <PropertyInfo>
                {
                    new PropertyInfo {
                        Name = "Int32Value", PropertyType = new TypeInfo(typeof(int))
                    },
                    new PropertyInfo {
                        Name = "StringValue", PropertyType = new TypeInfo(typeof(string))
                    },
                },
            };

            emittedType = new TypeEmitter().EmitType(typeInfo);
        }
 public ConstantQueryArgument(TypeInfo type)
     : base(type)
 {
 }
Beispiel #10
0
 public When_creating_type_info_of_generic_type_definition()
 {
     typeInfo = new TypeInfo(typeof(A <>));
 }
Beispiel #11
0
 public static ConstantExpression Constant(object value, Aqua.TypeSystem.TypeInfo type)
 {
     return(new ConstantExpression(value, type));
 }
Beispiel #12
0
        private Type InternalEmitType(TypeInfo typeInfo)
        {
            var fullName = CreateUniqueClassName();

            var propertyInfos = typeInfo.Properties.ToArray();

            // define type
            var type = _module.DefineType(fullName, TypeAttributes.Public | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.Sealed, typeof(object));

            type.SetCustomAttribute(new CustomAttributeBuilder(typeof(EmittedTypeAttribute).GetConstructor(new Type[0]), new object[0]));
            type.SetCustomAttribute(new CustomAttributeBuilder(typeof(CompilerGeneratedAttribute).GetConstructor(new Type[0]), new object[0]));

            // define fields
            var fields = propertyInfos
                .Select(x => type.DefineField($"_{x.Name}", x.PropertyType.Type, FieldAttributes.Private))
                .ToArray();

            // define default constructor
            var constructor = type.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, null);
            var objectCtor = typeof(object).GetConstructor(Type.EmptyTypes);
            var il = constructor.GetILGenerator();
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Call, objectCtor);
            il.Emit(OpCodes.Ret);

            // define properties
            var properties = propertyInfos
                .Select((x, i) =>
                {
                    var property = type.DefineProperty(x.Name, PropertyAttributes.HasDefault, x.PropertyType.Type, null);

                    var propertyGetter = type.DefineMethod($"get_{x.Name}", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, x.PropertyType.Type, null);
                    var getterPil = propertyGetter.GetILGenerator();
                    getterPil.Emit(OpCodes.Ldarg_0);
                    getterPil.Emit(OpCodes.Ldfld, fields[i]);
                    getterPil.Emit(OpCodes.Ret);

                    property.SetGetMethod(propertyGetter);

                    var propertySetter = type.DefineMethod($"set_{x.Name}", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null, new[] { x.PropertyType.Type });
                    var setterPil = propertySetter.GetILGenerator();
                    setterPil.Emit(OpCodes.Ldarg_0);
                    setterPil.Emit(OpCodes.Ldarg_1);
                    setterPil.Emit(OpCodes.Stfld, fields[i]);
                    setterPil.Emit(OpCodes.Ret);

                    property.SetSetMethod(propertySetter);

                    return property;
                })
                .ToArray();

            // create type
            var t1 = type.CreateTypeInfo();
            return t1.AsType();
        }