diff --git a/src/Castle.Core.Tests/DynamicProxy.Tests/ClassEmitterTestCase.cs b/src/Castle.Core.Tests/DynamicProxy.Tests/ClassEmitterTestCase.cs index 62d46e169..cef0481cc 100644 --- a/src/Castle.Core.Tests/DynamicProxy.Tests/ClassEmitterTestCase.cs +++ b/src/Castle.Core.Tests/DynamicProxy.Tests/ClassEmitterTestCase.cs @@ -1,4 +1,4 @@ -// Copyright 2004-2021 Castle Project - http://www.castleproject.org/ +// Copyright 2004-2025 Castle Project - http://www.castleproject.org/ // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -106,73 +106,5 @@ public void CreateStaticFieldWithAttributes() Assert.IsNotNull(field); Assert.AreEqual(FieldAttributes.Static | FieldAttributes.FamANDAssem | FieldAttributes.InitOnly, field.Attributes); } - - [Test] - public void UsingClassEmitterForInterfaces() - { - ClassEmitter emitter = new ClassEmitter(generator.ProxyBuilder.ModuleScope, "IFoo", null, Type.EmptyTypes, - TypeAttributes.Interface | TypeAttributes.Abstract | TypeAttributes.Public, false); - emitter.CreateMethod("MyMethod", MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual, - typeof(void), Type.EmptyTypes); - Type t = emitter.BuildType(); - Assert.IsTrue(t.IsInterface); - MethodInfo method = t.GetMethod("MyMethod"); - Assert.IsNotNull(method); - } - - [Test] - public void NoBaseTypeForInterfaces() - { - DisableVerification(); - ClassEmitter emitter = new ClassEmitter (generator.ProxyBuilder.ModuleScope, "IFoo", null, Type.EmptyTypes, - TypeAttributes.Interface | TypeAttributes.Abstract | TypeAttributes.Public, false); - - Assert.Throws(delegate { -#pragma warning disable 219 - Type t = emitter.BaseType; -#pragma warning restore 219 - }); - } - - [Test] - public void NoDefaultCtorForInterfaces() - { - DisableVerification(); - ClassEmitter emitter = new ClassEmitter(generator.ProxyBuilder.ModuleScope, "IFoo", null, Type.EmptyTypes, - TypeAttributes.Interface | TypeAttributes.Abstract | TypeAttributes.Public, false); - - Assert.Throws(delegate { - emitter.CreateDefaultConstructor(); - }); - } - - [Test] - public void NoCustomCtorForInterfaces() - { - DisableVerification(); - ClassEmitter emitter = new ClassEmitter(generator.ProxyBuilder.ModuleScope, "IFoo", null, Type.EmptyTypes, - TypeAttributes.Interface | TypeAttributes.Abstract | TypeAttributes.Public, false); - - Assert.Throws(delegate { - emitter.CreateConstructor(); - }); - } - - [Test] - public void NestedInterface() - { - ClassEmitter outerEmitter = new ClassEmitter(generator.ProxyBuilder.ModuleScope, "IOuter", null, Type.EmptyTypes, - TypeAttributes.Interface | TypeAttributes.Abstract | TypeAttributes.Public, false); - NestedClassEmitter innerEmitter = new NestedClassEmitter(outerEmitter, "IInner", - TypeAttributes.Interface | TypeAttributes.Abstract | TypeAttributes.NestedPublic, null, Type.EmptyTypes); - innerEmitter.CreateMethod("MyMethod", MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual, - typeof(void), Type.EmptyTypes); - Type inner = innerEmitter.BuildType(); - Type outer = outerEmitter.BuildType(); - Assert.IsTrue(inner.IsInterface); - MethodInfo method = inner.GetMethod("MyMethod"); - Assert.IsNotNull(method); - Assert.AreSame(inner, outer.GetNestedType("IInner", BindingFlags.Public)); - } } } \ No newline at end of file diff --git a/src/Castle.Core/DynamicProxy/Contributors/IInvocationCreationContributor.cs b/src/Castle.Core/DynamicProxy/Contributors/IInvocationCreationContributor.cs index 87b94f848..81e62bc7d 100644 --- a/src/Castle.Core/DynamicProxy/Contributors/IInvocationCreationContributor.cs +++ b/src/Castle.Core/DynamicProxy/Contributors/IInvocationCreationContributor.cs @@ -1,4 +1,4 @@ -// Copyright 2004-2021 Castle Project - http://www.castleproject.org/ +// Copyright 2004-2025 Castle Project - http://www.castleproject.org/ // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,11 +21,11 @@ namespace Castle.DynamicProxy.Contributors internal interface IInvocationCreationContributor { - ConstructorEmitter CreateConstructor(ArgumentReference[] baseCtorArguments, AbstractTypeEmitter invocation); + ConstructorEmitter CreateConstructor(ArgumentReference[] baseCtorArguments, ClassEmitter invocation); MethodInfo GetCallbackMethod(); - MethodInvocationExpression GetCallbackMethodInvocation(AbstractTypeEmitter invocation, IExpression[] args, + MethodInvocationExpression GetCallbackMethodInvocation(ClassEmitter invocation, IExpression[] args, Reference targetField, MethodEmitter invokeMethodOnTarget); IExpression[] GetConstructorInvocationArguments(IExpression[] arguments, ClassEmitter proxy); diff --git a/src/Castle.Core/DynamicProxy/Contributors/InvocationWithDelegateContributor.cs b/src/Castle.Core/DynamicProxy/Contributors/InvocationWithDelegateContributor.cs index 48f7d2969..ff5b2db63 100644 --- a/src/Castle.Core/DynamicProxy/Contributors/InvocationWithDelegateContributor.cs +++ b/src/Castle.Core/DynamicProxy/Contributors/InvocationWithDelegateContributor.cs @@ -1,4 +1,4 @@ -// Copyright 2004-2021 Castle Project - http://www.castleproject.org/ +// Copyright 2004-2025 Castle Project - http://www.castleproject.org/ // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -40,7 +40,7 @@ public InvocationWithDelegateContributor(Type delegateType, Type targetType, Met this.namingScope = namingScope; } - public ConstructorEmitter CreateConstructor(ArgumentReference[] baseCtorArguments, AbstractTypeEmitter invocation) + public ConstructorEmitter CreateConstructor(ArgumentReference[] baseCtorArguments, ClassEmitter invocation) { var arguments = GetArguments(baseCtorArguments); var constructor = invocation.CreateConstructor(arguments); @@ -55,7 +55,7 @@ public MethodInfo GetCallbackMethod() return delegateType.GetMethod("Invoke"); } - public MethodInvocationExpression GetCallbackMethodInvocation(AbstractTypeEmitter invocation, IExpression[] args, + public MethodInvocationExpression GetCallbackMethodInvocation(ClassEmitter invocation, IExpression[] args, Reference targetField, MethodEmitter invokeMethodOnTarget) { diff --git a/src/Castle.Core/DynamicProxy/Contributors/InvocationWithGenericDelegateContributor.cs b/src/Castle.Core/DynamicProxy/Contributors/InvocationWithGenericDelegateContributor.cs index 3dbeaf5fe..fd186aa6e 100644 --- a/src/Castle.Core/DynamicProxy/Contributors/InvocationWithGenericDelegateContributor.cs +++ b/src/Castle.Core/DynamicProxy/Contributors/InvocationWithGenericDelegateContributor.cs @@ -1,4 +1,4 @@ -// Copyright 2004-2021 Castle Project - http://www.castleproject.org/ +// Copyright 2004-2025 Castle Project - http://www.castleproject.org/ // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -39,7 +39,7 @@ public InvocationWithGenericDelegateContributor(Type delegateType, MetaMethod me this.targetReference = targetReference; } - public ConstructorEmitter CreateConstructor(ArgumentReference[] baseCtorArguments, AbstractTypeEmitter invocation) + public ConstructorEmitter CreateConstructor(ArgumentReference[] baseCtorArguments, ClassEmitter invocation) { return invocation.CreateConstructor(baseCtorArguments); } @@ -49,7 +49,7 @@ public MethodInfo GetCallbackMethod() return delegateType.GetMethod("Invoke"); } - public MethodInvocationExpression GetCallbackMethodInvocation(AbstractTypeEmitter invocation, IExpression[] args, + public MethodInvocationExpression GetCallbackMethodInvocation(ClassEmitter invocation, IExpression[] args, Reference targetField, MethodEmitter invokeMethodOnTarget) { @@ -62,7 +62,7 @@ public IExpression[] GetConstructorInvocationArguments(IExpression[] arguments, return arguments; } - private Reference GetDelegate(AbstractTypeEmitter invocation, MethodEmitter invokeMethodOnTarget) + private Reference GetDelegate(ClassEmitter invocation, MethodEmitter invokeMethodOnTarget) { var genericTypeParameters = invocation.GenericTypeParams.AsTypeArray(); var closedDelegateType = delegateType.MakeGenericType(genericTypeParameters); diff --git a/src/Castle.Core/DynamicProxy/Generators/CompositionInvocationTypeGenerator.cs b/src/Castle.Core/DynamicProxy/Generators/CompositionInvocationTypeGenerator.cs index 93bd20b44..cd3adcc88 100644 --- a/src/Castle.Core/DynamicProxy/Generators/CompositionInvocationTypeGenerator.cs +++ b/src/Castle.Core/DynamicProxy/Generators/CompositionInvocationTypeGenerator.cs @@ -57,7 +57,7 @@ protected override FieldReference GetTargetReference() return new FieldReference(InvocationMethods.CompositionInvocationTarget); } - protected override void ImplementInvokeMethodOnTarget(AbstractTypeEmitter invocation, ParameterInfo[] parameters, + protected override void ImplementInvokeMethodOnTarget(ClassEmitter invocation, ParameterInfo[] parameters, MethodEmitter invokeMethodOnTarget, Reference targetField) { invokeMethodOnTarget.CodeBuilder.AddStatement( diff --git a/src/Castle.Core/DynamicProxy/Generators/DelegateTypeGenerator.cs b/src/Castle.Core/DynamicProxy/Generators/DelegateTypeGenerator.cs index 8efd6d40c..a18f2ec75 100644 --- a/src/Castle.Core/DynamicProxy/Generators/DelegateTypeGenerator.cs +++ b/src/Castle.Core/DynamicProxy/Generators/DelegateTypeGenerator.cs @@ -1,4 +1,4 @@ -// Copyright 2004-2021 Castle Project - http://www.castleproject.org/ +// Copyright 2004-2025 Castle Project - http://www.castleproject.org/ // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ namespace Castle.DynamicProxy.Generators using Castle.DynamicProxy.Generators.Emitters.SimpleAST; using Castle.DynamicProxy.Internal; - internal class DelegateTypeGenerator : IGenerator + internal class DelegateTypeGenerator : IGenerator { private const TypeAttributes DelegateFlags = TypeAttributes.Class | TypeAttributes.Public | @@ -38,7 +38,7 @@ public DelegateTypeGenerator(MetaMethod method, Type targetType) this.targetType = targetType; } - public AbstractTypeEmitter Generate(ClassEmitter @class, INamingScope namingScope) + public ClassEmitter Generate(ClassEmitter @class, INamingScope namingScope) { var emitter = GetEmitter(@class, namingScope); BuildConstructor(emitter); @@ -46,14 +46,14 @@ public AbstractTypeEmitter Generate(ClassEmitter @class, INamingScope namingScop return emitter; } - private void BuildConstructor(AbstractTypeEmitter emitter) + private void BuildConstructor(ClassEmitter emitter) { var constructor = emitter.CreateConstructor(new ArgumentReference(typeof(object)), new ArgumentReference(typeof(IntPtr))); constructor.ConstructorBuilder.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed); } - private void BuildInvokeMethod(AbstractTypeEmitter @delegate) + private void BuildInvokeMethod(ClassEmitter @delegate) { var paramTypes = GetParamTypes(@delegate); var invoke = @delegate.CreateMethod("Invoke", @@ -66,7 +66,7 @@ private void BuildInvokeMethod(AbstractTypeEmitter @delegate) invoke.MethodBuilder.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed); } - private AbstractTypeEmitter GetEmitter(ClassEmitter @class, INamingScope namingScope) + private ClassEmitter GetEmitter(ClassEmitter @class, INamingScope namingScope) { var methodInfo = method.MethodOnTarget; var suggestedName = string.Format("Castle.Proxies.Delegates.{0}_{1}", @@ -84,7 +84,7 @@ private AbstractTypeEmitter GetEmitter(ClassEmitter @class, INamingScope namingS return @delegate; } - private Type[] GetParamTypes(AbstractTypeEmitter @delegate) + private Type[] GetParamTypes(ClassEmitter @delegate) { var parameters = method.MethodOnTarget.GetParameters(); if (@delegate.TypeBuilder.IsGenericType) diff --git a/src/Castle.Core/DynamicProxy/Generators/Emitters/AbstractTypeEmitter.cs b/src/Castle.Core/DynamicProxy/Generators/Emitters/AbstractTypeEmitter.cs deleted file mode 100644 index 361a6bdf8..000000000 --- a/src/Castle.Core/DynamicProxy/Generators/Emitters/AbstractTypeEmitter.cs +++ /dev/null @@ -1,374 +0,0 @@ -// Copyright 2004-2021 Castle Project - http://www.castleproject.org/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -namespace Castle.DynamicProxy.Generators.Emitters -{ - using System; - using System.Collections.Generic; - using System.Diagnostics; - using System.Reflection; - using System.Reflection.Emit; - - using Castle.DynamicProxy.Generators.Emitters.SimpleAST; - using Castle.DynamicProxy.Internal; - - internal abstract class AbstractTypeEmitter - { - private const MethodAttributes defaultAttributes = - MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.Public; - - private readonly List constructors; - private readonly List events; - - private readonly IDictionary fields = - new Dictionary(StringComparer.OrdinalIgnoreCase); - - private readonly List methods; - - private readonly List nested; - private readonly List properties; - private readonly TypeBuilder typeBuilder; - - private GenericTypeParameterBuilder[] genericTypeParams; - - protected AbstractTypeEmitter(TypeBuilder typeBuilder) - { - this.typeBuilder = typeBuilder; - nested = new List(); - methods = new List(); - constructors = new List(); - properties = new List(); - events = new List(); - } - - public Type BaseType - { - get - { - if (TypeBuilder.IsInterface) - { - throw new InvalidOperationException("This emitter represents an interface; interfaces have no base types."); - } - return TypeBuilder.BaseType; - } - } - - public TypeConstructorEmitter ClassConstructor { get; private set; } - - public GenericTypeParameterBuilder[] GenericTypeParams - { - get { return genericTypeParams; } - } - - public TypeBuilder TypeBuilder - { - get { return typeBuilder; } - } - - public void AddCustomAttributes(IEnumerable additionalAttributes) - { - foreach (var attribute in additionalAttributes) - { - typeBuilder.SetCustomAttribute(attribute.Builder); - } - } - - public void AddNestedClass(NestedClassEmitter nestedClass) - { - nested.Add(nestedClass); - } - - public virtual Type BuildType() - { - EnsureBuildersAreInAValidState(); - - var type = CreateType(typeBuilder); - - foreach (var builder in nested) - { - builder.BuildType(); - } - - return type; - } - - public void CopyGenericParametersFromMethod(MethodInfo methodToCopyGenericsFrom) - { - // big sanity check - if (genericTypeParams != null) - { - throw new InvalidOperationException("Cannot invoke me twice"); - } - - SetGenericTypeParameters(GenericUtil.CopyGenericArguments(methodToCopyGenericsFrom, typeBuilder)); - } - - 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 CreateDefaultConstructor() - { - if (TypeBuilder.IsInterface) - { - throw new InvalidOperationException("Interfaces cannot have constructors."); - } - - constructors.Add(new ConstructorEmitter(this)); - } - - public EventEmitter CreateEvent(string name, EventAttributes atts, Type type) - { - var eventEmitter = new EventEmitter(this, name, atts, type); - events.Add(eventEmitter); - return eventEmitter; - } - - public FieldReference CreateField(string name, Type fieldType) - { - return CreateField(name, fieldType, true); - } - - public FieldReference CreateField(string name, Type fieldType, bool serializable) - { - var atts = FieldAttributes.Private; - - if (!serializable) - { - atts |= FieldAttributes.NotSerialized; - } - - return CreateField(name, fieldType, atts); - } - - public FieldReference CreateField(string name, Type fieldType, FieldAttributes atts) - { - var fieldBuilder = typeBuilder.DefineField(name, fieldType, atts); - var reference = new FieldReference(fieldBuilder); - fields[name] = reference; - return reference; - } - - public MethodEmitter CreateMethod(string name, MethodAttributes attrs, Type returnType, params Type[] argumentTypes) - { - var member = new MethodEmitter(this, name, attrs, returnType, argumentTypes ?? Type.EmptyTypes); - methods.Add(member); - return member; - } - - public MethodEmitter CreateMethod(string name, Type returnType, params Type[] parameterTypes) - { - return CreateMethod(name, defaultAttributes, returnType, parameterTypes); - } - - public MethodEmitter CreateMethod(string name, MethodInfo methodToUseAsATemplate) - { - return CreateMethod(name, defaultAttributes, methodToUseAsATemplate); - } - - public MethodEmitter CreateMethod(string name, MethodAttributes attributes, MethodInfo methodToUseAsATemplate) - { - var method = new MethodEmitter(this, name, attributes, methodToUseAsATemplate); - methods.Add(method); - return method; - } - - public PropertyEmitter CreateProperty(string name, PropertyAttributes attributes, Type propertyType, Type[] arguments) - { - var propEmitter = new PropertyEmitter(this, name, attributes, propertyType, arguments); - properties.Add(propEmitter); - return propEmitter; - } - - public FieldReference CreateStaticField(string name, Type fieldType) - { - return CreateStaticField(name, fieldType, FieldAttributes.Private); - } - - public FieldReference CreateStaticField(string name, Type fieldType, FieldAttributes atts) - { - atts |= FieldAttributes.Static; - return CreateField(name, fieldType, atts); - } - - public ConstructorEmitter CreateTypeConstructor() - { - var member = new TypeConstructorEmitter(this); - constructors.Add(member); - ClassConstructor = member; - return member; - } - - public void DefineCustomAttribute(CustomAttributeBuilder attribute) - { - typeBuilder.SetCustomAttribute(attribute); - } - - public void DefineCustomAttribute(object[] constructorArguments) where TAttribute : Attribute - { - var customAttributeInfo = AttributeUtil.CreateInfo(typeof(TAttribute), constructorArguments); - typeBuilder.SetCustomAttribute(customAttributeInfo.Builder); - } - - public void DefineCustomAttribute() where TAttribute : Attribute, new() - { - var customAttributeInfo = AttributeUtil.CreateInfo(); - typeBuilder.SetCustomAttribute(customAttributeInfo.Builder); - } - - public void DefineCustomAttributeFor(FieldReference field) where TAttribute : Attribute, new() - { - var customAttributeInfo = AttributeUtil.CreateInfo(); - var fieldBuilder = field.FieldBuilder; - if (fieldBuilder == null) - { - throw new ArgumentException( - "Invalid field reference.This reference does not point to field on type being generated", nameof(field)); - } - fieldBuilder.SetCustomAttribute(customAttributeInfo.Builder); - } - - public IEnumerable GetAllFields() - { - return fields.Values; - } - - public FieldReference GetField(string name) - { - if (string.IsNullOrEmpty(name)) - { - return null; - } - - FieldReference value; - fields.TryGetValue(name, out value); - return value; - } - - public Type GetClosedParameterType(Type parameter) - { - if (parameter.IsGenericType) - { - // ECMA-335 section II.9.4: "The CLI does not support partial instantiation - // of generic types. And generic types shall not appear uninstantiated any- - // where in metadata signature blobs." (And parameters are defined there!) - Debug.Assert(parameter.IsGenericTypeDefinition == false); - - var arguments = parameter.GetGenericArguments(); - if (CloseGenericParametersIfAny(arguments)) - { - return parameter.GetGenericTypeDefinition().MakeGenericType(arguments); - } - } - - if (parameter.IsGenericParameter) - { - return GetGenericArgument(parameter.GenericParameterPosition); - } - - if (parameter.IsArray) - { - var elementType = GetClosedParameterType(parameter.GetElementType()); - int rank = parameter.GetArrayRank(); - return rank == 1 - ? elementType.MakeArrayType() - : elementType.MakeArrayType(rank); - } - - if (parameter.IsByRef) - { - var elementType = GetClosedParameterType(parameter.GetElementType()); - return elementType.MakeByRefType(); - } - - return parameter; - - bool CloseGenericParametersIfAny(Type[] arguments) - { - var hasAnyGenericParameters = false; - for (var i = 0; i < arguments.Length; i++) - { - var newType = GetClosedParameterType(arguments[i]); - if (newType != null && !ReferenceEquals(newType, arguments[i])) - { - arguments[i] = newType; - hasAnyGenericParameters = true; - } - } - return hasAnyGenericParameters; - } - } - - public Type GetGenericArgument(int position) - { - Debug.Assert(0 <= position && position < genericTypeParams.Length); - - return genericTypeParams[position]; - } - - public Type[] GetGenericArgumentsFor(MethodInfo genericMethod) - { - Debug.Assert(genericMethod.GetGenericArguments().Length == genericTypeParams.Length); - - return genericTypeParams; - } - - public void SetGenericTypeParameters(GenericTypeParameterBuilder[] genericTypeParameterBuilders) - { - genericTypeParams = genericTypeParameterBuilders; - } - - protected Type CreateType(TypeBuilder type) - { - return type.CreateTypeInfo(); - } - - protected virtual void EnsureBuildersAreInAValidState() - { - if (!typeBuilder.IsInterface && constructors.Count == 0) - { - CreateDefaultConstructor(); - } - - foreach (IMemberEmitter builder in properties) - { - builder.EnsureValidCodeBlock(); - builder.Generate(); - } - foreach (IMemberEmitter builder in events) - { - builder.EnsureValidCodeBlock(); - builder.Generate(); - } - foreach (IMemberEmitter builder in constructors) - { - builder.EnsureValidCodeBlock(); - builder.Generate(); - } - foreach (IMemberEmitter builder in methods) - { - builder.EnsureValidCodeBlock(); - builder.Generate(); - } - } - } -} \ No newline at end of file diff --git a/src/Castle.Core/DynamicProxy/Generators/Emitters/ClassEmitter.cs b/src/Castle.Core/DynamicProxy/Generators/Emitters/ClassEmitter.cs index 07a658aee..151c7ff26 100644 --- a/src/Castle.Core/DynamicProxy/Generators/Emitters/ClassEmitter.cs +++ b/src/Castle.Core/DynamicProxy/Generators/Emitters/ClassEmitter.cs @@ -1,4 +1,4 @@ -// Copyright 2004-2021 Castle Project - http://www.castleproject.org/ +// Copyright 2004-2025 Castle Project - http://www.castleproject.org/ // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,23 +20,44 @@ namespace Castle.DynamicProxy.Generators.Emitters using System.Reflection; using System.Reflection.Emit; + using Castle.DynamicProxy.Generators.Emitters.SimpleAST; using Castle.DynamicProxy.Internal; - internal class ClassEmitter : AbstractTypeEmitter + internal sealed class ClassEmitter { - internal const TypeAttributes DefaultAttributes = - TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Serializable; + private const MethodAttributes defaultAttributes = + MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.Public; private readonly ModuleScope moduleScope; - public ClassEmitter(ModuleScope moduleScope, string name, Type baseType, IEnumerable interfaces) - : this(moduleScope, name, baseType, interfaces, DefaultAttributes, forceUnsigned: false) + private readonly List constructors; + private readonly List events; + + private readonly IDictionary fields = + new Dictionary(StringComparer.OrdinalIgnoreCase); + + private readonly List methods; + + private readonly List properties; + private readonly TypeBuilder typeBuilder; + + private GenericTypeParameterBuilder[] genericTypeParams; + + internal const TypeAttributes DefaultTypeAttributes = + TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Serializable; + + public ClassEmitter(TypeBuilder typeBuilder) { + Debug.Assert(typeBuilder.IsClass, $"{nameof(ClassEmitter)} only supports class types."); + + this.typeBuilder = typeBuilder; + methods = new List(); + constructors = new List(); + properties = new List(); + events = new List(); } - public ClassEmitter(ModuleScope moduleScope, string name, Type baseType, IEnumerable interfaces, - TypeAttributes flags, - bool forceUnsigned) + public ClassEmitter(ModuleScope moduleScope, string name, Type baseType, IEnumerable interfaces, TypeAttributes flags, bool forceUnsigned) : this(CreateTypeBuilder(moduleScope, name, baseType, interfaces, flags, forceUnsigned)) { interfaces = InitializeGenericArgumentsFromBases(ref baseType, interfaces); @@ -60,23 +81,12 @@ public ClassEmitter(ModuleScope moduleScope, string name, Type baseType, IEnumer this.moduleScope = moduleScope; } - public ClassEmitter(TypeBuilder typeBuilder) - : base(typeBuilder) - { - } - - public ModuleScope ModuleScope - { - get { return moduleScope; } - } - - internal bool InStrongNamedModule + public ClassEmitter(ModuleScope moduleScope, string name, Type baseType, IEnumerable interfaces) + : this(moduleScope, name, baseType, interfaces, DefaultTypeAttributes, forceUnsigned: false) { - get { return StrongNameUtil.IsAssemblySigned(TypeBuilder.Assembly); } } - protected virtual IEnumerable InitializeGenericArgumentsFromBases(ref Type baseType, - IEnumerable interfaces) + private static IEnumerable InitializeGenericArgumentsFromBases(ref Type baseType, IEnumerable interfaces) { if (baseType != null && baseType.IsGenericTypeDefinition) { @@ -99,11 +109,302 @@ protected virtual IEnumerable InitializeGenericArgumentsFromBases(ref Type } private static TypeBuilder CreateTypeBuilder(ModuleScope moduleScope, string name, Type baseType, - IEnumerable interfaces, - TypeAttributes flags, bool forceUnsigned) + IEnumerable interfaces, + TypeAttributes flags, bool forceUnsigned) { var isAssemblySigned = !forceUnsigned && !StrongNameUtil.IsAnyTypeFromUnsignedAssembly(baseType, interfaces); return moduleScope.DefineType(isAssemblySigned, name, flags); } + + public Type BaseType + { + get + { + return TypeBuilder.BaseType; + } + } + + public ConstructorEmitter ClassConstructor { get; private set; } + + internal bool InStrongNamedModule + { + get { return StrongNameUtil.IsAssemblySigned(TypeBuilder.Assembly); } + } + + public GenericTypeParameterBuilder[] GenericTypeParams + { + get { return genericTypeParams; } + } + + public ModuleScope ModuleScope + { + get { return moduleScope; } + } + + public TypeBuilder TypeBuilder + { + get { return typeBuilder; } + } + + public void AddCustomAttributes(IEnumerable additionalAttributes) + { + foreach (var attribute in additionalAttributes) + { + typeBuilder.SetCustomAttribute(attribute.Builder); + } + } + + public void CopyGenericParametersFromMethod(MethodInfo methodToCopyGenericsFrom) + { + // big sanity check + if (genericTypeParams != null) + { + throw new InvalidOperationException("Cannot invoke me twice"); + } + + SetGenericTypeParameters(GenericUtil.CopyGenericArguments(methodToCopyGenericsFrom, typeBuilder)); + } + + public ConstructorEmitter CreateConstructor(params ArgumentReference[] arguments) + { + var member = new ConstructorEmitter(this, arguments); + constructors.Add(member); + return member; + } + + public void CreateDefaultConstructor() + { + constructors.Add(new ConstructorEmitter(this)); + } + + public EventEmitter CreateEvent(string name, EventAttributes atts, Type type) + { + var eventEmitter = new EventEmitter(this, name, atts, type); + events.Add(eventEmitter); + return eventEmitter; + } + + public FieldReference CreateField(string name, Type fieldType) + { + return CreateField(name, fieldType, true); + } + + public FieldReference CreateField(string name, Type fieldType, bool serializable) + { + var atts = FieldAttributes.Private; + + if (!serializable) + { + atts |= FieldAttributes.NotSerialized; + } + + return CreateField(name, fieldType, atts); + } + + public FieldReference CreateField(string name, Type fieldType, FieldAttributes atts) + { + var fieldBuilder = typeBuilder.DefineField(name, fieldType, atts); + var reference = new FieldReference(fieldBuilder); + fields[name] = reference; + return reference; + } + + public MethodEmitter CreateMethod(string name, MethodAttributes attrs, Type returnType, params Type[] argumentTypes) + { + var member = new MethodEmitter(this, name, attrs, returnType, argumentTypes ?? Type.EmptyTypes); + methods.Add(member); + return member; + } + + public MethodEmitter CreateMethod(string name, Type returnType, params Type[] parameterTypes) + { + return CreateMethod(name, defaultAttributes, returnType, parameterTypes); + } + + public MethodEmitter CreateMethod(string name, MethodInfo methodToUseAsATemplate) + { + return CreateMethod(name, defaultAttributes, methodToUseAsATemplate); + } + + public MethodEmitter CreateMethod(string name, MethodAttributes attributes, MethodInfo methodToUseAsATemplate) + { + var method = new MethodEmitter(this, name, attributes, methodToUseAsATemplate); + methods.Add(method); + return method; + } + + public PropertyEmitter CreateProperty(string name, PropertyAttributes attributes, Type propertyType, Type[] arguments) + { + var propEmitter = new PropertyEmitter(this, name, attributes, propertyType, arguments); + properties.Add(propEmitter); + return propEmitter; + } + + public FieldReference CreateStaticField(string name, Type fieldType) + { + return CreateStaticField(name, fieldType, FieldAttributes.Private); + } + + public FieldReference CreateStaticField(string name, Type fieldType, FieldAttributes atts) + { + atts |= FieldAttributes.Static; + return CreateField(name, fieldType, atts); + } + + public ConstructorEmitter CreateTypeConstructor() + { + var member = new ConstructorEmitter(this, TypeBuilder.DefineTypeInitializer()); + constructors.Add(member); + ClassConstructor = member; + return member; + } + + public void DefineCustomAttribute(CustomAttributeBuilder attribute) + { + typeBuilder.SetCustomAttribute(attribute); + } + + public void DefineCustomAttribute(object[] constructorArguments) where TAttribute : Attribute + { + var customAttributeInfo = AttributeUtil.CreateInfo(typeof(TAttribute), constructorArguments); + typeBuilder.SetCustomAttribute(customAttributeInfo.Builder); + } + + public void DefineCustomAttribute() where TAttribute : Attribute, new() + { + var customAttributeInfo = AttributeUtil.CreateInfo(); + typeBuilder.SetCustomAttribute(customAttributeInfo.Builder); + } + + public void DefineCustomAttributeFor(FieldReference field) where TAttribute : Attribute, new() + { + var customAttributeInfo = AttributeUtil.CreateInfo(); + var fieldBuilder = field.FieldBuilder; + if (fieldBuilder == null) + { + throw new ArgumentException( + "Invalid field reference.This reference does not point to field on type being generated", nameof(field)); + } + fieldBuilder.SetCustomAttribute(customAttributeInfo.Builder); + } + + public IEnumerable GetAllFields() + { + return fields.Values; + } + + public FieldReference GetField(string name) + { + if (string.IsNullOrEmpty(name)) + { + return null; + } + + FieldReference value; + fields.TryGetValue(name, out value); + return value; + } + + public Type GetClosedParameterType(Type parameter) + { + if (parameter.IsGenericType) + { + // ECMA-335 section II.9.4: "The CLI does not support partial instantiation + // of generic types. And generic types shall not appear uninstantiated any- + // where in metadata signature blobs." (And parameters are defined there!) + Debug.Assert(parameter.IsGenericTypeDefinition == false); + + var arguments = parameter.GetGenericArguments(); + if (CloseGenericParametersIfAny(arguments)) + { + return parameter.GetGenericTypeDefinition().MakeGenericType(arguments); + } + } + + if (parameter.IsGenericParameter) + { + return GetGenericArgument(parameter.GenericParameterPosition); + } + + if (parameter.IsArray) + { + var elementType = GetClosedParameterType(parameter.GetElementType()); + int rank = parameter.GetArrayRank(); + return rank == 1 + ? elementType.MakeArrayType() + : elementType.MakeArrayType(rank); + } + + if (parameter.IsByRef) + { + var elementType = GetClosedParameterType(parameter.GetElementType()); + return elementType.MakeByRefType(); + } + + return parameter; + + bool CloseGenericParametersIfAny(Type[] arguments) + { + var hasAnyGenericParameters = false; + for (var i = 0; i < arguments.Length; i++) + { + var newType = GetClosedParameterType(arguments[i]); + if (newType != null && !ReferenceEquals(newType, arguments[i])) + { + arguments[i] = newType; + hasAnyGenericParameters = true; + } + } + return hasAnyGenericParameters; + } + } + + public Type GetGenericArgument(int position) + { + Debug.Assert(0 <= position && position < genericTypeParams.Length); + + return genericTypeParams[position]; + } + + public Type[] GetGenericArgumentsFor(MethodInfo genericMethod) + { + Debug.Assert(genericMethod.GetGenericArguments().Length == genericTypeParams.Length); + + return genericTypeParams; + } + + public void SetGenericTypeParameters(GenericTypeParameterBuilder[] genericTypeParameterBuilders) + { + genericTypeParams = genericTypeParameterBuilders; + } + + public Type BuildType() + { + if (constructors.Count == 0) + { + CreateDefaultConstructor(); + } + + foreach (var builder in properties) + { + builder.Generate(); + } + foreach (var builder in events) + { + builder.Generate(); + } + foreach (var builder in constructors) + { + builder.Generate(); + } + foreach (var builder in methods) + { + builder.Generate(); + } + + var type = typeBuilder.CreateTypeInfo(); + + return type; + } } } \ No newline at end of file diff --git a/src/Castle.Core/DynamicProxy/Generators/Emitters/ConstructorEmitter.cs b/src/Castle.Core/DynamicProxy/Generators/Emitters/ConstructorEmitter.cs index 74b2edac3..463da37ac 100644 --- a/src/Castle.Core/DynamicProxy/Generators/Emitters/ConstructorEmitter.cs +++ b/src/Castle.Core/DynamicProxy/Generators/Emitters/ConstructorEmitter.cs @@ -1,4 +1,4 @@ -// Copyright 2004-2021 Castle Project - http://www.castleproject.org/ +// Copyright 2004-2025 Castle Project - http://www.castleproject.org/ // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,20 +20,20 @@ namespace Castle.DynamicProxy.Generators.Emitters using Castle.DynamicProxy.Generators.Emitters.SimpleAST; - internal class ConstructorEmitter : IMemberEmitter + internal class ConstructorEmitter { private readonly ConstructorBuilder builder; private readonly CodeBuilder codeBuilder; - private readonly AbstractTypeEmitter mainType; + private readonly ClassEmitter mainType; - protected internal ConstructorEmitter(AbstractTypeEmitter mainType, ConstructorBuilder builder) + protected internal ConstructorEmitter(ClassEmitter mainType, ConstructorBuilder builder) { this.mainType = mainType; this.builder = builder; codeBuilder = new CodeBuilder(); } - internal ConstructorEmitter(AbstractTypeEmitter mainType, params ArgumentReference[] arguments) + internal ConstructorEmitter(ClassEmitter mainType, params ArgumentReference[] arguments) { this.mainType = mainType; @@ -53,16 +53,6 @@ public ConstructorBuilder ConstructorBuilder get { return builder; } } - public MemberInfo Member - { - get { return builder; } - } - - public Type ReturnType - { - get { return typeof(void); } - } - private bool ImplementedByRuntime { get @@ -72,15 +62,6 @@ private bool ImplementedByRuntime } } - public virtual void EnsureValidCodeBlock() - { - if (ImplementedByRuntime == false && CodeBuilder.IsEmpty) - { - CodeBuilder.AddStatement(new ConstructorInvocationStatement(mainType.BaseType)); - CodeBuilder.AddStatement(new ReturnStatement()); - } - } - public virtual void Generate() { if (ImplementedByRuntime) @@ -88,6 +69,16 @@ public virtual void Generate() return; } + if (CodeBuilder.IsEmpty) + { + if (builder.IsStatic == false) + { + CodeBuilder.AddStatement(new ConstructorInvocationStatement(mainType.BaseType)); + } + + CodeBuilder.AddStatement(new ReturnStatement()); + } + CodeBuilder.Generate(builder.GetILGenerator()); } } diff --git a/src/Castle.Core/DynamicProxy/Generators/Emitters/EventEmitter.cs b/src/Castle.Core/DynamicProxy/Generators/Emitters/EventEmitter.cs index 08ad72ea3..1c48a147b 100644 --- a/src/Castle.Core/DynamicProxy/Generators/Emitters/EventEmitter.cs +++ b/src/Castle.Core/DynamicProxy/Generators/Emitters/EventEmitter.cs @@ -1,4 +1,4 @@ -// Copyright 2004-2021 Castle Project - http://www.castleproject.org/ +// Copyright 2004-2025 Castle Project - http://www.castleproject.org/ // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,15 +18,14 @@ namespace Castle.DynamicProxy.Generators.Emitters using System.Reflection; using System.Reflection.Emit; - internal class EventEmitter : IMemberEmitter + internal class EventEmitter { private readonly EventBuilder eventBuilder; - private readonly Type type; - private readonly AbstractTypeEmitter typeEmitter; + private readonly ClassEmitter typeEmitter; private MethodEmitter addMethod; private MethodEmitter removeMethod; - public EventEmitter(AbstractTypeEmitter typeEmitter, string name, EventAttributes attributes, Type type) + public EventEmitter(ClassEmitter typeEmitter, string name, EventAttributes attributes, Type type) { if (name == null) { @@ -37,20 +36,9 @@ public EventEmitter(AbstractTypeEmitter typeEmitter, string name, EventAttribute throw new ArgumentNullException(nameof(type)); } this.typeEmitter = typeEmitter; - this.type = type; eventBuilder = typeEmitter.TypeBuilder.DefineEvent(name, attributes, type); } - public MemberInfo Member - { - get { return null; } - } - - public Type ReturnType - { - get { return type; } - } - public MethodEmitter CreateAddMethod(string addMethodName, MethodAttributes attributes, MethodInfo methodToOverride) { if (addMethod != null) @@ -73,12 +61,6 @@ public MethodEmitter CreateRemoveMethod(string removeMethodName, MethodAttribute return removeMethod; } - public void EnsureValidCodeBlock() - { - addMethod.EnsureValidCodeBlock(); - removeMethod.EnsureValidCodeBlock(); - } - public void Generate() { if (addMethod == null) diff --git a/src/Castle.Core/DynamicProxy/Generators/Emitters/IMemberEmitter.cs b/src/Castle.Core/DynamicProxy/Generators/Emitters/IMemberEmitter.cs deleted file mode 100644 index 9f6676a1a..000000000 --- a/src/Castle.Core/DynamicProxy/Generators/Emitters/IMemberEmitter.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2004-2021 Castle Project - http://www.castleproject.org/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -namespace Castle.DynamicProxy.Generators.Emitters -{ - using System; - using System.Reflection; - - internal interface IMemberEmitter - { - MemberInfo Member { get; } - - Type ReturnType { get; } - - void EnsureValidCodeBlock(); - - void Generate(); - } -} \ No newline at end of file diff --git a/src/Castle.Core/DynamicProxy/Generators/Emitters/MethodEmitter.cs b/src/Castle.Core/DynamicProxy/Generators/Emitters/MethodEmitter.cs index 7d2579f10..b77c62b2d 100644 --- a/src/Castle.Core/DynamicProxy/Generators/Emitters/MethodEmitter.cs +++ b/src/Castle.Core/DynamicProxy/Generators/Emitters/MethodEmitter.cs @@ -1,4 +1,4 @@ -// Copyright 2004-2021 Castle Project - http://www.castleproject.org/ +// Copyright 2004-2025 Castle Project - http://www.castleproject.org/ // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -26,7 +26,7 @@ namespace Castle.DynamicProxy.Generators.Emitters using Castle.DynamicProxy.Internal; [DebuggerDisplay("{builder.Name}")] - internal class MethodEmitter : IMemberEmitter + internal class MethodEmitter { private readonly MethodBuilder builder; private readonly CodeBuilder codeBuilder; @@ -40,12 +40,12 @@ protected internal MethodEmitter(MethodBuilder builder) codeBuilder = new CodeBuilder(); } - internal MethodEmitter(AbstractTypeEmitter owner, string name, MethodAttributes attributes) + internal MethodEmitter(ClassEmitter owner, string name, MethodAttributes attributes) : this(owner.TypeBuilder.DefineMethod(name, attributes)) { } - internal MethodEmitter(AbstractTypeEmitter owner, string name, + internal MethodEmitter(ClassEmitter owner, string name, MethodAttributes attributes, Type returnType, params Type[] argumentTypes) : this(owner, name, attributes) @@ -54,7 +54,7 @@ internal MethodEmitter(AbstractTypeEmitter owner, string name, SetReturnType(returnType); } - internal MethodEmitter(AbstractTypeEmitter owner, string name, + internal MethodEmitter(ClassEmitter owner, string name, MethodAttributes attributes, MethodInfo methodToUseAsATemplate) : this(owner, name, attributes) { @@ -93,11 +93,6 @@ public MethodBuilder MethodBuilder get { return builder; } } - public MemberInfo Member - { - get { return builder; } - } - public Type ReturnType { get { return builder.ReturnType; } @@ -124,9 +119,14 @@ public void SetParameters(Type[] paramTypes) ArgumentsUtil.InitializeArgumentsByPosition(arguments, MethodBuilder.IsStatic); } - public virtual void EnsureValidCodeBlock() + public virtual void Generate() { - if (ImplementedByRuntime == false && CodeBuilder.IsEmpty) + if (ImplementedByRuntime) + { + return; + } + + if (CodeBuilder.IsEmpty) { if (ReturnType == typeof(void)) { @@ -137,14 +137,6 @@ public virtual void EnsureValidCodeBlock() CodeBuilder.AddStatement(new ReturnStatement(new DefaultValueExpression(ReturnType))); } } - } - - public virtual void Generate() - { - if (ImplementedByRuntime) - { - return; - } codeBuilder.Generate(builder.GetILGenerator()); } diff --git a/src/Castle.Core/DynamicProxy/Generators/Emitters/NestedClassEmitter.cs b/src/Castle.Core/DynamicProxy/Generators/Emitters/NestedClassEmitter.cs deleted file mode 100644 index d019a7bfd..000000000 --- a/src/Castle.Core/DynamicProxy/Generators/Emitters/NestedClassEmitter.cs +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2004-2021 Castle Project - http://www.castleproject.org/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -namespace Castle.DynamicProxy.Generators.Emitters -{ - using System; - using System.Reflection; - using System.Reflection.Emit; - - internal class NestedClassEmitter : AbstractTypeEmitter - { - public NestedClassEmitter(AbstractTypeEmitter mainType, string name, Type baseType, Type[] interfaces) - : this( - mainType, - CreateTypeBuilder(mainType, name, TypeAttributes.Sealed | TypeAttributes.NestedPublic | TypeAttributes.Class, - baseType, interfaces)) - { - } - - public NestedClassEmitter(AbstractTypeEmitter mainType, string name, TypeAttributes attributes, Type baseType, - Type[] interfaces) - : this(mainType, CreateTypeBuilder(mainType, name, attributes, baseType, interfaces)) - { - } - - public NestedClassEmitter(AbstractTypeEmitter mainType, TypeBuilder typeBuilder) - : base(typeBuilder) - { - mainType.AddNestedClass(this); - } - - private static TypeBuilder CreateTypeBuilder(AbstractTypeEmitter mainType, string name, TypeAttributes attributes, - Type baseType, Type[] interfaces) - { - return mainType.TypeBuilder.DefineNestedType( - name, - attributes, - baseType, interfaces); - } - } -} \ No newline at end of file diff --git a/src/Castle.Core/DynamicProxy/Generators/Emitters/PropertyEmitter.cs b/src/Castle.Core/DynamicProxy/Generators/Emitters/PropertyEmitter.cs index c2674b3de..0202600dc 100644 --- a/src/Castle.Core/DynamicProxy/Generators/Emitters/PropertyEmitter.cs +++ b/src/Castle.Core/DynamicProxy/Generators/Emitters/PropertyEmitter.cs @@ -1,4 +1,4 @@ -// Copyright 2004-2021 Castle Project - http://www.castleproject.org/ +// Copyright 2004-2025 Castle Project - http://www.castleproject.org/ // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,14 +18,14 @@ namespace Castle.DynamicProxy.Generators.Emitters using System.Reflection; using System.Reflection.Emit; - internal class PropertyEmitter : IMemberEmitter + internal class PropertyEmitter { private readonly PropertyBuilder builder; - private readonly AbstractTypeEmitter parentTypeEmitter; + private readonly ClassEmitter parentTypeEmitter; private MethodEmitter getMethod; private MethodEmitter setMethod; - public PropertyEmitter(AbstractTypeEmitter parentTypeEmitter, string name, PropertyAttributes attributes, + public PropertyEmitter(ClassEmitter parentTypeEmitter, string name, PropertyAttributes attributes, Type propertyType, Type[] arguments) { this.parentTypeEmitter = parentTypeEmitter; @@ -35,16 +35,6 @@ public PropertyEmitter(AbstractTypeEmitter parentTypeEmitter, string name, Prope null, null, arguments, null, null); } - public MemberInfo Member - { - get { return null; } - } - - public Type ReturnType - { - get { return builder.PropertyType; } - } - public MethodEmitter CreateGetMethod(string name, MethodAttributes attrs, MethodInfo methodToOverride, params Type[] parameters) { @@ -85,19 +75,6 @@ public void DefineCustomAttribute(CustomAttributeBuilder attribute) builder.SetCustomAttribute(attribute); } - public void EnsureValidCodeBlock() - { - if (setMethod != null) - { - setMethod.EnsureValidCodeBlock(); - } - - if (getMethod != null) - { - getMethod.EnsureValidCodeBlock(); - } - } - public void Generate() { if (setMethod != null) diff --git a/src/Castle.Core/DynamicProxy/Generators/Emitters/TypeConstructorEmitter.cs b/src/Castle.Core/DynamicProxy/Generators/Emitters/TypeConstructorEmitter.cs deleted file mode 100644 index 2167a63a3..000000000 --- a/src/Castle.Core/DynamicProxy/Generators/Emitters/TypeConstructorEmitter.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2004-2021 Castle Project - http://www.castleproject.org/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -namespace Castle.DynamicProxy.Generators.Emitters -{ - using Castle.DynamicProxy.Generators.Emitters.SimpleAST; - - internal class TypeConstructorEmitter : ConstructorEmitter - { - internal TypeConstructorEmitter(AbstractTypeEmitter mainType) - : base(mainType, mainType.TypeBuilder.DefineTypeInitializer()) - { - } - - public override void EnsureValidCodeBlock() - { - if (CodeBuilder.IsEmpty) - { - CodeBuilder.AddStatement(new ReturnStatement()); - } - } - } -} \ No newline at end of file diff --git a/src/Castle.Core/DynamicProxy/Generators/InvocationTypeGenerator.cs b/src/Castle.Core/DynamicProxy/Generators/InvocationTypeGenerator.cs index 749b65e77..4508fc122 100644 --- a/src/Castle.Core/DynamicProxy/Generators/InvocationTypeGenerator.cs +++ b/src/Castle.Core/DynamicProxy/Generators/InvocationTypeGenerator.cs @@ -24,7 +24,7 @@ namespace Castle.DynamicProxy.Generators using Castle.DynamicProxy.Internal; using Castle.DynamicProxy.Tokens; - internal abstract class InvocationTypeGenerator : IGenerator + internal abstract class InvocationTypeGenerator : IGenerator { protected readonly MetaMethod method; protected readonly Type targetType; @@ -53,7 +53,7 @@ protected abstract ArgumentReference[] GetBaseCtorArguments(Type targetFieldType protected abstract FieldReference GetTargetReference(); - public AbstractTypeEmitter Generate(ClassEmitter @class, INamingScope namingScope) + public ClassEmitter Generate(ClassEmitter @class, INamingScope namingScope) { var methodInfo = method.Method; @@ -86,7 +86,7 @@ public AbstractTypeEmitter Generate(ClassEmitter @class, INamingScope namingScop return invocation; } - protected virtual MethodInvocationExpression GetCallbackMethodInvocation(AbstractTypeEmitter invocation, + protected virtual MethodInvocationExpression GetCallbackMethodInvocation(ClassEmitter invocation, IExpression[] args, MethodInfo callbackMethod, Reference targetField, MethodEmitter invokeMethodOnTarget) @@ -102,7 +102,7 @@ protected virtual MethodInvocationExpression GetCallbackMethodInvocation(Abstrac return methodOnTargetInvocationExpression; } - protected virtual void ImplementInvokeMethodOnTarget(AbstractTypeEmitter invocation, ParameterInfo[] parameters, + protected virtual void ImplementInvokeMethodOnTarget(ClassEmitter invocation, ParameterInfo[] parameters, MethodEmitter invokeMethodOnTarget, Reference targetField) { @@ -268,7 +268,7 @@ private void AssignBackByRefArguments(MethodEmitter invokeMethodOnTarget, Dictio invokeMethodOnTarget.CodeBuilder.AddStatement(new EndExceptionBlockStatement()); } - private void CreateConstructor(AbstractTypeEmitter invocation) + private void CreateConstructor(ClassEmitter invocation) { ConstructorInfo baseConstructor; var baseCtorArguments = GetBaseCtorArguments(targetType, out baseConstructor); @@ -278,7 +278,7 @@ private void CreateConstructor(AbstractTypeEmitter invocation) constructor.CodeBuilder.AddStatement(new ReturnStatement()); } - private ConstructorEmitter CreateConstructor(AbstractTypeEmitter invocation, ArgumentReference[] baseCtorArguments) + private ConstructorEmitter CreateConstructor(ClassEmitter invocation, ArgumentReference[] baseCtorArguments) { if (contributor == null) { @@ -295,7 +295,7 @@ private void EmitCallThrowOnNoTarget(MethodEmitter invokeMethodOnTarget) invokeMethodOnTarget.CodeBuilder.AddStatement(new ReturnStatement()); } - private MethodInfo GetCallbackMethod(AbstractTypeEmitter invocation) + private MethodInfo GetCallbackMethod(ClassEmitter invocation) { if (contributor != null) { @@ -315,23 +315,22 @@ private MethodInfo GetCallbackMethod(AbstractTypeEmitter invocation) return callbackMethod.MakeGenericMethod(invocation.GetGenericArgumentsFor(callbackMethod)); } - private AbstractTypeEmitter GetEmitter(ClassEmitter @class, Type[] interfaces, INamingScope namingScope, - MethodInfo methodInfo) + private ClassEmitter GetEmitter(ClassEmitter @class, Type[] interfaces, INamingScope namingScope, MethodInfo methodInfo) { var suggestedName = string.Format("Castle.Proxies.Invocations.{0}_{1}", methodInfo.DeclaringType.Name, methodInfo.Name); var uniqueName = namingScope.ParentScope.GetUniqueName(suggestedName); - return new ClassEmitter(@class.ModuleScope, uniqueName, GetBaseType(), interfaces, ClassEmitter.DefaultAttributes, forceUnsigned: @class.InStrongNamedModule == false); + return new ClassEmitter(@class.ModuleScope, uniqueName, GetBaseType(), interfaces, ClassEmitter.DefaultTypeAttributes, forceUnsigned: @class.InStrongNamedModule == false); } - private void ImplementInvokeMethodOnTarget(AbstractTypeEmitter invocation, ParameterInfo[] parameters, + private void ImplementInvokeMethodOnTarget(ClassEmitter invocation, ParameterInfo[] parameters, FieldReference targetField, MethodInfo callbackMethod) { var invokeMethodOnTarget = invocation.CreateMethod("InvokeMethodOnTarget", typeof(void)); ImplementInvokeMethodOnTarget(invocation, parameters, invokeMethodOnTarget, targetField); } - private void ImplementChangeInvocationTarget(AbstractTypeEmitter invocation, FieldReference targetField) + private void ImplementChangeInvocationTarget(ClassEmitter invocation, FieldReference targetField) { var changeInvocationTarget = invocation.CreateMethod("ChangeInvocationTarget", typeof(void), new[] { typeof(object) }); changeInvocationTarget.CodeBuilder.AddStatement( @@ -340,7 +339,7 @@ private void ImplementChangeInvocationTarget(AbstractTypeEmitter invocation, Fie changeInvocationTarget.CodeBuilder.AddStatement(new ReturnStatement()); } - private void ImplementChangeProxyTarget(AbstractTypeEmitter invocation, ClassEmitter @class) + private void ImplementChangeProxyTarget(ClassEmitter invocation, ClassEmitter @class) { var changeProxyTarget = invocation.CreateMethod("ChangeProxyTarget", typeof(void), new[] { typeof(object) }); @@ -361,7 +360,7 @@ private void ImplementChangeProxyTarget(AbstractTypeEmitter invocation, ClassEmi changeProxyTarget.CodeBuilder.AddStatement(new ReturnStatement()); } - private void ImplementChangeProxyTargetInterface(ClassEmitter @class, AbstractTypeEmitter invocation, + private void ImplementChangeProxyTargetInterface(ClassEmitter @class, ClassEmitter invocation, FieldReference targetField) { ImplementChangeInvocationTarget(invocation, targetField);