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; }
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); }
protected void ImplementBlankInterface( Type targetType, Type _interface, ClassEmitter emitter, FieldReference interceptorsField, ConstructorEmitter typeInitializerConstructor) { ImplementBlankInterface(targetType, _interface, emitter, interceptorsField, typeInitializerConstructor, false); }
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; }