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()); }
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}."), })
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 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'"); }
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); } }
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)); }
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) { }
public When_creating_type_info_of_generic_type_definition() { typeInfo = new TypeInfo(typeof(A <>)); }
public static ConstantExpression Constant(object value, Aqua.TypeSystem.TypeInfo type) { return(new ConstantExpression(value, type)); }
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(); }