Example #1
0
        public ConstructorEmitter CreateConstructor(params ArgumentReference[] arguments)
        {
            if (TypeBuilder.IsInterface)
            {
                throw new InvalidOperationException("Interfaces cannot have constructors.");
            }

            var member = new ConstructorEmitter(this, arguments);
            constructors.Add(member);
            return member;
        }
Example #2
0
		public void Add(ConstructorEmitter constructor)
		{
			InnerList.Add(constructor);
		}
		protected void ImplementBlankInterface(
			Type targetType,
			Type _interface,
			ClassEmitter emitter,
			FieldReference interceptorsField,
			ConstructorEmitter typeInitializerConstructor)
		{
			CheckNotGenericTypeDefinition(targetType, "targetType");
			CheckNotGenericTypeDefinition(_interface, "_interface");

			PropertyToGenerate[] propsToGenerate;
			EventToGenerate[] eventsToGenerate;
			MethodInfo[] methods =
				CollectMethodsAndProperties(emitter, _interface, false, out propsToGenerate, out eventsToGenerate);

			Dictionary<MethodInfo, NestedClassEmitter> method2Invocation = new Dictionary<MethodInfo, NestedClassEmitter>();

			foreach(MethodInfo method in methods)
			{
				AddFieldToCacheMethodTokenAndStatementsToInitialize(method, typeInitializerConstructor, emitter);

				method2Invocation[method] =
					BuildInvocationNestedType(emitter,
					                          targetType,
					                          emitter.TypeBuilder,
					                          method,
					                          null,
					                          ConstructorVersion.WithoutTargetMethod);
			}

			foreach(MethodInfo method in methods)
			{
				if (method.IsSpecialName && (method.Name.StartsWith("get_") || method.Name.StartsWith("set_")))
				{
					continue;
				}

				NestedClassEmitter nestedClass = method2Invocation[method];

				MethodEmitter newProxiedMethod =
					CreateProxiedMethod(targetType,
					                    method,
					                    emitter,
					                    nestedClass,
					                    interceptorsField,
					                    SelfReference.Self,
					                    ConstructorVersion.WithoutTargetMethod,
					                    null);

				ReplicateNonInheritableAttributes(method, newProxiedMethod);
			}

			foreach(PropertyToGenerate propToGen in propsToGenerate)
			{
				if (propToGen.CanRead)
				{
					NestedClassEmitter nestedClass = method2Invocation[propToGen.GetMethod];

					MethodAttributes atts = ObtainMethodAttributes(propToGen.GetMethod);

					MethodEmitter getEmitter = propToGen.Emitter.CreateGetMethod(atts);

					ImplementProxiedMethod(targetType,
					                       getEmitter,
					                       propToGen.GetMethod,
					                       emitter,
					                       nestedClass,
					                       interceptorsField,
					                       SelfReference.Self,
					                       ConstructorVersion.WithoutTargetMethod,
					                       null);

					ReplicateNonInheritableAttributes(propToGen.GetMethod, getEmitter);
				}

				if (propToGen.CanWrite)
				{
					NestedClassEmitter nestedClass = method2Invocation[propToGen.SetMethod];

					MethodAttributes atts = ObtainMethodAttributes(propToGen.SetMethod);

					MethodEmitter setEmitter = propToGen.Emitter.CreateSetMethod(atts);

					ImplementProxiedMethod(targetType,
					                       setEmitter,
					                       propToGen.SetMethod,
					                       emitter,
					                       nestedClass,
					                       interceptorsField,
					                       SelfReference.Self,
					                       ConstructorVersion.WithoutTargetMethod,
					                       null);

					ReplicateNonInheritableAttributes(propToGen.SetMethod, setEmitter);
				}
			}

			foreach(EventToGenerate eventToGenerate in eventsToGenerate)
			{
				NestedClassEmitter add_nestedClass = method2Invocation[eventToGenerate.AddMethod];

				MethodAttributes add_atts = ObtainMethodAttributes(eventToGenerate.AddMethod);

				MethodEmitter addEmitter = eventToGenerate.Emitter.CreateAddMethod(add_atts);

				ImplementProxiedMethod(targetType,
				                       addEmitter,
				                       eventToGenerate.AddMethod,
				                       emitter,
				                       add_nestedClass,
				                       interceptorsField,
				                       SelfReference.Self,
				                       ConstructorVersion.WithoutTargetMethod,
				                       null);

				ReplicateNonInheritableAttributes(eventToGenerate.AddMethod, addEmitter);

				NestedClassEmitter remove_nestedClass = method2Invocation[eventToGenerate.RemoveMethod];

				MethodAttributes remove_atts = ObtainMethodAttributes(eventToGenerate.RemoveMethod);

				MethodEmitter removeEmitter = eventToGenerate.Emitter.CreateRemoveMethod(remove_atts);

				ImplementProxiedMethod(targetType,
				                       removeEmitter,
				                       eventToGenerate.RemoveMethod,
				                       emitter,
				                       remove_nestedClass,
				                       interceptorsField,
				                       SelfReference.Self,
				                       ConstructorVersion.WithoutTargetMethod,
				                       null);

				ReplicateNonInheritableAttributes(eventToGenerate.RemoveMethod, removeEmitter);
			}
		}
		protected void AddFieldToCacheMethodTokenAndStatementsToInitialize(
			MethodInfo method, ConstructorEmitter typeInitializerConstructor, ClassEmitter classEmitter)
		{
			if (!method2TokenField.ContainsKey(method))
			{
				FieldReference fieldCache =
					classEmitter.CreateStaticField("tokenCache" + fieldCount++, typeof(MethodInfo));

				method2TokenField.Add(method, fieldCache);

				typeInitializerConstructor.CodeBuilder.AddStatement(
					new AssignStatement(fieldCache, new MethodTokenExpression(method)));
			}
		}
		protected void CacheMethodTokens(
			ClassEmitter classEmitter, MethodInfo[] methods, ConstructorEmitter typeInitializerConstructor)
		{
			foreach(MethodInfo method in methods)
			{
				// Aparently we cannot cache generic methods
				if (method.IsGenericMethod) continue;

				AddFieldToCacheMethodTokenAndStatementsToInitialize(method, typeInitializerConstructor, classEmitter);
			}
		}
		/// <summary>
		/// Improvement: this cache should be static. We should generate a
		/// type constructor instead
		/// </summary>
		protected void CreateInitializeCacheMethodBody(
			Type targetType, MethodInfo[] methods, ClassEmitter classEmitter, ConstructorEmitter typeInitializerConstructor)
		{
			typeTokenField = classEmitter.CreateStaticField("typeTokenCache", typeof(Type));

			typeInitializerConstructor.CodeBuilder.AddStatement(
				new AssignStatement(typeTokenField, new TypeTokenExpression(targetType)));

			CacheMethodTokens(classEmitter, methods, typeInitializerConstructor);
		}
Example #7
0
		protected void ImplementBlankInterface(
			Type targetType,
			Type _interface,
			ClassEmitter emitter,
			FieldReference interceptorsField,
			ConstructorEmitter typeInitializerConstructor)
		{
			ImplementBlankInterface(targetType, _interface, emitter, interceptorsField, typeInitializerConstructor, false);
		}
Example #8
0
		protected void CacheMethodTokens(
			ClassEmitter classEmitter, MethodInfo[] methods, ConstructorEmitter typeInitializerConstructor)
		{
			foreach (MethodInfo method in methods)
			{
				AddFieldToCacheMethodTokenAndStatementsToInitialize(method, typeInitializerConstructor, classEmitter);
			}
		}
		public ConstructorEmitter CreateConstructor(params ArgumentReference[] arguments)
		{
			ConstructorEmitter member = new ConstructorEmitter(this, arguments);
			constructors.Add(member);
			return member;
		}