|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
namespace System.Reflection.Emit
{
internal sealed class RuntimeConstructorBuilder : ConstructorBuilder
{
private readonly RuntimeMethodBuilder m_methodBuilder;
internal bool m_isDefaultConstructor;
#region Constructor
internal RuntimeConstructorBuilder(string name, MethodAttributes attributes, CallingConventions callingConvention,
Type[]? parameterTypes, Type[][]? requiredCustomModifiers, Type[][]? optionalCustomModifiers, RuntimeModuleBuilder mod, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] RuntimeTypeBuilder type)
{
m_methodBuilder = new RuntimeMethodBuilder(name, attributes, callingConvention, null, null, null,
parameterTypes, requiredCustomModifiers, optionalCustomModifiers, mod, type);
type.m_listMethods!.Add(m_methodBuilder);
m_methodBuilder.GetMethodSignature().InternalGetSignature(out _);
_ = m_methodBuilder.MetadataToken; // Doubles as "CreateMethod" for MethodBuilder -- analogous to CreateType()
}
internal RuntimeConstructorBuilder(string name, MethodAttributes attributes, CallingConventions callingConvention,
Type[]? parameterTypes, RuntimeModuleBuilder mod, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] RuntimeTypeBuilder type) :
this(name, attributes, callingConvention, parameterTypes, null, null, mod, type)
{
}
#endregion
#region Internal
internal override Type[] GetParameterTypes()
{
return m_methodBuilder.GetParameterTypes();
}
[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
private RuntimeTypeBuilder GetTypeBuilder()
{
return m_methodBuilder.GetTypeBuilder();
}
internal SignatureHelper GetMethodSignature()
{
return m_methodBuilder.GetMethodSignature();
}
#endregion
#region Object Overrides
public override string ToString()
{
return m_methodBuilder.ToString();
}
#endregion
#region MemberInfo Overrides
public override int MetadataToken => m_methodBuilder.MetadataToken;
public override Module Module => m_methodBuilder.Module;
public override Type? ReflectedType => m_methodBuilder.ReflectedType;
public override Type? DeclaringType => m_methodBuilder.DeclaringType;
public override string Name => m_methodBuilder.Name;
#endregion
#region MethodBase Overrides
public override object Invoke(object? obj, BindingFlags invokeAttr, Binder? binder, object?[]? parameters, CultureInfo? culture)
{
throw new NotSupportedException(SR.NotSupported_DynamicModule);
}
public override ParameterInfo[] GetParameters()
{
ConstructorInfo rci = GetTypeBuilder().GetConstructor(m_methodBuilder.m_parameterTypes!)!;
return rci.GetParameters();
}
public override MethodAttributes Attributes => m_methodBuilder.Attributes;
public override MethodImplAttributes GetMethodImplementationFlags()
{
return m_methodBuilder.GetMethodImplementationFlags();
}
public override RuntimeMethodHandle MethodHandle => m_methodBuilder.MethodHandle;
#endregion
#region ConstructorInfo Overrides
public override object Invoke(BindingFlags invokeAttr, Binder? binder, object?[]? parameters, CultureInfo? culture)
{
throw new NotSupportedException(SR.NotSupported_DynamicModule);
}
#endregion
#region ICustomAttributeProvider Implementation
public override object[] GetCustomAttributes(bool inherit)
{
return m_methodBuilder.GetCustomAttributes(inherit);
}
public override object[] GetCustomAttributes(Type attributeType, bool inherit)
{
return m_methodBuilder.GetCustomAttributes(attributeType, inherit);
}
public override bool IsDefined(Type attributeType, bool inherit)
{
return m_methodBuilder.IsDefined(attributeType, inherit);
}
#endregion
#region Public Members
protected override ParameterBuilder DefineParameterCore(int iSequence, ParameterAttributes attributes, string? strParamName)
{
// Theoretically we shouldn't allow iSequence to be 0 because in reflection ctors don't have
// return parameters. But we'll allow it for backward compatibility with V2. The attributes
// defined on the return parameters won't be very useful but won't do much harm either.
// MD will assert if we try to set the reserved bits explicitly
attributes &= ~ParameterAttributes.ReservedMask;
return m_methodBuilder.DefineParameter(iSequence, attributes, strParamName);
}
protected override ILGenerator GetILGeneratorCore(int streamSize)
{
if (m_isDefaultConstructor)
throw new InvalidOperationException(SR.InvalidOperation_DefaultConstructorILGen);
return m_methodBuilder.GetILGenerator(streamSize);
}
public override CallingConventions CallingConvention
{
get
{
if (DeclaringType!.IsGenericType)
return CallingConventions.HasThis;
return CallingConventions.Standard;
}
}
internal override Type GetReturnType()
{
return m_methodBuilder.ReturnType;
}
protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan<byte> binaryAttribute)
{
m_methodBuilder.SetCustomAttribute(con, binaryAttribute);
}
protected override void SetImplementationFlagsCore(MethodImplAttributes attributes)
{
m_methodBuilder.SetImplementationFlags(attributes);
}
protected override bool InitLocalsCore
{
get => m_methodBuilder.InitLocals;
set => m_methodBuilder.InitLocals = value;
}
#endregion
}
}
|