pschelpdesk/Vendor/Prise.Proxy/runtime/IngoreAccessChecksToAttributeBuilder.cs
2024-11-04 20:45:34 +01:00

102 lines
5.1 KiB
C#

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// Original File: https://github.com/dotnet/runtime/blob/6072e4d3a7a2a1493f514cdf4be75a3d56580e84/src/libraries/Common/src/System/Reflection/Emit/IgnoreAccessChecksToAttributeBuilder.cs
using System.Linq;
namespace System.Reflection.Emit
{
internal static class IgnoreAccessChecksToAttributeBuilder
{
/// <summary>
/// Generate the declaration for the IgnoresAccessChecksToAttribute type.
/// This attribute will be both defined and used in the dynamic assembly.
/// Each usage identifies the name of the assembly containing non-public
/// types the dynamic assembly needs to access. Normally those types
/// would be inaccessible, but this attribute allows them to be visible.
/// It works like a reverse InternalsVisibleToAttribute.
/// This method returns the ConstructorInfo of the generated attribute.
/// </summary>
public static ConstructorInfo AddToModule(ModuleBuilder mb)
{
TypeBuilder attributeTypeBuilder =
mb.DefineType("System.Runtime.CompilerServices.IgnoresAccessChecksToAttribute",
TypeAttributes.Public | TypeAttributes.Class,
typeof(Attribute));
// Create backing field as:
// private string assemblyName;
FieldBuilder assemblyNameField =
attributeTypeBuilder.DefineField("assemblyName", typeof(string), FieldAttributes.Private);
// Create ctor as:
// public IgnoresAccessChecksToAttribute(string)
ConstructorBuilder constructorBuilder = attributeTypeBuilder.DefineConstructor(MethodAttributes.Public,
CallingConventions.HasThis,
new Type[] { assemblyNameField.FieldType });
ILGenerator il = constructorBuilder.GetILGenerator();
// Create ctor body as:
// this.assemblyName = {ctor parameter 0}
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg, 1);
il.Emit(OpCodes.Stfld, assemblyNameField);
// return
il.Emit(OpCodes.Ret);
// Define property as:
// public string AssemblyName {get { return this.assemblyName; } }
_ = attributeTypeBuilder.DefineProperty(
"AssemblyName",
PropertyAttributes.None,
CallingConventions.HasThis,
returnType: typeof(string),
parameterTypes: null);
MethodBuilder getterMethodBuilder = attributeTypeBuilder.DefineMethod(
"get_AssemblyName",
MethodAttributes.Public,
CallingConventions.HasThis,
returnType: typeof(string),
parameterTypes: null);
// Generate body:
// return this.assemblyName;
il = getterMethodBuilder.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldfld, assemblyNameField);
il.Emit(OpCodes.Ret);
// Generate the AttributeUsage attribute for this attribute type:
// [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
TypeInfo attributeUsageTypeInfo = typeof(AttributeUsageAttribute).GetTypeInfo();
// Find the ctor that takes only AttributeTargets
ConstructorInfo attributeUsageConstructorInfo =
attributeUsageTypeInfo.DeclaredConstructors
.Single(c => c.GetParameters().Length == 1 &&
c.GetParameters()[0].ParameterType == typeof(AttributeTargets));
// Find the property to set AllowMultiple
PropertyInfo allowMultipleProperty =
attributeUsageTypeInfo.DeclaredProperties
.Single(f => string.Equals(f.Name, "AllowMultiple"));
// Create a builder to construct the instance via the ctor and property
CustomAttributeBuilder customAttributeBuilder =
new CustomAttributeBuilder(attributeUsageConstructorInfo,
new object[] { AttributeTargets.Assembly },
new PropertyInfo[] { allowMultipleProperty },
new object[] { true });
// Attach this attribute instance to the newly defined attribute type
attributeTypeBuilder.SetCustomAttribute(customAttributeBuilder);
// Make the TypeInfo real so the constructor can be used.
return attributeTypeBuilder.CreateTypeInfo()!.DeclaredConstructors.Single();
}
}
}