Пример #1
0
		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)
				;
		}
Пример #2
0
		private LocalBuilder GetInitContextBuilder(
			string initContextName, EmitHelper emit)
		{
			LocalBuilder initField = (LocalBuilder)Context.Items[initContextName];

			if (initField == null)
			{
				Context.Items[initContextName] = 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())

					.stloc    (initField)
					;

				Context.Items.Add("$BLToolkit.Default.DirtyParameters", false);
			}

			return initField;
		}
Пример #3
0
		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)
				;
		}
Пример #4
0
		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)
				;
		}
Пример #5
0
		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)
				;
		}
Пример #6
0
		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)
				;
		}