public void SetUp() { grinderContextMock = TestHelpers.TestUtils.CreateContextMock(); loggerMock = TestHelpers.TestUtils.CreateLoggerMock(); grinderContextMock.Setup(c => c.ScriptFile).Returns(TestHelpers.TestUtils.TestsAsScriptFile); grinderContextMock.Setup(c => c.GetLogger(typeof(AbstractGrinderElementTests.TestElement))).Returns(loggerMock.Object); typeHelper = new TypeHelper(grinderContextMock.Object); }
public void Initialize() { if (GrinderContext == null) { throw new AwarenessException("GrinderContext == null"); } Logger = new LoggerFacade(GrinderContext.GetLogger(GetType()), GrinderContext); Logger.Trace("Initialize: Enter"); TypeHelper = new TypeHelper(GrinderContext); OnInitialize(); Logger.Trace("Initialize: Exit"); }
private void CreateInitContextLazyInstance( FieldBuilder field, TypeHelper fieldType, TypeHelper objectType, EmitHelper emit, object[] parameters) { if (!CheckObjectHolderCtor(fieldType, objectType)) return; LocalBuilder initField = emit.DeclareLocal(InitContextType); emit .newobj (InitContextType.GetPublicDefaultConstructor()) .dup .ldarg_0 .callvirt (InitContextType.GetProperty("Parent").GetSetMethod()) .dup .ldc_i4_1 .callvirt (InitContextType.GetProperty("IsInternal").GetSetMethod()) .dup .ldc_i4_1 .callvirt (InitContextType.GetProperty("IsLazyInstance").GetSetMethod()) ; if (parameters != null) { emit .dup .ldsfld (GetParameterField()) .callvirt (InitContextType.GetProperty("MemberParameters").GetSetMethod()) ; } emit .stloc (initField); if (objectType.IsAbstract) { emit .ldarg_0 .ldsfld (GetTypeAccessorField()) .ldloc (initField) .callvirtNoGenerics (typeof(TypeAccessor), "CreateInstanceEx", _initContextType) .isinst (objectType) ; } else { emit .ldarg_0 .ldloc (initField) .newobj (objectType.GetPublicConstructor(typeof(InitContext))) ; } if (IsObjectHolder) { emit .newobj (fieldType, objectType) ; } emit .stfld (field) ; }
private void BuildLazyInstanceEnsurer() { string fieldName = GetFieldName(); FieldBuilder field = Context.GetField(fieldName); TypeHelper fieldType = new TypeHelper(field.FieldType); TypeHelper objectType = new TypeHelper(GetObjectType()); MethodBuilderHelper ensurer = Context.TypeBuilder.DefineMethod( string.Format("$EnsureInstance{0}", fieldName), MethodAttributes.Private | MethodAttributes.HideBySig); EmitHelper emit = ensurer.Emitter; Label end = emit.DefineLabel(); emit .ldarg_0 .ldfld (field) .brtrue_s (end) ; object[] parameters = TypeHelper.GetPropertyParameters(Context.CurrentProperty); ConstructorInfo ci = objectType.GetPublicConstructor(typeof(InitContext)); if (ci != null || objectType.IsAbstract) CreateInitContextLazyInstance(field, fieldType, objectType, emit, parameters); else if (parameters == null) CreateDefaultInstance(field, fieldType, objectType, emit); else CreateParametrizedInstance(field, fieldType, objectType, emit, parameters); emit .MarkLabel(end) .ret() ; Context.Items.Add("$BLToolkit.FieldInstanceEnsurer." + fieldName, ensurer); }
private void CreateInitContextDefaultInstance( string initContextName, FieldBuilder field, TypeHelper fieldType, TypeHelper objectType, EmitHelper emit, object[] parameters) { if (!CheckObjectHolderCtor(fieldType, objectType)) return; LocalBuilder initField = GetInitContextBuilder(initContextName, emit); MethodInfo memberParams = InitContextType.GetProperty("MemberParameters").GetSetMethod(); if (parameters != null) { emit .ldloc (initField) .ldsfld (GetParameterField()) .callvirt (memberParams) ; } else if ((bool)Context.Items["$BLToolkit.Default.DirtyParameters"]) { emit .ldloc (initField) .ldnull .callvirt (memberParams) ; } Context.Items["$BLToolkit.Default.DirtyParameters"] = parameters != null; if (objectType.IsAbstract) { emit .ldarg_0 .ldsfld (GetTypeAccessorField()) .ldloc (initField) .callvirtNoGenerics (typeof(TypeAccessor), "CreateInstanceEx", _initContextType) .isinst (objectType) ; } else { emit .ldarg_0 .ldloc (initField) .newobj (objectType.GetPublicConstructor(typeof(InitContext))) ; } if (IsObjectHolder) { emit .newobj (fieldType, objectType) ; } emit .stfld (field) ; }
private bool CheckObjectHolderCtor(TypeHelper fieldType, TypeHelper objectType) { if (IsObjectHolder) { ConstructorInfo holderCi = fieldType.GetPublicConstructor(objectType); if (holderCi == null) { string message = string.Format( Resources.TypeBuilder_PropertyTypeHasNoCtorWithParamType, Context.CurrentProperty.Name, Context.Type.FullName, fieldType.FullName, objectType.FullName); Context.TypeBuilder.DefaultConstructor.Emitter .ldstr (message) .newobj (typeof(TypeBuilderException), typeof(string)) .@throw .end() ; return false; } } return true; }
private void BuildDefaultInstance() { string fieldName = GetFieldName(); FieldBuilder field = Context.GetField(fieldName); TypeHelper fieldType = new TypeHelper(field.FieldType); TypeHelper objectType = new TypeHelper(GetObjectType()); EmitHelper emit = Context.TypeBuilder.DefaultConstructor.Emitter; object[] ps = TypeHelper.GetPropertyParameters(Context.CurrentProperty); ConstructorInfo ci = objectType.GetPublicConstructor(typeof(InitContext)); if (ci != null && ci.GetParameters()[0].ParameterType != typeof(InitContext)) ci = null; if (ci != null || objectType.IsAbstract) CreateInitContextDefaultInstance( "$BLToolkit.DefaultInitContext.", field, fieldType, objectType, emit, ps); else if (ps == null) CreateDefaultInstance(field, fieldType, objectType, emit); else CreateParametrizedInstance(field, fieldType, objectType, emit, ps); }
private Stack<ConstructorInfo> GetGenericNestedConstructors(TypeHelper objectType, Predicate<TypeHelper> isActionable, Action<TypeHelper> action, Func<bool> isBreakCondition) { Stack<ConstructorInfo> genericNestedConstructors = null; if (isActionable(objectType)) action(objectType); while (objectType.Type.IsGenericType && !isBreakCondition()) { var typeArgs = objectType.Type.GetGenericArguments(); if (typeArgs.Length == 1) { var genericCtor = objectType.GetPublicConstructor(typeArgs[0]); if (genericCtor != null) { if (genericNestedConstructors == null) genericNestedConstructors = new Stack<ConstructorInfo>(); genericNestedConstructors.Push(genericCtor); objectType = typeArgs[0]; if (isActionable(objectType)) action(objectType); } } else { throw new TypeBuilderException( string.Format(Resources.TypeBuilder_GenericShouldBeSingleTyped, Context.CurrentProperty.Name, Context.Type.FullName, objectType.FullName)); } } return genericNestedConstructors; }
private void CreateParametrizedInstance( FieldBuilder field, TypeHelper fieldType, TypeHelper objectType, EmitHelper emit, object[] parameters) { if (!CheckObjectHolderCtor(fieldType, objectType)) return; if (parameters.Length == 1) { object o = parameters[0]; if (o == null) { if (objectType.IsValueType == false) emit .ldarg_0 .ldnull .end() ; if (IsObjectHolder) { emit .newobj (fieldType, objectType) ; } emit .stfld (field) ; return; } else { if (objectType.Type == o.GetType()) { if (objectType.Type == typeof(string)) { emit .ldarg_0 .ldstr ((string)o) .stfld (field) ; return; } if (objectType.IsValueType) { emit.ldarg_0.end(); if (emit.LoadWellKnownValue(o) == false) { emit .ldsfld (GetParameterField()) .ldc_i4_0 .ldelem_ref .end() ; } emit.stfld(field); return; } } } } Type[] types = new Type[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { if (parameters[i] != null) { Type t = parameters[i].GetType(); types[i] = (t.IsEnum) ? Enum.GetUnderlyingType(t) : t; } else types[i] = typeof(object); } ConstructorInfo ci = objectType.GetPublicConstructor(types); if (ci == null) { if (objectType.IsValueType) return; throw new TypeBuilderException( string.Format(types.Length == 0? Resources.TypeBuilder_PropertyTypeHasNoPublicDefaultCtor: Resources.TypeBuilder_PropertyTypeHasNoPublicCtor, Context.CurrentProperty.Name, Context.Type.FullName, objectType.FullName)); } ParameterInfo[] pi = ci.GetParameters(); emit.ldarg_0.end(); for (int i = 0; i < parameters.Length; i++) { object o = parameters[i]; Type oType = o.GetType(); if (emit.LoadWellKnownValue(o)) { if (oType.IsValueType) { if (!pi[i].ParameterType.IsValueType) emit.box(oType); else if (Type.GetTypeCode(oType) != Type.GetTypeCode(pi[i].ParameterType)) emit.conv(pi[i].ParameterType); } } else { emit .ldsfld (GetParameterField()) .ldc_i4 (i) .ldelem_ref .CastFromObject (types[i]) ; if (oType.IsValueType && !pi[i].ParameterType.IsValueType) emit.box(oType); } } emit .newobj (ci) ; if (IsObjectHolder) { emit .newobj (fieldType, objectType) ; } emit .stfld (field) ; }
private void CreateDefaultInstance( FieldBuilder field, TypeHelper fieldType, TypeHelper objectType, EmitHelper emit) { if (!CheckObjectHolderCtor(fieldType, objectType)) return; if (objectType.Type == typeof(string)) { emit .ldarg_0 .LoadInitValue (objectType) ; } else if (objectType.IsArray) { FieldBuilder initializer = GetArrayInitializer(objectType); emit .ldarg_0 .ldsfld (initializer) ; } else { ConstructorInfo ci = objectType.GetPublicDefaultConstructor(); if (ci == null) { if (objectType.Type.IsValueType) return; string message = string.Format( Resources.TypeBuilder_PropertyTypeHasNoPublicDefaultCtor, Context.CurrentProperty.Name, Context.Type.FullName, objectType.FullName); emit .ldstr (message) .newobj (typeof(TypeBuilderException), typeof(string)) .@throw .end() ; return; } else { emit .ldarg_0 .newobj (ci) ; } } if (IsObjectHolder) { emit .newobj (fieldType, objectType) ; } emit .stfld (field) ; }
private void BuildHolderInstance(EmitHelper emit) { string fieldName = GetFieldName(); FieldBuilder field = Context.GetField(fieldName); TypeHelper fieldType = new TypeHelper(field.FieldType); TypeHelper objectType = new TypeHelper(GetObjectType()); ConstructorInfo ci = fieldType.GetPublicDefaultConstructor(); if (ci != null) { emit .ldarg_0 .newobj (ci) .stfld (field) ; } else { if (!CheckObjectHolderCtor(fieldType, objectType)) return; emit .ldarg_0 .ldnull .newobj (fieldType, objectType) .stfld (field) ; } }
private void LoadParameterOrNull(ParameterInfo pi, Type type) { EmitHelper emit = Context.MethodBuilder.Emitter; object[] attrs = pi.GetCustomAttributes(typeof(ParamNullValueAttribute), true); object nullValue = attrs.Length == 0? null: ((ParamNullValueAttribute)attrs[0]).Value; Label labelNull = emit.DefineLabel(); Label labelEndIf = emit.DefineLabel(); if (pi.Attributes == ParameterAttributes.Out) { emit .ldnull .end() ; return; } if (nullValue != null) { Type nullValueType = type; bool isNullable = TypeHelper.IsNullable(type); if (type.IsEnum) { nullValueType = Enum.GetUnderlyingType(type); nullValue = System.Convert.ChangeType(nullValue, nullValueType); } else if (isNullable) { nullValueType = type.GetGenericArguments()[0]; emit .ldarga (pi) .call (type, "get_HasValue") .brfalse (labelNull) ; } if (nullValueType == nullValue.GetType() && emit.LoadWellKnownValue(nullValue)) { if (nullValueType == typeof(string)) emit .ldargEx (pi, false) .call (nullValueType, "Equals", nullValueType) .brtrue (labelNull) ; else if (isNullable) emit .ldarga (pi) .call (type, "get_Value") .beq (labelNull) ; else emit .ldargEx (pi, false) .beq (labelNull) ; } else { string nullString = TypeDescriptor.GetConverter(nullValue).ConvertToInvariantString(nullValue); FieldBuilder staticField = CreateNullValueField(nullValueType, nullString); MethodInfo miEquals = new TypeHelper(nullValueType).GetPublicMethod("Equals", nullValueType); if (miEquals == null) { // Is it possible? // throw new TypeBuilderException(string.Format( Resources.DataAccessorBuilder_EqualsMethodIsNotPublic, type.FullName)); } if (isNullable) emit .ldsflda (staticField) .ldarga (pi) .call (pi.ParameterType, "get_Value") ; else emit .ldsflda (staticField) .ldarg (pi) ; if (miEquals.GetParameters()[0].ParameterType.IsClass) emit .boxIfValueType(nullValueType) ; emit .call (miEquals) .brtrue (labelNull) ; } } if (type.IsEnum) emit .ldloc (_locManager) .callvirt (typeof (DbManager).GetProperty("MappingSchema").GetGetMethod()) ; emit .ldargEx(pi, true) ; if (type.IsEnum) emit .ldc_i4_1 .callvirt (typeof (MappingSchema), "MapEnumToValue", typeof (object), typeof (bool)) ; if (nullValue != null) { emit .br (labelEndIf) .MarkLabel (labelNull) .ldnull .MarkLabel (labelEndIf) ; } }
public void NumericTest() { TypeHelper helper = new TypeHelper(typeof(Convert)); IConvertible src = 123; // All types from SByte to Decimal can convert to each other // for (int from = 0; from < NumericTypes.Length; ++from) { Type typeFrom = NumericTypes[from]; object test = src.ToType(typeFrom, null); for (int to = 0; to < NumericTypes.Length; ++to) { if (from == to) continue; Type typeTo = NumericTypes[to]; MethodInfo mi = helper.GetMethod("To" + typeTo.Name, bindingFlags, typeFrom); Assert.IsNotNull(mi, string.Format("Missed To{0}({1})", typeTo.Name, typeFrom.Name)); Assert.AreEqual(123, mi.Invoke(null, new object[] { test })); } } }
private void BuildInitContextInstance() { var fieldName = GetFieldName(); var field = Context.GetField(fieldName); var fieldType = new TypeHelper(field.FieldType); var objectType = new TypeHelper(GetObjectType()); var emit = Context.TypeBuilder.InitConstructor.Emitter; var parameters = TypeHelper.GetPropertyParameters(Context.CurrentProperty); var ci = objectType.GetPublicConstructor(typeof(InitContext)); if (ci != null && ci.GetParameters()[0].ParameterType != typeof(InitContext)) ci = null; if (ci != null || objectType.IsAbstract) CreateAbstractInitContextInstance(field, fieldType, objectType, emit, parameters); else if (parameters == null) CreateDefaultInstance(field, fieldType, objectType, emit); else CreateParametrizedInstance(field, fieldType, objectType, emit, parameters); }
private void CreateAbstractInitContextInstance( FieldBuilder field, TypeHelper fieldType, TypeHelper objectType, EmitHelper emit, object[] parameters) { if (!CheckObjectHolderCtor(fieldType, objectType)) return; MethodInfo memberParams = InitContextType.GetProperty("MemberParameters").GetSetMethod(); LocalBuilder parentField = (LocalBuilder)Context.Items["$BLToolkit.InitContext.Parent"]; if (parentField == null) { Context.Items["$BLToolkit.InitContext.Parent"] = parentField = emit.DeclareLocal(typeof(object)); Label label = emit.DefineLabel(); emit .ldarg_1 .brtrue_s (label) .newobj (InitContextType.GetPublicDefaultConstructor()) .starg (1) .ldarg_1 .ldc_i4_1 .callvirt (InitContextType.GetProperty("IsInternal").GetSetMethod()) .MarkLabel (label) .ldarg_1 .callvirt (InitContextType.GetProperty("Parent").GetGetMethod()) .stloc (parentField) ; } emit .ldarg_1 .ldarg_0 .callvirt (InitContextType.GetProperty("Parent").GetSetMethod()) ; object isDirty = Context.Items["$BLToolkit.InitContext.DirtyParameters"]; if (parameters != null) { emit .ldarg_1 .ldsfld (GetParameterField()) .callvirt (memberParams) ; } else if (isDirty != null && (bool)isDirty) { emit .ldarg_1 .ldnull .callvirt (memberParams) ; } Context.Items["$BLToolkit.InitContext.DirtyParameters"] = parameters != null; if (objectType.IsAbstract) { emit .ldarg_0 .ldsfld (GetTypeAccessorField()) .ldarg_1 .callvirtNoGenerics (typeof(TypeAccessor), "CreateInstanceEx", _initContextType) .isinst (objectType) ; } else { emit .ldarg_0 .ldarg_1 .newobj (objectType.GetPublicConstructor(typeof(InitContext))) ; } if (IsObjectHolder) { emit .newobj (fieldType, objectType) ; } emit .stfld (field) ; }
public bool IsBasicType() { var typeHelper = new TypeHelper(); return typeHelper.IsBasicType(FieldType); }
private void CreateParametrizedInstance( FieldBuilder field, TypeHelper fieldType, TypeHelper objectType, EmitHelper emit, object[] parameters) { if (!CheckObjectHolderCtor(fieldType, objectType)) return; Stack<ConstructorInfo> genericNestedConstructors; if (parameters.Length == 1) { var o = parameters[0]; if (o == null) { if (objectType.IsValueType == false) emit .ldarg_0 .ldnull .end() ; if (IsObjectHolder) { emit .newobj (fieldType, objectType) ; } else { if (objectType.Type.IsGenericType) { Type nullableType = null; genericNestedConstructors = GetGenericNestedConstructors( objectType, typeHelper => typeHelper.IsValueType == false || (typeHelper.Type.IsGenericType && typeHelper.Type.GetGenericTypeDefinition() == typeof (Nullable<>)), typeHelper => { nullableType = typeHelper.Type; }, () => nullableType != null); if (nullableType == null) throw new Exception("Cannot find nullable type in generic types chain"); if (nullableType.IsValueType == false) { emit .ldarg_0 .ldnull .end() ; } else { var nullable = emit.DeclareLocal(nullableType); emit .ldloca(nullable) .initobj(nullableType) .ldarg_0 .ldloc(nullable) ; if (genericNestedConstructors != null) { while (genericNestedConstructors.Count != 0) { emit .newobj(genericNestedConstructors.Pop()) ; } } } } } emit .stfld (field) ; return; } if (objectType.Type == o.GetType()) { if (objectType.Type == typeof(string)) { emit .ldarg_0 .ldstr ((string)o) .stfld (field) ; return; } if (objectType.IsValueType) { emit.ldarg_0.end(); if (emit.LoadWellKnownValue(o) == false) { emit .ldsfld (GetParameterField()) .ldc_i4_0 .ldelem_ref .end() ; } emit.stfld(field); return; } } } var types = new Type[parameters.Length]; for (var i = 0; i < parameters.Length; i++) { if (parameters[i] != null) { var t = parameters[i].GetType(); types[i] = (t.IsEnum) ? Enum.GetUnderlyingType(t) : t; } else types[i] = typeof(object); } // Do some heuristics for Nullable<DateTime> and EditableValue<Decimal> // ConstructorInfo objectCtor = null; genericNestedConstructors = GetGenericNestedConstructors( objectType, typeHelper => true, typeHelper => { objectCtor = typeHelper.GetPublicConstructor(types); }, () => objectCtor != null); if (objectCtor == null) { if (objectType.IsValueType) return; throw new TypeBuilderException( string.Format(types.Length == 0? Resources.TypeBuilder_PropertyTypeHasNoPublicDefaultCtor: Resources.TypeBuilder_PropertyTypeHasNoPublicCtor, Context.CurrentProperty.Name, Context.Type.FullName, objectType.FullName)); } var pi = objectCtor.GetParameters(); emit.ldarg_0.end(); for (var i = 0; i < parameters.Length; i++) { var o = parameters[i]; var oType = o.GetType(); if (emit.LoadWellKnownValue(o)) { if (oType.IsValueType) { if (!pi[i].ParameterType.IsValueType) emit.box(oType); else if (Type.GetTypeCode(oType) != Type.GetTypeCode(pi[i].ParameterType)) emit.conv(pi[i].ParameterType); } } else { emit .ldsfld (GetParameterField()) .ldc_i4 (i) .ldelem_ref .CastFromObject (types[i]) ; if (oType.IsValueType && !pi[i].ParameterType.IsValueType) emit.box(oType); } } emit .newobj (objectCtor) ; if (genericNestedConstructors != null) { while (genericNestedConstructors.Count != 0) { emit .newobj(genericNestedConstructors.Pop()) ; } } if (IsObjectHolder) { emit .newobj (fieldType, objectType) ; } emit .stfld (field) ; }