diff --git a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx
index d2bc611dbbbee9..f32b66df95e796 100644
--- a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx
+++ b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx
@@ -4289,4 +4289,7 @@
This operation is not available because the reflection support was disabled at compile time.
-
+
+ This AssemblyBuilder instance doesn't support saving. Use AssemblyBuilder.DefinePersistedAssembly to create an AssemblyBuilder instance that supports saving.
+
+
\ No newline at end of file
diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs
index d7ee53669cc91b..8599d39aa4b166 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Runtime.CompilerServices;
@@ -32,8 +33,56 @@ public ModuleBuilder DefineDynamicModule(string name)
return GetDynamicModuleCore(name);
}
+ ///
+ /// Defines an that can be saved to a file or stream.
+ ///
+ /// The name of the assembly.
+ /// The assembly that denotes the "system assembly" that houses the well-known types such as
+ /// A collection that contains the attributes of the assembly.
+ /// An that can be persisted.
+ /// The or or is null.
+ /// Currently the persisted assembly doesn't support running, need to save it and load back to run.
+ public static AssemblyBuilder DefinePersistedAssembly(AssemblyName name, Assembly coreAssembly, IEnumerable? assemblyAttributes = null)
+ {
+ ArgumentNullException.ThrowIfNull(name);
+ ArgumentException.ThrowIfNullOrEmpty(name.Name, "AssemblyName.Name");
+ ArgumentNullException.ThrowIfNull(coreAssembly);
+
+ Type assemblyType = Type.GetType("System.Reflection.Emit.AssemblyBuilderImpl, System.Reflection.Emit", throwOnError: true)!;
+ ConstructorInfo con = assemblyType.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, [typeof(AssemblyName), typeof(Assembly), typeof(IEnumerable)])!;
+ return (AssemblyBuilder)con.Invoke([name, coreAssembly, assemblyAttributes]);
+ }
+
protected abstract ModuleBuilder? GetDynamicModuleCore(string name);
+ ///
+ /// Serializes the assembly to .
+ ///
+ /// The to which the assembly serialized.
+ /// is null.
+ /// The AssemblyBuilder instance doesn't support saving.
+ public void Save(Stream stream) => SaveCore(stream);
+
+ ///
+ /// Saves the assembly to disk.
+ ///
+ /// The file name of the assembly.
+ /// is null.
+ /// The AssemblyBuilder instance doesn't support saving.
+ public void Save(string assemblyFileName)
+ {
+ ArgumentNullException.ThrowIfNull(assemblyFileName);
+
+ using var peStream = new FileStream(assemblyFileName, FileMode.Create, FileAccess.Write);
+ SaveCore(peStream);
+ }
+
+ ///
+ /// When implemented in a derived type, serializes the assembly to a stream.
+ ///
+ /// The stream to which the assembly serialized.
+ protected virtual void SaveCore(Stream stream) => throw new NotSupportedException(SR.NotSupported_AssemblySave);
+
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
{
ArgumentNullException.ThrowIfNull(con);
diff --git a/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs b/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs
index 7d55329ba942f3..1cd9aa71da7432 100644
--- a/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs
+++ b/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs
@@ -24,6 +24,7 @@ protected AssemblyBuilder() { }
public static System.Reflection.Emit.AssemblyBuilder DefineDynamicAssembly(System.Reflection.AssemblyName name, System.Reflection.Emit.AssemblyBuilderAccess access) { throw null; }
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Defining a dynamic assembly requires dynamic code.")]
public static System.Reflection.Emit.AssemblyBuilder DefineDynamicAssembly(System.Reflection.AssemblyName name, System.Reflection.Emit.AssemblyBuilderAccess access, System.Collections.Generic.IEnumerable? assemblyAttributes) { throw null; }
+ public static System.Reflection.Emit.AssemblyBuilder DefinePersistedAssembly(System.Reflection.AssemblyName name, System.Reflection.Assembly coreAssembly, System.Collections.Generic.IEnumerable? assemblyAttributes = null) { throw null; }
public System.Reflection.Emit.ModuleBuilder DefineDynamicModule(string name) { throw null; }
protected abstract System.Reflection.Emit.ModuleBuilder DefineDynamicModuleCore(string name);
public override bool Equals(object? obj) { throw null; }
@@ -54,6 +55,9 @@ protected AssemblyBuilder() { }
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed by trimming. If the type name is a string literal, consider using Type.GetType instead.")]
public override System.Type? GetType(string name, bool throwOnError, bool ignoreCase) { throw null; }
public override bool IsDefined(System.Type attributeType, bool inherit) { throw null; }
+ public void Save(string assemblyFileName) { throw null; }
+ public void Save(System.IO.Stream stream) { throw null; }
+ protected virtual void SaveCore(System.IO.Stream stream) { }
public void SetCustomAttribute(System.Reflection.ConstructorInfo con, byte[] binaryAttribute) { }
public void SetCustomAttribute(System.Reflection.Emit.CustomAttributeBuilder customBuilder) { }
protected abstract void SetCustomAttributeCore(System.Reflection.ConstructorInfo con, System.ReadOnlySpan binaryAttribute);
diff --git a/src/libraries/System.Reflection.Emit/src/ILLink/ILLink.Descriptors.LibraryBuild.xml b/src/libraries/System.Reflection.Emit/src/ILLink/ILLink.Descriptors.LibraryBuild.xml
index 4ac5a6f3584506..8cf11ab4c01f72 100644
--- a/src/libraries/System.Reflection.Emit/src/ILLink/ILLink.Descriptors.LibraryBuild.xml
+++ b/src/libraries/System.Reflection.Emit/src/ILLink/ILLink.Descriptors.LibraryBuild.xml
@@ -1,9 +1,8 @@
-
-
-
+
+
diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/AssemblyBuilderImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/AssemblyBuilderImpl.cs
index 834d8612a949e0..b52bec9f11c4a8 100644
--- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/AssemblyBuilderImpl.cs
+++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/AssemblyBuilderImpl.cs
@@ -19,15 +19,9 @@ internal sealed class AssemblyBuilderImpl : AssemblyBuilder
internal List? _customAttributes;
- internal AssemblyBuilderImpl(AssemblyName name, Assembly coreAssembly, IEnumerable? assemblyAttributes)
+ internal AssemblyBuilderImpl(AssemblyName name, Assembly coreAssembly, IEnumerable? assemblyAttributes = null)
{
- ArgumentNullException.ThrowIfNull(name);
-
- name = (AssemblyName)name.Clone();
-
- ArgumentException.ThrowIfNullOrEmpty(name.Name, "AssemblyName.Name");
-
- _assemblyName = name;
+ _assemblyName = (AssemblyName)name.Clone();
_coreAssembly = coreAssembly;
_metadataBuilder = new MetadataBuilder();
@@ -40,10 +34,6 @@ internal AssemblyBuilderImpl(AssemblyName name, Assembly coreAssembly, IEnumerab
}
}
- internal static AssemblyBuilderImpl DefinePersistedAssembly(AssemblyName name, Assembly coreAssembly,
- IEnumerable? assemblyAttributes)
- => new AssemblyBuilderImpl(name, coreAssembly, assemblyAttributes);
-
private void WritePEImage(Stream peStream, BlobBuilder ilBuilder, BlobBuilder fieldData)
{
var peHeaderBuilder = new PEHeaderBuilder(
@@ -64,7 +54,7 @@ private void WritePEImage(Stream peStream, BlobBuilder ilBuilder, BlobBuilder fi
peBlob.WriteContentTo(peStream);
}
- internal void Save(Stream stream)
+ protected override void SaveCore(Stream stream)
{
ArgumentNullException.ThrowIfNull(stream);
@@ -103,14 +93,6 @@ internal void Save(Stream stream)
private static AssemblyFlags AddContentType(AssemblyFlags flags, AssemblyContentType contentType)
=> (AssemblyFlags)((int)contentType << 9) | flags;
- internal void Save(string assemblyFileName)
- {
- ArgumentNullException.ThrowIfNull(assemblyFileName);
-
- using var peStream = new FileStream(assemblyFileName, FileMode.Create, FileAccess.Write);
- Save(peStream);
- }
-
protected override ModuleBuilder DefineDynamicModuleCore(string name)
{
if (_module != null)
diff --git a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveAssemblyBuilder.cs b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveAssemblyBuilder.cs
index 4fca521e6a352c..5dbabe683e0734 100644
--- a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveAssemblyBuilder.cs
+++ b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveAssemblyBuilder.cs
@@ -34,7 +34,7 @@ public void AssemblyWithDifferentTypes()
aName.CultureInfo = new CultureInfo("en");
aName.Flags = AssemblyNameFlags.Retargetable;
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndSaveMethod(aName, null, typeof(string), out MethodInfo saveMethod);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilder(aName);
ab.SetCustomAttribute(new CustomAttributeBuilder(typeof(AssemblyDelaySignAttribute).GetConstructor([typeof(bool)]), [true]));
@@ -213,10 +213,12 @@ public void AssemblyWithDifferentTypes()
eventb.SetRemoveOnMethod(mbRemove);
tbEvents.CreateType();
- saveMethod.Invoke(ab, [file.Path]);
+ ab.Save(file.Path);
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- CheckAssembly(assemblyFromDisk);
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ CheckAssembly(mlc.LoadFromAssemblyPath(file.Path));
+ }
}
}
diff --git a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveConstructorBuilderTests.cs b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveConstructorBuilderTests.cs
index 31ec0e31d87be0..618b01b2a9ae06 100644
--- a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveConstructorBuilderTests.cs
+++ b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveConstructorBuilderTests.cs
@@ -15,7 +15,7 @@ public void DefineConstructorsTest()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo saveMethod);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
ConstructorBuilder constructor = type.DefineDefaultConstructor(MethodAttributes.Public);
ConstructorBuilder constructor2 = type.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, [typeof(int)]);
constructor2.DefineParameter(1, ParameterAttributes.None, "parameter1");
@@ -28,7 +28,7 @@ public void DefineConstructorsTest()
il.Emit(OpCodes.Stfld, fieldBuilderA);
il.Emit(OpCodes.Ret);
type.CreateType();
- saveMethod.Invoke(ab, [file.Path]);
+ ab.Save(file.Path);
using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
{
@@ -51,7 +51,7 @@ public void DefineConstructorsTest()
[Fact]
public void DefineDefaultConstructor_WithTypeBuilderParent()
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo _);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
type.CreateType();
TypeBuilder child = ab.GetDynamicModule("MyModule").DefineType("ChildType", TypeAttributes.Public | TypeAttributes.Class);
child.SetParent(type);
@@ -69,7 +69,7 @@ public void DefineDefaultConstructor_TypesWithGenericParents()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo saveMethod);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
type.DefineGenericParameters("T");
ConstructorBuilder constructor = type.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes);
FieldBuilder field = type.DefineField("TestField", typeof(bool), FieldAttributes.Public | FieldAttributes.Static);
@@ -93,23 +93,26 @@ public void DefineDefaultConstructor_TypesWithGenericParents()
type2.SetParent(genericList);
type2.DefineDefaultConstructor(MethodAttributes.Public);
type2.CreateTypeInfo();
- saveMethod.Invoke(ab, [file.Path]);
-
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- ConstructorInfo[] ctors = assemblyFromDisk.GetType("MyType").GetConstructors();
- Assert.Equal(1, ctors.Length);
- Assert.Empty(ctors[0].GetParameters());
- Type derivedFromFile = assemblyFromDisk.GetType("Derived");
- Assert.NotNull(derivedFromFile.GetConstructor(Type.EmptyTypes));
- Assert.Equal(genericParent.FullName, derivedFromFile.BaseType.FullName);
- Assert.NotNull(assemblyFromDisk.GetType("Type2").GetConstructor(Type.EmptyTypes));
+ ab.Save(file.Path);
+
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ ConstructorInfo[] ctors = assemblyFromDisk.GetType("MyType").GetConstructors();
+ Assert.Equal(1, ctors.Length);
+ Assert.Empty(ctors[0].GetParameters());
+ Type derivedFromFile = assemblyFromDisk.GetType("Derived");
+ Assert.NotNull(derivedFromFile.GetConstructor(Type.EmptyTypes));
+ Assert.Equal(genericParent.FullName, derivedFromFile.BaseType.FullName);
+ Assert.NotNull(assemblyFromDisk.GetType("Type2").GetConstructor(Type.EmptyTypes));
+ }
}
}
[Fact]
public void DefineDefaultConstructor_Interface_ThrowsInvalidOperationException()
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndSaveMethod(new AssemblyName("MyAssembly"), null, typeof(string), out var _);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilder(new AssemblyName("MyAssembly"));
TypeBuilder type = ab.DefineDynamicModule("MyModule").DefineType("MyType", TypeAttributes.Public | TypeAttributes.Interface | TypeAttributes.Abstract);
Assert.Throws(() => type.DefineDefaultConstructor(MethodAttributes.Public));
}
@@ -117,7 +120,7 @@ public void DefineDefaultConstructor_Interface_ThrowsInvalidOperationException()
[Fact]
public void DefineDefaultConstructor_ThrowsNotSupportedException_IfParentNotCreated()
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo _);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
TypeBuilder child = ab.GetDynamicModule("MyModule").DefineType("MyType", TypeAttributes.Public);
child.SetParent(type);
Assert.Throws(() => child.DefineDefaultConstructor(MethodAttributes.Public));
@@ -126,14 +129,14 @@ public void DefineDefaultConstructor_ThrowsNotSupportedException_IfParentNotCrea
[Fact]
public void DefineDefaultConstructor_StaticVirtual_ThrowsArgumentException()
{
- AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo saveMethod);
+ AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
AssertExtensions.Throws(null, () => type.DefineDefaultConstructor(MethodAttributes.Virtual | MethodAttributes.Static));
}
[Fact]
public void DefineDefaultConstructor_ParentNoDefaultConstructor_ThrowsNotSupportedException()
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo _);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
FieldBuilder field = type.DefineField("TestField", typeof(int), FieldAttributes.Family);
ConstructorBuilder constructor = type.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, new[] { typeof(int) });
@@ -156,7 +159,7 @@ public void DefineDefaultConstructor_ParentNoDefaultConstructor_ThrowsNotSupport
[InlineData(MethodAttributes.PrivateScope)]
public void DefineDefaultConstructor_ParentPrivateDefaultConstructor_ThrowsNotSupportedException(MethodAttributes attributes)
{
- AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder baseType, out MethodInfo _);
+ AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder baseType);
ConstructorBuilder constructor = baseType.DefineConstructor(attributes, CallingConventions.HasThis, new[] { typeof(int) });
constructor.GetILGenerator().Emit(OpCodes.Ret);
@@ -168,7 +171,7 @@ public void DefineDefaultConstructor_ParentPrivateDefaultConstructor_ThrowsNotSu
[Fact]
public void GetConstructor_DeclaringTypeOfConstructorGenericTypeDefinition()
{
- AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo _);
+ AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
type.DefineGenericParameters("T");
ConstructorBuilder ctor = type.DefineDefaultConstructor(MethodAttributes.PrivateScope | MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName);
@@ -179,7 +182,7 @@ public void GetConstructor_DeclaringTypeOfConstructorGenericTypeDefinition()
[Fact]
public void TypeBuilder_GetConstructorWorks()
{
- AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo _);
+ AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
type.DefineGenericParameters("T");
ConstructorBuilder ctor = type.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.RTSpecialName);
@@ -193,7 +196,7 @@ public void TypeBuilder_GetConstructorWorks()
[Fact]
public void GetConstructor_DeclaringTypeOfConstructorNotGenericTypeDefinitionOfType_ThrowsArgumentException()
{
- AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type1, out MethodInfo _);
+ AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type1);
type1.DefineGenericParameters("T");
TypeBuilder type2 = ((ModuleBuilder)type1.Module).DefineType("TestType2", TypeAttributes.Class | TypeAttributes.Public);
@@ -209,7 +212,7 @@ public void GetConstructor_DeclaringTypeOfConstructorNotGenericTypeDefinitionOfT
[Fact]
public void GetConstructor_TypeNotGeneric_ThrowsArgumentException()
{
- AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo _);
+ AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
ConstructorBuilder ctor = type.DefineDefaultConstructor(MethodAttributes.Public);
diff --git a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveCustomAttributeTests.cs b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveCustomAttributeTests.cs
index 7d7191c8c365a0..e2f51e70dab228 100644
--- a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveCustomAttributeTests.cs
+++ b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveCustomAttributeTests.cs
@@ -42,12 +42,15 @@ public void AssemblyModuleWithCustomAttributes()
{
WriteAssemblyToDisk(assemblyName, Type.EmptyTypes, file.Path, _attributes, _attributes);
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Module moduleFromDisk = assemblyFromDisk.Modules.First();
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Module moduleFromDisk = assemblyFromDisk.Modules.First();
- AssemblySaveTools.AssertAssemblyNameAndModule(assemblyName, assemblyFromDisk.GetName(), moduleFromDisk);
- ValidateAttributes(assemblyFromDisk.GetCustomAttributesData());
- ValidateAttributes(moduleFromDisk.GetCustomAttributesData());
+ AssemblySaveTools.AssertAssemblyNameAndModule(assemblyName, assemblyFromDisk.GetName(), moduleFromDisk);
+ ValidateAttributes(assemblyFromDisk.GetCustomAttributesData());
+ ValidateAttributes(moduleFromDisk.GetCustomAttributesData());
+ }
}
}
@@ -61,33 +64,36 @@ public void MethodFieldWithCustomAttributes()
WriteAssemblyToDisk(PopulateAssemblyName(), types, file.Path, typeAttributes: _attributes,
methodAttributes: _attributes, fieldAttributes: _attributes);
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
- Module moduleFromDisk = assemblyFromDisk.Modules.First();
- Type[] typesFromDisk = moduleFromDisk.GetTypes();
+ Module moduleFromDisk = assemblyFromDisk.Modules.First();
+ Type[] typesFromDisk = moduleFromDisk.GetTypes();
- Assert.Equal(types.Length, typesFromDisk.Length);
+ Assert.Equal(types.Length, typesFromDisk.Length);
- for (int i = 0; i < types.Length; i++)
- {
- Type typeFromDisk = typesFromDisk[i];
- Type sourceType = types[i];
- MethodInfo[] methodsFromDisk = typeFromDisk.IsValueType ? typeFromDisk.GetMethods(BindingFlags.DeclaredOnly) : typeFromDisk.GetMethods();
- FieldInfo[] fieldsFromDisk = typeFromDisk.GetFields();
+ for (int i = 0; i < types.Length; i++)
+ {
+ Type typeFromDisk = typesFromDisk[i];
+ Type sourceType = types[i];
+ MethodInfo[] methodsFromDisk = typeFromDisk.IsValueType ? typeFromDisk.GetMethods(BindingFlags.DeclaredOnly) : typeFromDisk.GetMethods();
+ FieldInfo[] fieldsFromDisk = typeFromDisk.GetFields();
- AssemblySaveTools.AssertTypeProperties(sourceType, typeFromDisk);
- AssemblySaveTools.AssertMethods(sourceType.IsValueType ? sourceType.GetMethods(BindingFlags.DeclaredOnly) : sourceType.GetMethods(), methodsFromDisk);
- AssemblySaveTools.AssertFields(sourceType.GetFields(), fieldsFromDisk);
- ValidateAttributes(typeFromDisk.GetCustomAttributesData());
+ AssemblySaveTools.AssertTypeProperties(sourceType, typeFromDisk);
+ AssemblySaveTools.AssertMethods(sourceType.IsValueType ? sourceType.GetMethods(BindingFlags.DeclaredOnly) : sourceType.GetMethods(), methodsFromDisk);
+ AssemblySaveTools.AssertFields(sourceType.GetFields(), fieldsFromDisk);
+ ValidateAttributes(typeFromDisk.GetCustomAttributesData());
- for (int j = 0; j < methodsFromDisk.Length; j++)
- {
- ValidateAttributes(methodsFromDisk[j].GetCustomAttributesData());
- }
+ for (int j = 0; j < methodsFromDisk.Length; j++)
+ {
+ ValidateAttributes(methodsFromDisk[j].GetCustomAttributesData());
+ }
- for (int j = 0; j < fieldsFromDisk.Length; j++)
- {
- ValidateAttributes(fieldsFromDisk[j].GetCustomAttributesData());
+ for (int j = 0; j < fieldsFromDisk.Length; j++)
+ {
+ ValidateAttributes(fieldsFromDisk[j].GetCustomAttributesData());
+ }
}
}
}
@@ -119,10 +125,10 @@ private static void WriteAssemblyToDisk(AssemblyName assemblyName, Type[] types,
List? moduleAttributes = null, List? typeAttributes = null,
List? methodAttributes = null, List? fieldAttributes = null)
{
- AssemblyBuilder assemblyBuilder = AssemblySaveTools.PopulateAssemblyBuilderAndSaveMethod(assemblyName, assemblyAttributes, typeof(string), out MethodInfo saveMethod);
+ AssemblyBuilder assemblyBuilder = AssemblySaveTools.PopulateAssemblyBuilder(assemblyName, assemblyAttributes);
ModuleBuilder mb = assemblyBuilder.DefineDynamicModule(assemblyName.Name);
PopulateMembersForModule(mb, types, moduleAttributes, typeAttributes, methodAttributes, fieldAttributes);
- saveMethod.Invoke(assemblyBuilder, new object[] { fileLocation });
+ assemblyBuilder.Save(fileLocation);
}
private static void PopulateMembersForModule(ModuleBuilder mb, Type[] types, List? moduleAttributes,
@@ -192,62 +198,64 @@ public void CreateStructWithPseudoCustomAttributesTest()
new CustomAttributeBuilder(typeof(SpecialNameAttribute).GetConstructor(Type.EmptyTypes), new object[] { })
};
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndSaveMethod(
- PopulateAssemblyName(), null, typeof(string), out MethodInfo saveMethod);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilder(PopulateAssemblyName());
TypeBuilder tb = ab.DefineDynamicModule("Module").DefineType(type.FullName, type.Attributes, type.BaseType);
DefineFieldsAndSetAttributes(fieldAttributes.ToList(), type.GetFields(), tb);
typeAttributes.ForEach(tb.SetCustomAttribute);
tb.CreateType();
- saveMethod.Invoke(ab, new object[] { file.Path });
+ ab.Save(file.Path);
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Module moduleFromDisk = assemblyFromDisk.Modules.First();
- Type testType = moduleFromDisk.GetTypes()[0];
- IList attributesFromDisk = testType.GetCustomAttributesData();
-
- Assert.Equal(typeAttributes.Count - 3, attributesFromDisk.Count); // 3 pseudo attributes
- Assert.True((testType.Attributes & TypeAttributes.Serializable) != 0); // SerializableAttribute
- Assert.True((testType.Attributes & TypeAttributes.SpecialName) != 0); // SpecialNameAttribute
- Assert.True((testType.Attributes & TypeAttributes.ExplicitLayout) != 0); // StructLayoutAttribute
- Assert.True((testType.Attributes & TypeAttributes.UnicodeClass) != 0); // StructLayoutAttribute, not sure if we could test the PackingSize and Size
-
- for (int i = 0; i < attributesFromDisk.Count; i++)
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
{
- switch (attributesFromDisk[i].AttributeType.Name)
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Module moduleFromDisk = assemblyFromDisk.Modules.First();
+ Type testType = moduleFromDisk.GetTypes()[0];
+ IList attributesFromDisk = testType.GetCustomAttributesData();
+
+ Assert.Equal(typeAttributes.Count - 3, attributesFromDisk.Count); // 3 pseudo attributes
+ Assert.True((testType.Attributes & TypeAttributes.Serializable) != 0); // SerializableAttribute
+ Assert.True((testType.Attributes & TypeAttributes.SpecialName) != 0); // SpecialNameAttribute
+ Assert.True((testType.Attributes & TypeAttributes.ExplicitLayout) != 0); // StructLayoutAttribute
+ Assert.True((testType.Attributes & TypeAttributes.UnicodeClass) != 0); // StructLayoutAttribute, not sure if we could test the PackingSize and Size
+
+ for (int i = 0; i < attributesFromDisk.Count; i++)
{
- case "GuidAttribute":
- Assert.Equal(s_guidPair.args[0], attributesFromDisk[i].ConstructorArguments[0].Value);
- break;
- default:
- Assert.Fail($"Not expected attribute : {attributesFromDisk[i].AttributeType.Name}");
- break;
+ switch (attributesFromDisk[i].AttributeType.Name)
+ {
+ case "GuidAttribute":
+ Assert.Equal(s_guidPair.args[0], attributesFromDisk[i].ConstructorArguments[0].Value);
+ break;
+ default:
+ Assert.Fail($"Not expected attribute : {attributesFromDisk[i].AttributeType.Name}");
+ break;
+ }
}
- }
- FieldInfo field = testType.GetFields()[0];
- IList fieldAttributesFromDisk = field.GetCustomAttributesData();
+ FieldInfo field = testType.GetFields()[0];
+ IList fieldAttributesFromDisk = field.GetCustomAttributesData();
- Assert.Equal(3, fieldAttributesFromDisk.Count);
- Assert.True((field.Attributes & FieldAttributes.NotSerialized) != 0); // NonSerializedAttribute
- Assert.True((field.Attributes & FieldAttributes.SpecialName) != 0); // SpecialNameAttribute
- Assert.True((field.Attributes & FieldAttributes.HasFieldMarshal) != 0); // MarshalAsAttribute
+ Assert.Equal(3, fieldAttributesFromDisk.Count);
+ Assert.True((field.Attributes & FieldAttributes.NotSerialized) != 0); // NonSerializedAttribute
+ Assert.True((field.Attributes & FieldAttributes.SpecialName) != 0); // SpecialNameAttribute
+ Assert.True((field.Attributes & FieldAttributes.HasFieldMarshal) != 0); // MarshalAsAttribute
- for (int i = 0; i < fieldAttributesFromDisk.Count; i++)
- {
- switch (fieldAttributesFromDisk[i].AttributeType.Name)
+ for (int i = 0; i < fieldAttributesFromDisk.Count; i++)
{
- case "FieldOffsetAttribute":
- Assert.Equal(2, fieldAttributesFromDisk[i].ConstructorArguments[0].Value);
- break;
- case "MarshalAsAttribute":
- Assert.Equal(UnmanagedType.I4, (UnmanagedType)fieldAttributesFromDisk[i].ConstructorArguments[0].Value);
- break;
- case "GuidAttribute":
- Assert.Equal(s_guidPair.args[0], fieldAttributesFromDisk[i].ConstructorArguments[0].Value);
- break;
- default:
- Assert.Fail($"Not expected attribute : {fieldAttributesFromDisk[i].AttributeType.Name}");
- break;
+ switch (fieldAttributesFromDisk[i].AttributeType.Name)
+ {
+ case "FieldOffsetAttribute":
+ Assert.Equal(2, fieldAttributesFromDisk[i].ConstructorArguments[0].Value);
+ break;
+ case "MarshalAsAttribute":
+ Assert.Equal(UnmanagedType.I4, (UnmanagedType)fieldAttributesFromDisk[i].ConstructorArguments[0].Value);
+ break;
+ case "GuidAttribute":
+ Assert.Equal(s_guidPair.args[0], fieldAttributesFromDisk[i].ConstructorArguments[0].Value);
+ break;
+ default:
+ Assert.Fail($"Not expected attribute : {fieldAttributesFromDisk[i].AttributeType.Name}");
+ break;
+ }
}
}
}
@@ -282,128 +290,131 @@ public void InterfacesWithPseudoCustomAttributes()
new CustomAttributeBuilder(marshalAsEnumCtor, new object[] { UnmanagedType.CustomMarshaler },
new FieldInfo[] { typeof(MarshalAsAttribute).GetField("MarshalType")}, new object[] { typeof(EmptyTestClass).AssemblyQualifiedName })};
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndSaveMethod(PopulateAssemblyName(), null, typeof(string), out MethodInfo saveMethod);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilder(PopulateAssemblyName());
TypeBuilder tb = ab.DefineDynamicModule("Module").DefineType(type.FullName, type.Attributes);
typeAttributes.ForEach(tb.SetCustomAttribute);
DefineMethodsAndSetAttributes(methodAttributes, tb, type.GetMethods(), parameterAttributes);
tb.CreateType();
- saveMethod.Invoke(ab, new object[] { file.Path });
+ ab.Save(file.Path);
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Type testType = assemblyFromDisk.Modules.First().GetTypes()[0];
- IList attributesFromDisk = testType.GetCustomAttributesData();
-
- Assert.Equal(typeAttributes.Count, attributesFromDisk.Count);
- Assert.True((testType.Attributes & TypeAttributes.Import) != 0); // ComImportAttribute
- Assert.True((testType.Attributes & TypeAttributes.HasSecurity) != 0); // SuppressUnmanagedCodeSecurityAttribute
- for (int i = 0; i < attributesFromDisk.Count; i++)
- {
- switch (attributesFromDisk[i].AttributeType.Name)
- {
- case "ComImportAttribute": // just making sure that these attributes are expected
- case "SuppressUnmanagedCodeSecurityAttribute":
- break;
- case "GuidAttribute":
- Assert.Equal(s_guidPair.args[0], attributesFromDisk[i].ConstructorArguments[0].Value);
- break;
- default:
- Assert.Fail($"Not expected attribute : {attributesFromDisk[i].AttributeType.Name}");
- break;
- }
- }
-
- foreach (var method in testType.GetMethods())
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
{
- IList methodAttributesFromDisk = method.GetCustomAttributesData();
-
- Assert.True((method.Attributes & MethodAttributes.HasSecurity) != 0); // SuppressUnmanagedCodeSecurityAttribute
- Assert.True((method.Attributes & MethodAttributes.SpecialName) != 0); // SpecialNameAttribute
- MethodImplAttributes methodImpl = method.GetMethodImplementationFlags();
- Assert.True((methodImpl & MethodImplAttributes.NoInlining) != 0); // MethodImplAttribute
- Assert.True((methodImpl & MethodImplAttributes.AggressiveOptimization) != 0); // MethodImplAttribute
- Assert.True((methodImpl & MethodImplAttributes.PreserveSig) != 0); // PreserveSigAttribute
- Assert.Equal(methodAttributes.Count - 2, methodAttributesFromDisk.Count);
-
- for (int i = 0; i < methodAttributesFromDisk.Count; i++)
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Type testType = assemblyFromDisk.Modules.First().GetTypes()[0];
+ IList attributesFromDisk = testType.GetCustomAttributesData();
+
+ Assert.Equal(typeAttributes.Count, attributesFromDisk.Count);
+ Assert.True((testType.Attributes & TypeAttributes.Import) != 0); // ComImportAttribute
+ Assert.True((testType.Attributes & TypeAttributes.HasSecurity) != 0); // SuppressUnmanagedCodeSecurityAttribute
+ for (int i = 0; i < attributesFromDisk.Count; i++)
{
- switch (methodAttributesFromDisk[i].AttributeType.Name)
+ switch (attributesFromDisk[i].AttributeType.Name)
{
+ case "ComImportAttribute": // just making sure that these attributes are expected
case "SuppressUnmanagedCodeSecurityAttribute":
- case "PreserveSigAttribute":
break;
case "GuidAttribute":
- Assert.Equal(s_guidPair.args[0], methodAttributesFromDisk[i].ConstructorArguments[0].Value);
- break;
- case "DllImportAttribute":
- {
- CustomAttributeData attribute = methodAttributesFromDisk[i];
- Assert.Equal("test.dll", attribute.ConstructorArguments[0].Value);
-
- for (int j = 0; j < attribute.NamedArguments.Count; j++)
- {
- switch (attribute.NamedArguments[j].MemberName)
- {
- case "CharSet":
- Assert.Equal(CharSet.Ansi, (CharSet)attribute.NamedArguments[j].TypedValue.Value);
- break;
- case "SetLastError":
- Assert.True((bool)attribute.NamedArguments[j].TypedValue.Value);
- break;
- case "CallingConvention":
- Assert.Equal(CallingConvention.FastCall, (CallingConvention)attribute.NamedArguments[j].TypedValue.Value);
- break;
- case "BestFitMapping":
- Assert.True((bool)attribute.NamedArguments[j].TypedValue.Value);
- break;
- case "ThrowOnUnmappableChar":
- Assert.False((bool)attribute.NamedArguments[j].TypedValue.Value);
- break;
- }
- }
- }
+ Assert.Equal(s_guidPair.args[0], attributesFromDisk[i].ConstructorArguments[0].Value);
break;
default:
- Assert.Fail($"Not expected attribute : {methodAttributesFromDisk[i].AttributeType.Name}");
+ Assert.Fail($"Not expected attribute : {attributesFromDisk[i].AttributeType.Name}");
break;
}
}
- foreach(ParameterInfo param in method.GetParameters())
+ foreach (var method in testType.GetMethods())
{
- IList paramAttributes = param.GetCustomAttributesData();
-
- Assert.Equal(5, paramAttributes.Count);
- Assert.True((param.Attributes & ParameterAttributes.In) != 0); // InAttribute
- Assert.True((param.Attributes & ParameterAttributes.Out) != 0); // OutAttribute
- Assert.True((param.Attributes & ParameterAttributes.Optional) != 0); // OptionalAttribute
- Assert.True((param.Attributes & ParameterAttributes.HasFieldMarshal) != 0); // MarshalAsAttribute
+ IList methodAttributesFromDisk = method.GetCustomAttributesData();
- if (param.ParameterType.Equals(typeof(string)))
- {
- Assert.Equal("Hello", param.DefaultValue);
- }
+ Assert.True((method.Attributes & MethodAttributes.HasSecurity) != 0); // SuppressUnmanagedCodeSecurityAttribute
+ Assert.True((method.Attributes & MethodAttributes.SpecialName) != 0); // SpecialNameAttribute
+ MethodImplAttributes methodImpl = method.GetMethodImplementationFlags();
+ Assert.True((methodImpl & MethodImplAttributes.NoInlining) != 0); // MethodImplAttribute
+ Assert.True((methodImpl & MethodImplAttributes.AggressiveOptimization) != 0); // MethodImplAttribute
+ Assert.True((methodImpl & MethodImplAttributes.PreserveSig) != 0); // PreserveSigAttribute
+ Assert.Equal(methodAttributes.Count - 2, methodAttributesFromDisk.Count);
- for (int i = 0; i < paramAttributes.Count; i++)
+ for (int i = 0; i < methodAttributesFromDisk.Count; i++)
{
- switch (paramAttributes[i].AttributeType.Name)
+ switch (methodAttributesFromDisk[i].AttributeType.Name)
{
- case "InAttribute":
- case "OutAttribute":
- case "OptionalAttribute":
- break;
- case "MarshalAsAttribute":
- Assert.Equal(UnmanagedType.CustomMarshaler, (UnmanagedType)paramAttributes[i].ConstructorArguments[0].Value);
- Assert.Equal(typeof(EmptyTestClass).AssemblyQualifiedName,
- paramAttributes[i].NamedArguments.First(na => na.MemberName == "MarshalType").TypedValue.Value);
+ case "SuppressUnmanagedCodeSecurityAttribute":
+ case "PreserveSigAttribute":
break;
case "GuidAttribute":
- Assert.Equal(s_guidPair.args[0], paramAttributes[i].ConstructorArguments[0].Value);
+ Assert.Equal(s_guidPair.args[0], methodAttributesFromDisk[i].ConstructorArguments[0].Value);
+ break;
+ case "DllImportAttribute":
+ {
+ CustomAttributeData attribute = methodAttributesFromDisk[i];
+ Assert.Equal("test.dll", attribute.ConstructorArguments[0].Value);
+
+ for (int j = 0; j < attribute.NamedArguments.Count; j++)
+ {
+ switch (attribute.NamedArguments[j].MemberName)
+ {
+ case "CharSet":
+ Assert.Equal(CharSet.Ansi, (CharSet)attribute.NamedArguments[j].TypedValue.Value);
+ break;
+ case "SetLastError":
+ Assert.True((bool)attribute.NamedArguments[j].TypedValue.Value);
+ break;
+ case "CallingConvention":
+ Assert.Equal(CallingConvention.FastCall, (CallingConvention)attribute.NamedArguments[j].TypedValue.Value);
+ break;
+ case "BestFitMapping":
+ Assert.True((bool)attribute.NamedArguments[j].TypedValue.Value);
+ break;
+ case "ThrowOnUnmappableChar":
+ Assert.False((bool)attribute.NamedArguments[j].TypedValue.Value);
+ break;
+ }
+ }
+ }
break;
default:
- Assert.Fail($"Not expected attribute : {paramAttributes[i].AttributeType.Name}");
+ Assert.Fail($"Not expected attribute : {methodAttributesFromDisk[i].AttributeType.Name}");
break;
}
}
+
+ foreach (ParameterInfo param in method.GetParameters())
+ {
+ IList paramAttributes = param.GetCustomAttributesData();
+
+ Assert.Equal(5, paramAttributes.Count);
+ Assert.True((param.Attributes & ParameterAttributes.In) != 0); // InAttribute
+ Assert.True((param.Attributes & ParameterAttributes.Out) != 0); // OutAttribute
+ Assert.True((param.Attributes & ParameterAttributes.Optional) != 0); // OptionalAttribute
+ Assert.True((param.Attributes & ParameterAttributes.HasFieldMarshal) != 0); // MarshalAsAttribute
+
+ if (param.ParameterType.Equals(typeof(string)))
+ {
+ Assert.Equal("Hello", param.DefaultValue);
+ }
+
+ for (int i = 0; i < paramAttributes.Count; i++)
+ {
+ switch (paramAttributes[i].AttributeType.Name)
+ {
+ case "InAttribute":
+ case "OutAttribute":
+ case "OptionalAttribute":
+ break;
+ case "MarshalAsAttribute":
+ Assert.Equal(UnmanagedType.CustomMarshaler, (UnmanagedType)paramAttributes[i].ConstructorArguments[0].Value);
+ Assert.Equal(typeof(EmptyTestClass).AssemblyQualifiedName,
+ paramAttributes[i].NamedArguments.First(na => na.MemberName == "MarshalType").TypedValue.Value);
+ break;
+ case "GuidAttribute":
+ Assert.Equal(s_guidPair.args[0], paramAttributes[i].ConstructorArguments[0].Value);
+ break;
+ default:
+ Assert.Fail($"Not expected attribute : {paramAttributes[i].AttributeType.Name}");
+ break;
+ }
+ }
+ }
}
}
}
@@ -432,33 +443,35 @@ public void MarshalAsPseudoCustomAttributesTest(CustomAttributeBuilder attribute
using (TempFile file = TempFile.Create())
{
Type type = typeof(StructWithFields);
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndSaveMethod(
- PopulateAssemblyName(), null, typeof(string), out MethodInfo saveMethod);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilder(PopulateAssemblyName());
TypeBuilder tb = ab.DefineDynamicModule("Module").DefineType(type.FullName, type.Attributes, type.BaseType);
FieldInfo stringField = type.GetFields()[1];
FieldBuilder fb = tb.DefineField(stringField.Name, stringField.FieldType, stringField.Attributes);
fb.SetCustomAttribute(attribute);
tb.CreateType();
- saveMethod.Invoke(ab, new object[] { file.Path });
+ ab.Save(file.Path);
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- FieldInfo field = assemblyFromDisk.Modules.First().GetTypes()[0].GetFields()[0];
- CustomAttributeData attributeFromDisk = field.GetCustomAttributesData()[0];
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ FieldInfo field = assemblyFromDisk.Modules.First().GetTypes()[0].GetFields()[0];
+ CustomAttributeData attributeFromDisk = field.GetCustomAttributesData()[0];
- Assert.Equal(1, field.GetCustomAttributesData().Count);
- Assert.True((field.Attributes & FieldAttributes.HasFieldMarshal) != 0);
- Assert.Equal(expectedType, (UnmanagedType)attributeFromDisk.ConstructorArguments[0].Value);
+ Assert.Equal(1, field.GetCustomAttributesData().Count);
+ Assert.True((field.Attributes & FieldAttributes.HasFieldMarshal) != 0);
+ Assert.Equal(expectedType, (UnmanagedType)attributeFromDisk.ConstructorArguments[0].Value);
- switch (expectedType)
- {
- case UnmanagedType.CustomMarshaler:
- Assert.Equal(typeof(EmptyTestClass).AssemblyQualifiedName,
- attributeFromDisk.NamedArguments.First(na => na.MemberName == "MarshalType").TypedValue.Value);
- Assert.Equal("MyCookie", attributeFromDisk.NamedArguments.First(na => na.MemberName == "MarshalCookie").TypedValue.Value);
- break;
- case UnmanagedType.ByValTStr:
- Assert.Equal(256, attributeFromDisk.NamedArguments.First(na => na.MemberName == "SizeConst").TypedValue.Value);
- break;
+ switch (expectedType)
+ {
+ case UnmanagedType.CustomMarshaler:
+ Assert.Equal(typeof(EmptyTestClass).AssemblyQualifiedName,
+ attributeFromDisk.NamedArguments.First(na => na.MemberName == "MarshalType").TypedValue.Value);
+ Assert.Equal("MyCookie", attributeFromDisk.NamedArguments.First(na => na.MemberName == "MarshalCookie").TypedValue.Value);
+ break;
+ case UnmanagedType.ByValTStr:
+ Assert.Equal(256, attributeFromDisk.NamedArguments.First(na => na.MemberName == "SizeConst").TypedValue.Value);
+ break;
+ }
}
}
}
@@ -468,40 +481,43 @@ public void EnumBuilderSetCustomAttributesTest()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndSaveMethod(
- PopulateAssemblyName(), null, typeof(string), out MethodInfo saveMethod);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilder(PopulateAssemblyName());
EnumBuilder enumBuilder = ab.DefineDynamicModule("Module").DefineEnum("TestEnum", TypeAttributes.Public, typeof(int));
ConstructorInfo attributeConstructor = typeof(BoolAttribute).GetConstructor(new Type[] { typeof(bool) });
- CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder(attributeConstructor, new object[] { true });
+ CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder(attributeConstructor, [true]);
enumBuilder.SetCustomAttribute(attributeBuilder);
enumBuilder.SetCustomAttribute(new CustomAttributeBuilder(s_guidPair.con, s_guidPair.args));
enumBuilder.CreateTypeInfo();
- saveMethod.Invoke(ab, new object[] { file.Path });
+ ab.Save(file.Path);
- Type testEnum = AssemblySaveTools.LoadAssemblyFromPath(file.Path).Modules.First().GetType("TestEnum");
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Type testEnum = mlc.LoadFromAssemblyPath(file.Path).Modules.First().GetType("TestEnum");
- Assert.True(testEnum.IsEnum);
- AssemblySaveTools.AssertTypeProperties(enumBuilder, testEnum);
+ Assert.True(testEnum.IsEnum);
+ AssemblySaveTools.AssertTypeProperties(enumBuilder, testEnum);
- CustomAttributeData[] attributes = testEnum.GetCustomAttributesData().ToArray();
- if (attributes[0].AttributeType.Name == s_guidType.Name)
- {
- AssertEnumAttributes(s_guidType.FullName, "9ED54F84-A89D-4fcd-A854-44251E925F09", attributes[0]);
- AssertEnumAttributes(typeof(BoolAttribute).FullName, true, attributes[1]);
- }
- else
- {
- AssertEnumAttributes(s_guidType.FullName, "9ED54F84-A89D-4fcd-A854-44251E925F09", attributes[1]);
- AssertEnumAttributes(typeof(BoolAttribute).FullName, true, attributes[0]);
- }
+ CustomAttributeData[] attributes = testEnum.GetCustomAttributesData().ToArray();
+ if (attributes[0].AttributeType.Name == s_guidType.Name)
+ {
+ AssertEnumAttributes(s_guidType.FullName, "9ED54F84-A89D-4fcd-A854-44251E925F09", attributes[0]);
+ AssertEnumAttributes(typeof(BoolAttribute).FullName, true, attributes[1]);
+ }
+ else
+ {
+ AssertEnumAttributes(s_guidType.FullName, "9ED54F84-A89D-4fcd-A854-44251E925F09", attributes[1]);
+ AssertEnumAttributes(typeof(BoolAttribute).FullName, true, attributes[0]);
+ }
+ }
}
}
- private void AssertEnumAttributes(string fullName, object value, CustomAttributeData testAttrbiute)
+
+ private void AssertEnumAttributes(string fullName, object value, CustomAttributeData testAttribute)
{
- Assert.Equal(fullName, testAttrbiute.AttributeType.FullName);
- Assert.Equal(value, testAttrbiute.ConstructorArguments[0].Value);
+ Assert.Equal(fullName, testAttribute.AttributeType.FullName);
+ Assert.Equal(value, testAttribute.ConstructorArguments[0].Value);
}
}
diff --git a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveEnumBuilderTests.cs b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveEnumBuilderTests.cs
index 8ab0de66a8f205..9ea6560c5aea0e 100644
--- a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveEnumBuilderTests.cs
+++ b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveEnumBuilderTests.cs
@@ -64,24 +64,27 @@ public void DefineLiteral(Type underlyingType, object literalValue)
{
using (TempFile file = TempFile.Create())
{
- EnumBuilder enumBuilder = CreateAssemblyAndDefineEnum(out AssemblyBuilder assemblyBuilder, out MethodInfo saveMethod, out TypeBuilder type, underlyingType);
+ EnumBuilder enumBuilder = CreateAssemblyAndDefineEnum(out AssemblyBuilder assemblyBuilder, out TypeBuilder type, underlyingType);
FieldBuilder literal = enumBuilder.DefineLiteral("FieldOne", literalValue);
enumBuilder.CreateTypeInfo();
type.CreateTypeInfo();
- saveMethod.Invoke(assemblyBuilder, new object[] { file.Path });
-
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Module moduleFromDisk = assemblyFromDisk.Modules.First();
- Type testEnum = moduleFromDisk.GetType("TestEnum");
-
- Assert.True(testEnum.IsEnum);
- AssemblySaveTools.AssertTypeProperties(enumBuilder, testEnum);
- Assert.Equal(underlyingType.FullName, testEnum.GetEnumUnderlyingType().FullName);
-
- FieldInfo testField = testEnum.GetField("FieldOne");
- Assert.Equal(enumBuilder.Name, testField.DeclaringType.Name);
- Assert.Equal(FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal | FieldAttributes.HasDefault, literal.Attributes);
- Assert.Equal(enumBuilder.AsType().FullName, testField.FieldType.FullName);
+ assemblyBuilder.Save(file.Path);
+
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Module moduleFromDisk = assemblyFromDisk.Modules.First();
+ Type testEnum = moduleFromDisk.GetType("TestEnum");
+
+ Assert.True(testEnum.IsEnum);
+ AssemblySaveTools.AssertTypeProperties(enumBuilder, testEnum);
+ Assert.Equal(underlyingType.FullName, testEnum.GetEnumUnderlyingType().FullName);
+
+ FieldInfo testField = testEnum.GetField("FieldOne");
+ Assert.Equal(enumBuilder.Name, testField.DeclaringType.Name);
+ Assert.Equal(FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal | FieldAttributes.HasDefault, literal.Attributes);
+ Assert.Equal(enumBuilder.AsType().FullName, testField.FieldType.FullName);
+ }
}
}
@@ -94,7 +97,7 @@ public void SaveArrayTypeSignature(int rank, string name)
{
using (TempFile file = TempFile.Create())
{
- EnumBuilder enumBuilder = CreateAssemblyAndDefineEnum(out AssemblyBuilder ab, out MethodInfo saveMethod, out TypeBuilder tb);
+ EnumBuilder enumBuilder = CreateAssemblyAndDefineEnum(out AssemblyBuilder ab, out TypeBuilder tb);
Type arrayType = rank == 0 ? enumBuilder.MakeArrayType() : enumBuilder.MakeArrayType(rank);
MethodBuilder mb = tb.DefineMethod("TestMethod", MethodAttributes.Public);
mb.SetReturnType(arrayType);
@@ -102,21 +105,23 @@ public void SaveArrayTypeSignature(int rank, string name)
mb.GetILGenerator().Emit(OpCodes.Ret);
enumBuilder.CreateType();
tb.CreateType();
- saveMethod.Invoke(ab, new object[] { file.Path });
+ ab.Save(file.Path);
- Type testType = AssemblySaveTools.LoadAssemblyFromPath(file.Path).Modules.First().GetType("TestInterface");
- MethodInfo testMethod = testType.GetMethod("TestMethod");
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Type testType = mlc.LoadFromAssemblyPath(file.Path).Modules.First().GetType("TestInterface");
+ MethodInfo testMethod = testType.GetMethod("TestMethod");
- AssertArrayTypeSignature(rank, name, testMethod.ReturnType);
- AssertArrayTypeSignature(rank, name, testMethod.GetParameters()[1].ParameterType);
+ AssertArrayTypeSignature(rank, name, testMethod.ReturnType);
+ AssertArrayTypeSignature(rank, name, testMethod.GetParameters()[1].ParameterType);
+ }
}
}
private EnumBuilder CreateAssemblyAndDefineEnum(out AssemblyBuilder assemblyBuilder,
- out MethodInfo saveMethod, out TypeBuilder type, Type? underlyingType = null)
+ out TypeBuilder type, Type? underlyingType = null)
{
- assemblyBuilder = AssemblySaveTools.PopulateAssemblyBuilderAndSaveMethod(
- PopulateAssemblyName(), null, typeof(string), out saveMethod);
+ assemblyBuilder = AssemblySaveTools.PopulateAssemblyBuilder(PopulateAssemblyName());
ModuleBuilder mb = assemblyBuilder.DefineDynamicModule("My Module");
type = mb.DefineType("TestInterface", TypeAttributes.Interface | TypeAttributes.Abstract);
return mb.DefineEnum("TestEnum", TypeAttributes.Public, underlyingType == null ? typeof(int) : underlyingType);
@@ -135,7 +140,7 @@ public void SaveByRefTypeSignature()
{
using (TempFile file = TempFile.Create())
{
- EnumBuilder eb = CreateAssemblyAndDefineEnum(out AssemblyBuilder assemblyBuilder, out MethodInfo saveMethod, out TypeBuilder tb);
+ EnumBuilder eb = CreateAssemblyAndDefineEnum(out AssemblyBuilder assemblyBuilder, out TypeBuilder tb);
Type byrefType = eb.MakeByRefType();
MethodBuilder mb = tb.DefineMethod("TestMethod", MethodAttributes.Public);
mb.SetReturnType(byrefType);
@@ -143,14 +148,17 @@ public void SaveByRefTypeSignature()
mb.GetILGenerator().Emit(OpCodes.Ret);
eb.CreateType();
tb.CreateType();
- saveMethod.Invoke(assemblyBuilder, new object[] { file.Path });
+ assemblyBuilder.Save(file.Path);
- Type testType = AssemblySaveTools.LoadAssemblyFromPath(file.Path).Modules.First().GetType("TestInterface");
- MethodInfo testMethod = testType.GetMethod("TestMethod");
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Type testType = mlc.LoadFromAssemblyPath(file.Path).Modules.First().GetType("TestInterface");
+ MethodInfo testMethod = testType.GetMethod("TestMethod");
- Assert.False(testMethod.GetParameters()[0].ParameterType.IsByRef);
- AssertByRefType(testMethod.GetParameters()[1].ParameterType);
- AssertByRefType(testMethod.ReturnType);
+ Assert.False(testMethod.GetParameters()[0].ParameterType.IsByRef);
+ AssertByRefType(testMethod.GetParameters()[1].ParameterType);
+ AssertByRefType(testMethod.ReturnType);
+ }
}
}
@@ -165,7 +173,7 @@ public void SavePointerTypeSignature()
{
using (TempFile file = TempFile.Create())
{
- EnumBuilder eb = CreateAssemblyAndDefineEnum(out AssemblyBuilder assemblyBuilder, out MethodInfo saveMethod, out TypeBuilder tb);
+ EnumBuilder eb = CreateAssemblyAndDefineEnum(out AssemblyBuilder assemblyBuilder, out TypeBuilder tb);
Type pointerType = eb.MakePointerType();
MethodBuilder mb = tb.DefineMethod("TestMethod", MethodAttributes.Public);
mb.SetReturnType(pointerType);
@@ -173,14 +181,17 @@ public void SavePointerTypeSignature()
mb.GetILGenerator().Emit(OpCodes.Ret);
eb.CreateType();
tb.CreateType();
- saveMethod.Invoke(assemblyBuilder, new object[] { file.Path });
+ assemblyBuilder.Save(file.Path);
- Type testType = AssemblySaveTools.LoadAssemblyFromPath(file.Path).Modules.First().GetType("TestInterface");
- MethodInfo testMethod = testType.GetMethod("TestMethod");
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Type testType = mlc.LoadFromAssemblyPath(file.Path).Modules.First().GetType("TestInterface");
+ MethodInfo testMethod = testType.GetMethod("TestMethod");
- Assert.False(testMethod.GetParameters()[0].ParameterType.IsPointer);
- AssertPointerType(testMethod.GetParameters()[1].ParameterType);
- AssertPointerType(testMethod.ReturnType);
+ Assert.False(testMethod.GetParameters()[0].ParameterType.IsPointer);
+ AssertPointerType(testMethod.GetParameters()[1].ParameterType);
+ AssertPointerType(testMethod.ReturnType);
+ }
}
}
diff --git a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveEventBuilderTests.cs b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveEventBuilderTests.cs
index 0d95824b45d9ff..d7c03fa49fc2b2 100644
--- a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveEventBuilderTests.cs
+++ b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveEventBuilderTests.cs
@@ -16,7 +16,7 @@ public void DefineEventAndItsAccessors()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo saveMethod);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
EventBuilder eventType = type.DefineEvent("TestEvent", EventAttributes.SpecialName, typeof(int));
MethodBuilder addMethod = type.DefineMethod("AddMethod", MethodAttributes.Public | MethodAttributes.SpecialName);
MethodBuilder addMethod2 = type.DefineMethod("AddMethod2", MethodAttributes.Public | MethodAttributes.HideBySig, typeof(int), Type.EmptyTypes);
@@ -42,29 +42,32 @@ public void DefineEventAndItsAccessors()
otherILGenerator.Emit(OpCodes.Ret);
eventType.AddOtherMethod(otherMethod);
type.CreateType();
- saveMethod.Invoke(ab, new[] { file.Path });
+ ab.Save(file.Path);
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
- EventInfo eventFromDisk = typeFromDisk.GetEvent("TestEvent");
- Assert.Equal(addMethod2.Name, eventFromDisk.AddMethod.Name);
- Assert.Equal(raiseMethod.Name, eventFromDisk.RaiseMethod.Name);
- Assert.Equal(removeMethod.Name, eventFromDisk.RemoveMethod.Name);
- Assert.Equal(typeof(int).FullName, eventFromDisk.EventHandlerType.FullName);
- Assert.NotNull(typeFromDisk.GetMethod("OtherMethod", BindingFlags.NonPublic | BindingFlags.Instance));
- Assert.Equal(EventAttributes.SpecialName, eventFromDisk.Attributes);
- IList caData = eventFromDisk.GetCustomAttributesData();
- Assert.Equal(1, caData.Count);
- Assert.Equal(typeof(IntPropertyAttribute).FullName, caData[0].AttributeType.FullName);
- Assert.Equal(1, caData[0].ConstructorArguments.Count);
- Assert.Equal(9, caData[0].ConstructorArguments[0].Value);
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
+ EventInfo eventFromDisk = typeFromDisk.GetEvent("TestEvent");
+ Assert.Equal(addMethod2.Name, eventFromDisk.AddMethod.Name);
+ Assert.Equal(raiseMethod.Name, eventFromDisk.RaiseMethod.Name);
+ Assert.Equal(removeMethod.Name, eventFromDisk.RemoveMethod.Name);
+ Assert.Equal(typeof(int).FullName, eventFromDisk.EventHandlerType.FullName);
+ Assert.NotNull(typeFromDisk.GetMethod("OtherMethod", BindingFlags.NonPublic | BindingFlags.Instance));
+ Assert.Equal(EventAttributes.SpecialName, eventFromDisk.Attributes);
+ IList caData = eventFromDisk.GetCustomAttributesData();
+ Assert.Equal(1, caData.Count);
+ Assert.Equal(typeof(IntPropertyAttribute).FullName, caData[0].AttributeType.FullName);
+ Assert.Equal(1, caData[0].ConstructorArguments.Count);
+ Assert.Equal(9, caData[0].ConstructorArguments[0].Value);
+ }
}
}
[Fact]
public void Set_NullValue_ThrowsArgumentNullException()
{
- AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo _);
+ AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
EventBuilder eventBuilder = type.DefineEvent("TestEvent", EventAttributes.None, typeof(string));
AssertExtensions.Throws("eventtype", () => type.DefineEvent("EventTypeNull", EventAttributes.None, null));
@@ -78,7 +81,7 @@ public void Set_NullValue_ThrowsArgumentNullException()
[Fact]
public void Set_WhenTypeAlreadyCreated_ThrowsInvalidOperationException()
{
- AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo _);
+ AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
EventBuilder eventBuilder = type.DefineEvent("TestEvent", EventAttributes.None, typeof(int));
MethodBuilder method = type.DefineMethod("TestMethod", MethodAttributes.Public | MethodAttributes.SpecialName, typeof(int), null);
diff --git a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveILGeneratorTests.cs b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveILGeneratorTests.cs
index 331f8169f3afa5..b47aca11628bd3 100644
--- a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveILGeneratorTests.cs
+++ b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveILGeneratorTests.cs
@@ -17,23 +17,25 @@ public void MethodWithEmptyBody()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo saveMethod);
- MethodBuilder methodBuilder = type.DefineMethod("EmptyMethod", MethodAttributes.Public, typeof(void), new[] { typeof(Version) });
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
+ MethodBuilder methodBuilder = type.DefineMethod("EmptyMethod", MethodAttributes.Public, typeof(void), [typeof(Version)]);
ILGenerator il = methodBuilder.GetILGenerator();
il.Emit(OpCodes.Ret);
type.CreateType();
- saveMethod.Invoke(ab, new object[] { file.Path });
-
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
- MethodInfo method = typeFromDisk.GetMethod("EmptyMethod");
- MethodBody body = method.GetMethodBody();
- Assert.Empty(body.LocalVariables);
- Assert.Empty(body.ExceptionHandlingClauses);
- byte[]? bodyBytes = body.GetILAsByteArray();
- Assert.NotNull(bodyBytes);
- Assert.Equal(OpCodes.Ret.Value, bodyBytes[0]);
+ ab.Save(file.Path);
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
+ MethodInfo method = typeFromDisk.GetMethod("EmptyMethod");
+ MethodBody body = method.GetMethodBody();
+ Assert.Empty(body.LocalVariables);
+ Assert.Empty(body.ExceptionHandlingClauses);
+ byte[]? bodyBytes = body.GetILAsByteArray();
+ Assert.NotNull(bodyBytes);
+ Assert.Equal(OpCodes.Ret.Value, bodyBytes[0]);
+ }
}
}
@@ -44,7 +46,7 @@ public void MethodReturning_Int(int size)
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo saveMethod);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
MethodBuilder method = type.DefineMethod("TestMethod", MethodAttributes.Public | MethodAttributes.Static, typeof(int), Type.EmptyTypes);
ILGenerator ilGenerator = method.GetILGenerator(size);
@@ -52,16 +54,19 @@ public void MethodReturning_Int(int size)
ilGenerator.Emit(OpCodes.Ldc_I4, expectedReturn);
ilGenerator.Emit(OpCodes.Ret);
type.CreateType();
- saveMethod.Invoke(ab, new object[] { file.Path });
-
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
- MethodInfo methodFromFile = typeFromDisk.GetMethod("TestMethod");
- MethodBody body = methodFromFile.GetMethodBody();
- byte[]? bodyBytes = body.GetILAsByteArray();
- Assert.NotNull(bodyBytes);
- Assert.Equal(OpCodes.Ldc_I4_5.Value, bodyBytes[0]);
- Assert.Equal(OpCodes.Ret.Value, bodyBytes[1]);
+ ab.Save(file.Path);
+
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
+ MethodInfo methodFromFile = typeFromDisk.GetMethod("TestMethod");
+ MethodBody body = methodFromFile.GetMethodBody();
+ byte[]? bodyBytes = body.GetILAsByteArray();
+ Assert.NotNull(bodyBytes);
+ Assert.Equal(OpCodes.Ldc_I4_5.Value, bodyBytes[0]);
+ Assert.Equal(OpCodes.Ret.Value, bodyBytes[1]);
+ }
}
}
@@ -72,10 +77,10 @@ public void TypeWithTwoMethod_ReferenceMethodArguments(int multiplier)
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo saveMethod);
- MethodBuilder multiplyMethod = type.DefineMethod("MultiplyMethod", MethodAttributes.Public | MethodAttributes.Static, typeof(int), new Type[] { typeof(int) });
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
+ MethodBuilder multiplyMethod = type.DefineMethod("MultiplyMethod", MethodAttributes.Public | MethodAttributes.Static, typeof(int), [typeof(int)]);
multiplyMethod.DefineParameter(1, ParameterAttributes.None, "myParam");
- MethodBuilder addMethod = type.DefineMethod("AddMethod", MethodAttributes.Public | MethodAttributes.Static, typeof(int), new Type[] { typeof(int), typeof(int) });
+ MethodBuilder addMethod = type.DefineMethod("AddMethod", MethodAttributes.Public | MethodAttributes.Static, typeof(int), [typeof(int), typeof(int)]);
addMethod.DefineParameter(1, ParameterAttributes.None, "firsParam");
addMethod.DefineParameter(2, ParameterAttributes.None, "secondParam");
@@ -91,22 +96,25 @@ public void TypeWithTwoMethod_ReferenceMethodArguments(int multiplier)
addMethodIL.Emit(OpCodes.Add);
addMethodIL.Emit(OpCodes.Ret);
type.CreateType();
- saveMethod.Invoke(ab, new object[] { file.Path });
-
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
- byte[]? multiplyBody = typeFromDisk.GetMethod("MultiplyMethod").GetMethodBody().GetILAsByteArray();
- byte[]? addBody = typeFromDisk.GetMethod("AddMethod").GetMethodBody().GetILAsByteArray();
-
- Assert.NotNull(multiplyBody);
- Assert.Equal(OpCodes.Ldarg_0.Value, multiplyBody[0]);
- Assert.Equal(OpCodes.Ldc_I4_S.Value, multiplyBody[1]);
- Assert.Equal(multiplier, multiplyBody[2]);
- Assert.Equal(OpCodes.Mul.Value, multiplyBody[3]);
- Assert.NotNull(addBody);
- Assert.Equal(OpCodes.Ldarg_0.Value, addBody[0]);
- Assert.Equal(OpCodes.Ldarg_1.Value, addBody[1]);
- Assert.Equal(OpCodes.Add.Value, addBody[2]);
+ ab.Save(file.Path);
+
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
+ byte[]? multiplyBody = typeFromDisk.GetMethod("MultiplyMethod").GetMethodBody().GetILAsByteArray();
+ byte[]? addBody = typeFromDisk.GetMethod("AddMethod").GetMethodBody().GetILAsByteArray();
+
+ Assert.NotNull(multiplyBody);
+ Assert.Equal(OpCodes.Ldarg_0.Value, multiplyBody[0]);
+ Assert.Equal(OpCodes.Ldc_I4_S.Value, multiplyBody[1]);
+ Assert.Equal(multiplier, multiplyBody[2]);
+ Assert.Equal(OpCodes.Mul.Value, multiplyBody[3]);
+ Assert.NotNull(addBody);
+ Assert.Equal(OpCodes.Ldarg_0.Value, addBody[0]);
+ Assert.Equal(OpCodes.Ldarg_1.Value, addBody[1]);
+ Assert.Equal(OpCodes.Add.Value, addBody[2]);
+ }
}
}
@@ -115,9 +123,9 @@ public void MultipleTypesWithMultipleMethods()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo saveMethod);
- MethodBuilder multiplyMethod = type.DefineMethod("MultiplyMethod", MethodAttributes.Public, typeof(short), new Type[] { typeof(short) });
- MethodBuilder addMethod = type.DefineMethod("AddMethod", MethodAttributes.Public | MethodAttributes.Static, typeof(double), new Type[] { typeof(double) });
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
+ MethodBuilder multiplyMethod = type.DefineMethod("MultiplyMethod", MethodAttributes.Public, typeof(short), [typeof(short)]);
+ MethodBuilder addMethod = type.DefineMethod("AddMethod", MethodAttributes.Public | MethodAttributes.Static, typeof(double), [typeof(double)]);
ILGenerator multiplyMethodIL = multiplyMethod.GetILGenerator();
multiplyMethodIL.Emit(OpCodes.Ldarg, 1);
@@ -145,38 +153,41 @@ public void MultipleTypesWithMultipleMethods()
longMethodIL.Emit(OpCodes.Ldc_I8, (long)1234567);
longMethodIL.Emit(OpCodes.Ret);
anotherType.CreateType();
- saveMethod.Invoke(ab, new object[] { file.Path });
-
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Module moduleFromFile = assemblyFromDisk.Modules.First();
- Type typeFromDisk = moduleFromFile.GetType("MyType");
- Type anotherTypeFromDisk = moduleFromFile.GetType("AnotherType");
- byte[]? multiplyBody = typeFromDisk.GetMethod("MultiplyMethod").GetMethodBody().GetILAsByteArray();
- byte[]? addBody = typeFromDisk.GetMethod("AddMethod").GetMethodBody().GetILAsByteArray();
- byte[]? stringBody = anotherTypeFromDisk.GetMethod("StringMethod", BindingFlags.NonPublic | BindingFlags.Instance).GetMethodBody().GetILAsByteArray();
- byte[]? floatBody = anotherTypeFromDisk.GetMethod("FloatMethod", BindingFlags.NonPublic | BindingFlags.Instance).GetMethodBody().GetILAsByteArray();
- byte[]? longBody = anotherTypeFromDisk.GetMethod("LongMethod", BindingFlags.NonPublic | BindingFlags.Static).GetMethodBody().GetILAsByteArray();
-
- Assert.NotNull(multiplyBody);
- Assert.Equal(OpCodes.Ldarg_1.Value, multiplyBody[0]);
- Assert.Equal(OpCodes.Ldc_I4_S.Value, multiplyBody[1]);
- Assert.Equal(11, multiplyBody[2]);
- Assert.NotNull(addBody);
- Assert.Equal(OpCodes.Ldarg_0.Value, addBody[0]);
- Assert.Equal(OpCodes.Ldc_R8.Value, addBody[1]);
- Assert.NotNull(stringBody);
- Assert.Equal(OpCodes.Ldstr.Value, stringBody[0]);
- Assert.NotNull(floatBody);
- Assert.Equal(OpCodes.Ldc_R4.Value, floatBody[0]);
- Assert.NotNull(longBody);
- Assert.Equal(OpCodes.Ldc_I8.Value, longBody[0]);
+ ab.Save(file.Path);
+
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Module moduleFromFile = assemblyFromDisk.Modules.First();
+ Type typeFromDisk = moduleFromFile.GetType("MyType");
+ Type anotherTypeFromDisk = moduleFromFile.GetType("AnotherType");
+ byte[]? multiplyBody = typeFromDisk.GetMethod("MultiplyMethod").GetMethodBody().GetILAsByteArray();
+ byte[]? addBody = typeFromDisk.GetMethod("AddMethod").GetMethodBody().GetILAsByteArray();
+ byte[]? stringBody = anotherTypeFromDisk.GetMethod("StringMethod", BindingFlags.NonPublic | BindingFlags.Instance).GetMethodBody().GetILAsByteArray();
+ byte[]? floatBody = anotherTypeFromDisk.GetMethod("FloatMethod", BindingFlags.NonPublic | BindingFlags.Instance).GetMethodBody().GetILAsByteArray();
+ byte[]? longBody = anotherTypeFromDisk.GetMethod("LongMethod", BindingFlags.NonPublic | BindingFlags.Static).GetMethodBody().GetILAsByteArray();
+
+ Assert.NotNull(multiplyBody);
+ Assert.Equal(OpCodes.Ldarg_1.Value, multiplyBody[0]);
+ Assert.Equal(OpCodes.Ldc_I4_S.Value, multiplyBody[1]);
+ Assert.Equal(11, multiplyBody[2]);
+ Assert.NotNull(addBody);
+ Assert.Equal(OpCodes.Ldarg_0.Value, addBody[0]);
+ Assert.Equal(OpCodes.Ldc_R8.Value, addBody[1]);
+ Assert.NotNull(stringBody);
+ Assert.Equal(OpCodes.Ldstr.Value, stringBody[0]);
+ Assert.NotNull(floatBody);
+ Assert.Equal(OpCodes.Ldc_R4.Value, floatBody[0]);
+ Assert.NotNull(longBody);
+ Assert.Equal(OpCodes.Ldc_I8.Value, longBody[0]);
+ }
}
}
[Fact]
public void ILOffset_Test()
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo saveMethod);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
MethodBuilder method = type.DefineMethod("Method1", MethodAttributes.Public | MethodAttributes.Static, typeof(Type), Type.EmptyTypes);
ILGenerator ilGenerator = method.GetILGenerator();
@@ -190,8 +201,8 @@ public void ILMaxStack_Test()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo saveMethod);
- MethodBuilder method1 = type.DefineMethod("Method1", MethodAttributes.Public, typeof(long), new[] { typeof(int), typeof(long), typeof(short), typeof(byte) });
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
+ MethodBuilder method1 = type.DefineMethod("Method1", MethodAttributes.Public, typeof(long), [typeof(int), typeof(long), typeof(short), typeof(byte)]);
ILGenerator il1 = method1.GetILGenerator();
// public int Method1(int x, int y, short z, byte r) =>
@@ -217,7 +228,7 @@ public void ILMaxStack_Test()
il1.Emit(OpCodes.Add); // pop 2 push 1 stack size 1
il1.Emit(OpCodes.Ret); // pop 1 stack size 0
- MethodBuilder method2 = type.DefineMethod("Method2", MethodAttributes.Public, typeof(int), new Type[] { typeof(int), typeof(byte) });
+ MethodBuilder method2 = type.DefineMethod("Method2", MethodAttributes.Public, typeof(int), [typeof(int), typeof(byte)]);
ILGenerator il2 = method2.GetILGenerator();
// int Method2(int x, int y) => x + (y + 18);
@@ -228,18 +239,21 @@ public void ILMaxStack_Test()
il2.Emit(OpCodes.Add); // pop 2 push 1 stack size 1
il2.Emit(OpCodes.Ret); // pop 1 stack size 0
type.CreateType();
- saveMethod.Invoke(ab, new object[] { file.Path });
+ ab.Save(file.Path);
MethodInfo getMaxStackMethod = GetMaxStackMethod();
Assert.Equal(9, getMaxStackMethod.Invoke(il1, null));
Assert.Equal(3, getMaxStackMethod.Invoke(il2, null));
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
- MethodBody body1 = typeFromDisk.GetMethod("Method1").GetMethodBody();
- MethodBody body2 = typeFromDisk.GetMethod("Method2").GetMethodBody();
- Assert.Equal(9, body1.MaxStackSize);
- Assert.Equal(8, body2.MaxStackSize); // apparently doesn't write lower than 8
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
+ MethodBody body1 = typeFromDisk.GetMethod("Method1").GetMethodBody();
+ MethodBody body2 = typeFromDisk.GetMethod("Method2").GetMethodBody();
+ Assert.Equal(9, body1.MaxStackSize);
+ Assert.Equal(8, body2.MaxStackSize); // apparently doesn't write lower than 8
+ }
}
}
@@ -261,8 +275,8 @@ public void Label_ConditionalBranching()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo saveMethod);
- MethodBuilder methodBuilder = type.DefineMethod("Method1", MethodAttributes.Public, typeof(int), new[] { typeof(int), typeof(int) });
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
+ MethodBuilder methodBuilder = type.DefineMethod("Method1", MethodAttributes.Public, typeof(int), [typeof(int), typeof(int)]);
ILGenerator il = methodBuilder.GetILGenerator();
Label failed = il.DefineLabel();
Label endOfMethod = il.DefineLabel();
@@ -286,24 +300,27 @@ public void Label_ConditionalBranching()
il.MarkLabel(endOfMethod);
il.Emit(OpCodes.Ret);
type.CreateType();
- saveMethod.Invoke(ab, new object[] { file.Path });
+ ab.Save(file.Path);
MethodInfo getMaxStackMethod = GetMaxStackMethod();
Assert.Equal(2, getMaxStackMethod.Invoke(il, null));
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
- byte[]? bodyBytes = typeFromDisk.GetMethod("Method1").GetMethodBody().GetILAsByteArray();
- Assert.Equal(
- [
- (byte)OpCodes.Ldarg_1.Value, (byte)OpCodes.Ldc_I4_S.Value, 100, 0, 0, 0,
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
+ byte[]? bodyBytes = typeFromDisk.GetMethod("Method1").GetMethodBody().GetILAsByteArray();
+ Assert.Equal(
+ [
+ (byte)OpCodes.Ldarg_1.Value, (byte)OpCodes.Ldc_I4_S.Value, 100, 0, 0, 0,
(byte)OpCodes.Bgt_S.Value, 13,
(byte)OpCodes.Ldarg_2.Value, (byte)OpCodes.Ldc_I4_S.Value, 100, 0, 0, 0,
(byte)OpCodes.Bgt_S.Value, 5,
(byte)OpCodes.Ldarg_1.Value, (byte)OpCodes.Ldarg_2.Value, (byte)OpCodes.Add.Value,
(byte)OpCodes.Br_S.Value, (byte)OpCodes.Break.Value,
(byte)OpCodes.Ldc_I4_M1.Value, (byte)OpCodes.Ret.Value
- ], bodyBytes);
+ ], bodyBytes);
+ }
}
}
@@ -312,8 +329,8 @@ public void Label_SwitchCase()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo saveMethod);
- MethodBuilder methodBuilder = type.DefineMethod("Method1", MethodAttributes.Public, typeof(string), new[] { typeof(int) });
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
+ MethodBuilder methodBuilder = type.DefineMethod("Method1", MethodAttributes.Public, typeof(string), [typeof(int)]);
ILGenerator il = methodBuilder.GetILGenerator();
Label defaultCase = il.DefineLabel();
Label endOfMethod = il.DefineLabel();
@@ -357,18 +374,21 @@ public void Label_SwitchCase()
il.MarkLabel(endOfMethod);
il.Emit(OpCodes.Ret);
type.CreateType();
- saveMethod.Invoke(ab, new object[] { file.Path });
+ ab.Save(file.Path);
MethodInfo getMaxStackMethod = GetMaxStackMethod();
Assert.Equal(1, getMaxStackMethod.Invoke(il, null));
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
- byte[]? bodyBytes = typeFromDisk.GetMethod("Method1").GetMethodBody().GetILAsByteArray();
- Assert.Equal((byte)OpCodes.Ldarg_1.Value, bodyBytes[0]);
- Assert.Equal((byte)OpCodes.Switch.Value, bodyBytes[1]);
- Assert.Equal(5, bodyBytes[2]); // case count
- Assert.Equal(69, bodyBytes.Length);
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
+ byte[]? bodyBytes = typeFromDisk.GetMethod("Method1").GetMethodBody().GetILAsByteArray();
+ Assert.Equal((byte)OpCodes.Ldarg_1.Value, bodyBytes[0]);
+ Assert.Equal((byte)OpCodes.Switch.Value, bodyBytes[1]);
+ Assert.Equal(5, bodyBytes[2]); // case count
+ Assert.Equal(69, bodyBytes.Length);
+ }
}
}
@@ -377,8 +397,8 @@ public void LocalBuilderMultipleLocalsUsage()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo saveMethod);
- MethodBuilder methodBuilder = type.DefineMethod("Method1", MethodAttributes.Public | MethodAttributes.Static, typeof(int), new[] { typeof(int), typeof(string) });
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
+ MethodBuilder methodBuilder = type.DefineMethod("Method1", MethodAttributes.Public | MethodAttributes.Static, typeof(int), [typeof(int), typeof(string)]);
ILGenerator il = methodBuilder.GetILGenerator();
LocalBuilder intLocal = il.DeclareLocal(typeof(int));
LocalBuilder stringLocal = il.DeclareLocal(typeof(string));
@@ -406,50 +426,53 @@ public void LocalBuilderMultipleLocalsUsage()
type.CreateType();
MethodInfo getMaxStackMethod = GetMaxStackMethod();
Assert.Equal(2, getMaxStackMethod.Invoke(il, null));
- saveMethod.Invoke(ab, new object[] { file.Path });
-
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
- MethodBody body = typeFromDisk.GetMethod("Method1").GetMethodBody();
- Assert.Equal(4, body.LocalVariables.Count);
- Assert.Equal(intLocal.LocalIndex, body.LocalVariables[0].LocalIndex);
- Assert.Equal(intLocal.LocalType.FullName, body.LocalVariables[0].LocalType.FullName);
- Assert.Equal(intLocal.IsPinned, body.LocalVariables[0].IsPinned);
- Assert.Equal(stringLocal.LocalIndex, body.LocalVariables[1].LocalIndex);
- Assert.Equal(stringLocal.LocalType.FullName, body.LocalVariables[1].LocalType.FullName);
- Assert.Equal(stringLocal.IsPinned, body.LocalVariables[1].IsPinned);
- Assert.Equal(shortLocal.LocalIndex, body.LocalVariables[2].LocalIndex);
- Assert.Equal(shortLocal.LocalType.FullName, body.LocalVariables[2].LocalType.FullName);
- Assert.Equal(shortLocal.IsPinned, body.LocalVariables[2].IsPinned);
- Assert.Equal(int2Local.LocalIndex, body.LocalVariables[3].LocalIndex);
- Assert.Equal(int2Local.LocalType.FullName, body.LocalVariables[3].LocalType.FullName);
- Assert.Equal(int2Local.IsPinned, body.LocalVariables[3].IsPinned);
- byte[]? bodyBytes = body.GetILAsByteArray();
- Assert.Equal((byte)OpCodes.Ldarg_1.Value, bodyBytes[0]);
- Assert.Equal((byte)OpCodes.Stloc_1.Value, bodyBytes[1]);
- Assert.Equal((byte)OpCodes.Ldstr.Value, bodyBytes[2]);
- Assert.Equal((byte)OpCodes.Stloc_1.Value, bodyBytes[7]);
- Assert.Equal((byte)OpCodes.Ldloc_1.Value, bodyBytes[8]);
- Assert.Equal((byte)OpCodes.Starg_S.Value, bodyBytes[9]);
- Assert.Equal((byte)OpCodes.Ldarg_0.Value, bodyBytes[11]);
- Assert.Equal((byte)OpCodes.Stloc_0.Value, bodyBytes[12]);
- Assert.Equal((byte)OpCodes.Ldc_I4_S.Value, bodyBytes[13]);
- Assert.Equal(120, BinaryPrimitives.ReadInt32LittleEndian(bodyBytes.AsSpan().Slice(14, 4)));
- Assert.Equal(0xFE, bodyBytes[18]); // Stloc instruction occupies 2 bytes 0xfe0e
- Assert.Equal(0x0E, bodyBytes[19]);
- Assert.Equal(2, BinaryPrimitives.ReadInt32LittleEndian(bodyBytes.AsSpan().Slice(20, 4))); // index 2 of 'il.Emit(OpCodes.Stloc, 2);' instruction
- Assert.Equal((byte)OpCodes.Ldloc_2.Value, bodyBytes[24]);
- Assert.Equal(0xFE, bodyBytes[25]); // Ldloc = 0xfe0c
- Assert.Equal(0x0C, bodyBytes[26]);
- Assert.Equal(0, BinaryPrimitives.ReadInt32LittleEndian(bodyBytes.AsSpan().Slice(27, 4))); // index 0 of 'il.Emit(OpCodes.Ldloc, 0);' instruction
- Assert.Equal((byte)OpCodes.Add.Value, bodyBytes[31]);
- Assert.Equal((byte)OpCodes.Stloc_0.Value, bodyBytes[32]);
- Assert.Equal((byte)OpCodes.Ldloca_S.Value, bodyBytes[33]);
- Assert.Equal(0, bodyBytes[34]); // intLocal index is 0 for 'il.Emit(OpCodes.Ldloca, intLocal);' instruction
- Assert.Equal((byte)OpCodes.Ldind_I.Value, bodyBytes[35]);
- Assert.Equal((byte)OpCodes.Stloc_3.Value, bodyBytes[36]);
- Assert.Equal((byte)OpCodes.Ldloc_3.Value, bodyBytes[37]);
- Assert.Equal(OpCodes.Ret.Value, bodyBytes[38]);
+ ab.Save(file.Path);
+
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
+ MethodBody body = typeFromDisk.GetMethod("Method1").GetMethodBody();
+ Assert.Equal(4, body.LocalVariables.Count);
+ Assert.Equal(intLocal.LocalIndex, body.LocalVariables[0].LocalIndex);
+ Assert.Equal(intLocal.LocalType.FullName, body.LocalVariables[0].LocalType.FullName);
+ Assert.Equal(intLocal.IsPinned, body.LocalVariables[0].IsPinned);
+ Assert.Equal(stringLocal.LocalIndex, body.LocalVariables[1].LocalIndex);
+ Assert.Equal(stringLocal.LocalType.FullName, body.LocalVariables[1].LocalType.FullName);
+ Assert.Equal(stringLocal.IsPinned, body.LocalVariables[1].IsPinned);
+ Assert.Equal(shortLocal.LocalIndex, body.LocalVariables[2].LocalIndex);
+ Assert.Equal(shortLocal.LocalType.FullName, body.LocalVariables[2].LocalType.FullName);
+ Assert.Equal(shortLocal.IsPinned, body.LocalVariables[2].IsPinned);
+ Assert.Equal(int2Local.LocalIndex, body.LocalVariables[3].LocalIndex);
+ Assert.Equal(int2Local.LocalType.FullName, body.LocalVariables[3].LocalType.FullName);
+ Assert.Equal(int2Local.IsPinned, body.LocalVariables[3].IsPinned);
+ byte[]? bodyBytes = body.GetILAsByteArray();
+ Assert.Equal((byte)OpCodes.Ldarg_1.Value, bodyBytes[0]);
+ Assert.Equal((byte)OpCodes.Stloc_1.Value, bodyBytes[1]);
+ Assert.Equal((byte)OpCodes.Ldstr.Value, bodyBytes[2]);
+ Assert.Equal((byte)OpCodes.Stloc_1.Value, bodyBytes[7]);
+ Assert.Equal((byte)OpCodes.Ldloc_1.Value, bodyBytes[8]);
+ Assert.Equal((byte)OpCodes.Starg_S.Value, bodyBytes[9]);
+ Assert.Equal((byte)OpCodes.Ldarg_0.Value, bodyBytes[11]);
+ Assert.Equal((byte)OpCodes.Stloc_0.Value, bodyBytes[12]);
+ Assert.Equal((byte)OpCodes.Ldc_I4_S.Value, bodyBytes[13]);
+ Assert.Equal(120, BinaryPrimitives.ReadInt32LittleEndian(bodyBytes.AsSpan().Slice(14, 4)));
+ Assert.Equal(0xFE, bodyBytes[18]); // Stloc instruction occupies 2 bytes 0xfe0e
+ Assert.Equal(0x0E, bodyBytes[19]);
+ Assert.Equal(2, BinaryPrimitives.ReadInt32LittleEndian(bodyBytes.AsSpan().Slice(20, 4))); // index 2 of 'il.Emit(OpCodes.Stloc, 2);' instruction
+ Assert.Equal((byte)OpCodes.Ldloc_2.Value, bodyBytes[24]);
+ Assert.Equal(0xFE, bodyBytes[25]); // Ldloc = 0xfe0c
+ Assert.Equal(0x0C, bodyBytes[26]);
+ Assert.Equal(0, BinaryPrimitives.ReadInt32LittleEndian(bodyBytes.AsSpan().Slice(27, 4))); // index 0 of 'il.Emit(OpCodes.Ldloc, 0);' instruction
+ Assert.Equal((byte)OpCodes.Add.Value, bodyBytes[31]);
+ Assert.Equal((byte)OpCodes.Stloc_0.Value, bodyBytes[32]);
+ Assert.Equal((byte)OpCodes.Ldloca_S.Value, bodyBytes[33]);
+ Assert.Equal(0, bodyBytes[34]); // intLocal index is 0 for 'il.Emit(OpCodes.Ldloca, intLocal);' instruction
+ Assert.Equal((byte)OpCodes.Ldind_I.Value, bodyBytes[35]);
+ Assert.Equal((byte)OpCodes.Stloc_3.Value, bodyBytes[36]);
+ Assert.Equal((byte)OpCodes.Ldloc_3.Value, bodyBytes[37]);
+ Assert.Equal(OpCodes.Ret.Value, bodyBytes[38]);
+ }
}
}
@@ -458,8 +481,8 @@ public void LocalBuilderMultipleTypesWithMultipleMethodsWithLocals()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo saveMethod);
- MethodBuilder methodBuilder = type.DefineMethod("Method1", MethodAttributes.Public | MethodAttributes.Static, typeof(string), new[] { typeof(int), typeof(string) });
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
+ MethodBuilder methodBuilder = type.DefineMethod("Method1", MethodAttributes.Public | MethodAttributes.Static, typeof(string), [typeof(int), typeof(string)]);
ILGenerator il = methodBuilder.GetILGenerator();
LocalBuilder intLocal = il.DeclareLocal(typeof(int));
LocalBuilder stringLocal = il.DeclareLocal(typeof(string));
@@ -478,7 +501,7 @@ public void LocalBuilderMultipleTypesWithMultipleMethodsWithLocals()
il.Emit(OpCodes.Stloc, intLocal);
il.Emit(OpCodes.Ldloc, stringLocal);
il.Emit(OpCodes.Ret);
- MethodBuilder multiplyMethod = type.DefineMethod("MultiplyMethod", MethodAttributes.Public, typeof(int), new[] { typeof(int) });
+ MethodBuilder multiplyMethod = type.DefineMethod("MultiplyMethod", MethodAttributes.Public, typeof(int), [typeof(int)]);
ILGenerator multiplyMethodIL = multiplyMethod.GetILGenerator();
LocalBuilder iLocal = multiplyMethodIL.DeclareLocal(typeof(int));
LocalBuilder shLocal = multiplyMethodIL.DeclareLocal(typeof(short));
@@ -526,24 +549,27 @@ public void LocalBuilderMultipleTypesWithMultipleMethodsWithLocals()
longMethodIL.Emit(OpCodes.Ldloc, longLocal);
longMethodIL.Emit(OpCodes.Ret);
anotherType.CreateType();
- saveMethod.Invoke(ab, new object[] { file.Path });
-
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Module moduleFromFile = assemblyFromDisk.Modules.First();
- Type typeFromDisk = moduleFromFile.GetType("MyType");
- Assert.Equal(2, typeFromDisk.GetMethod("MultiplyMethod").GetMethodBody().LocalVariables.Count);
- Assert.Equal(3, typeFromDisk.GetMethod("Method1").GetMethodBody().LocalVariables.Count);
- Type anotherTypeFromDisk = moduleFromFile.GetType("AnotherType");
- Assert.Equal(1, anotherTypeFromDisk.GetMethod("StringMethod", BindingFlags.NonPublic | BindingFlags.Instance).GetMethodBody().LocalVariables.Count);
- Assert.Equal(2, anotherTypeFromDisk.GetMethod("TypeMethod", BindingFlags.NonPublic | BindingFlags.Instance).GetMethodBody().LocalVariables.Count);
- Assert.Equal(2, anotherTypeFromDisk.GetMethod("LongMethod", BindingFlags.NonPublic | BindingFlags.Static).GetMethodBody().LocalVariables.Count);
+ ab.Save(file.Path);
+
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Module moduleFromFile = assemblyFromDisk.Modules.First();
+ Type typeFromDisk = moduleFromFile.GetType("MyType");
+ Assert.Equal(2, typeFromDisk.GetMethod("MultiplyMethod").GetMethodBody().LocalVariables.Count);
+ Assert.Equal(3, typeFromDisk.GetMethod("Method1").GetMethodBody().LocalVariables.Count);
+ Type anotherTypeFromDisk = moduleFromFile.GetType("AnotherType");
+ Assert.Equal(1, anotherTypeFromDisk.GetMethod("StringMethod", BindingFlags.NonPublic | BindingFlags.Instance).GetMethodBody().LocalVariables.Count);
+ Assert.Equal(2, anotherTypeFromDisk.GetMethod("TypeMethod", BindingFlags.NonPublic | BindingFlags.Instance).GetMethodBody().LocalVariables.Count);
+ Assert.Equal(2, anotherTypeFromDisk.GetMethod("LongMethod", BindingFlags.NonPublic | BindingFlags.Static).GetMethodBody().LocalVariables.Count);
+ }
}
}
[Fact]
public void LocalBuilderExceptions()
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo saveMethod);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
ILGenerator il = type.DefineMethod("Method1", MethodAttributes.Public).GetILGenerator();
ILGenerator anotherIL = type.DefineMethod("AnotherMethod", MethodAttributes.Public).GetILGenerator();
LocalBuilder stringLocal = il.DeclareLocal(typeof(string));
@@ -559,8 +585,8 @@ public void ReferenceFieldInIL()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder tb, out MethodInfo saveMethod);
- MethodBuilder methodBuilder = tb.DefineMethod("Method1", MethodAttributes.Public, typeof(int), new[] { typeof(int) });
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder tb);
+ MethodBuilder methodBuilder = tb.DefineMethod("Method1", MethodAttributes.Public, typeof(int), [typeof(int)]);
FieldBuilder fbNumber = tb.DefineField("_number", typeof(int), FieldAttributes.Private);
Assert.Equal(0, fbNumber.MetadataToken);
@@ -571,19 +597,22 @@ public void ReferenceFieldInIL()
il.Emit(OpCodes.Mul);
il.Emit(OpCodes.Ret);
tb.CreateType();
- saveMethod.Invoke(ab, new object[] { file.Path });
-
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
- byte[]? bodyBytes = typeFromDisk.GetMethod("Method1").GetMethodBody().GetILAsByteArray();
- Assert.Equal(9, bodyBytes.Length);
- Assert.NotEqual(0, fbNumber.MetadataToken);
- Assert.Equal(OpCodes.Ldarg_0.Value, bodyBytes[0]);
- Assert.Equal(OpCodes.Ldfld.Value, bodyBytes[1]);
- Assert.Equal(fbNumber.MetadataToken, BinaryPrimitives.ReadInt32LittleEndian(bodyBytes.AsSpan().Slice(2, 4)));
- Assert.Equal(OpCodes.Ldarg_1.Value, bodyBytes[6]);
- Assert.Equal(OpCodes.Mul.Value, bodyBytes[7]);
- Assert.Equal(OpCodes.Ret.Value, bodyBytes[8]);
+ ab.Save(file.Path);
+
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
+ byte[]? bodyBytes = typeFromDisk.GetMethod("Method1").GetMethodBody().GetILAsByteArray();
+ Assert.Equal(9, bodyBytes.Length);
+ Assert.NotEqual(0, fbNumber.MetadataToken);
+ Assert.Equal(OpCodes.Ldarg_0.Value, bodyBytes[0]);
+ Assert.Equal(OpCodes.Ldfld.Value, bodyBytes[1]);
+ Assert.Equal(fbNumber.MetadataToken, BinaryPrimitives.ReadInt32LittleEndian(bodyBytes.AsSpan().Slice(2, 4)));
+ Assert.Equal(OpCodes.Ldarg_1.Value, bodyBytes[6]);
+ Assert.Equal(OpCodes.Mul.Value, bodyBytes[7]);
+ Assert.Equal(OpCodes.Ret.Value, bodyBytes[8]);
+ }
}
}
@@ -592,12 +621,12 @@ public void ReferenceFieldAndMethodsInIL()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder tb, out MethodInfo saveMethod);
- MethodBuilder methodMain = tb.DefineMethod("Main", MethodAttributes.Public, typeof(void), new[] { typeof(int) });
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder tb);
+ MethodBuilder methodMain = tb.DefineMethod("Main", MethodAttributes.Public, typeof(void), [typeof(int)]);
FieldBuilder field = tb.DefineField("_field", typeof(int), FieldAttributes.Private);
- MethodInfo writeLineString = typeof(Console).GetMethod("WriteLine", new[] { typeof(string) });
- MethodInfo writeLineObj = typeof(Console).GetMethod("WriteLine", new[] { typeof(string), typeof(object), typeof(object), typeof(object) });
- MethodBuilder methodMultiply = tb.DefineMethod("Multiply", MethodAttributes.Public, typeof(int), new[] { typeof(int) });
+ MethodInfo writeLineString = typeof(Console).GetMethod("WriteLine", [typeof(string)]);
+ MethodInfo writeLineObj = typeof(Console).GetMethod("WriteLine", [typeof(string), typeof(object), typeof(object), typeof(object)]);
+ MethodBuilder methodMultiply = tb.DefineMethod("Multiply", MethodAttributes.Public, typeof(int), [typeof(int)]);
/*
class MyType
{
@@ -633,32 +662,35 @@ void Main(int a)
ilMain.Emit(OpCodes.Call, writeLineObj);
ilMain.Emit(OpCodes.Ret);
tb.CreateType();
- saveMethod.Invoke(ab, new object[] { file.Path });
-
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
- byte[]? bodyBytes = typeFromDisk.GetMethod("Main").GetMethodBody().GetILAsByteArray();
- Assert.Equal(OpCodes.Ldstr.Value, bodyBytes[0]);
- Assert.Equal(OpCodes.Call.Value, bodyBytes[5]);
- // Bytes 6, 7, 8, 9 are token for writeLineString, but it is not same as the value before save
- Assert.Equal(OpCodes.Ldstr.Value, bodyBytes[10]);
- Assert.Equal(OpCodes.Ldarg_0.Value, bodyBytes[15]);
- Assert.Equal(OpCodes.Ldfld.Value, bodyBytes[16]);
- Assert.Equal(field.MetadataToken, BinaryPrimitives.ReadInt32LittleEndian(bodyBytes.AsSpan().Slice(17, 4)));
- Assert.Equal(OpCodes.Box.Value, bodyBytes[21]);
- int intTypeToken = BinaryPrimitives.ReadInt32LittleEndian(bodyBytes.AsSpan().Slice(22, 4));
- Assert.Equal(OpCodes.Ldarg_1.Value, bodyBytes[26]);
- Assert.Equal(OpCodes.Box.Value, bodyBytes[27]);
- Assert.Equal(intTypeToken, BinaryPrimitives.ReadInt32LittleEndian(bodyBytes.AsSpan().Slice(28, 4)));
- Assert.Equal(OpCodes.Ldarg_0.Value, bodyBytes[32]);
- Assert.Equal(OpCodes.Ldarg_1.Value, bodyBytes[33]);
- Assert.Equal(OpCodes.Call.Value, bodyBytes[34]);
- Assert.Equal(methodMultiply.MetadataToken, BinaryPrimitives.ReadInt32LittleEndian(bodyBytes.AsSpan().Slice(35, 4)));
- Assert.Equal(OpCodes.Box.Value, bodyBytes[39]);
- Assert.Equal(intTypeToken, BinaryPrimitives.ReadInt32LittleEndian(bodyBytes.AsSpan().Slice(40, 4)));
- Assert.Equal(OpCodes.Call.Value, bodyBytes[44]);
- // Bytes 24, 46, 47, 48 are token for writeLineObj, but it is not same as the value before save
- Assert.Equal(OpCodes.Ret.Value, bodyBytes[49]);
+ ab.Save(file.Path);
+
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
+ byte[]? bodyBytes = typeFromDisk.GetMethod("Main").GetMethodBody().GetILAsByteArray();
+ Assert.Equal(OpCodes.Ldstr.Value, bodyBytes[0]);
+ Assert.Equal(OpCodes.Call.Value, bodyBytes[5]);
+ // Bytes 6, 7, 8, 9 are token for writeLineString, but it is not same as the value before save
+ Assert.Equal(OpCodes.Ldstr.Value, bodyBytes[10]);
+ Assert.Equal(OpCodes.Ldarg_0.Value, bodyBytes[15]);
+ Assert.Equal(OpCodes.Ldfld.Value, bodyBytes[16]);
+ Assert.Equal(field.MetadataToken, BinaryPrimitives.ReadInt32LittleEndian(bodyBytes.AsSpan().Slice(17, 4)));
+ Assert.Equal(OpCodes.Box.Value, bodyBytes[21]);
+ int intTypeToken = BinaryPrimitives.ReadInt32LittleEndian(bodyBytes.AsSpan().Slice(22, 4));
+ Assert.Equal(OpCodes.Ldarg_1.Value, bodyBytes[26]);
+ Assert.Equal(OpCodes.Box.Value, bodyBytes[27]);
+ Assert.Equal(intTypeToken, BinaryPrimitives.ReadInt32LittleEndian(bodyBytes.AsSpan().Slice(28, 4)));
+ Assert.Equal(OpCodes.Ldarg_0.Value, bodyBytes[32]);
+ Assert.Equal(OpCodes.Ldarg_1.Value, bodyBytes[33]);
+ Assert.Equal(OpCodes.Call.Value, bodyBytes[34]);
+ Assert.Equal(methodMultiply.MetadataToken, BinaryPrimitives.ReadInt32LittleEndian(bodyBytes.AsSpan().Slice(35, 4)));
+ Assert.Equal(OpCodes.Box.Value, bodyBytes[39]);
+ Assert.Equal(intTypeToken, BinaryPrimitives.ReadInt32LittleEndian(bodyBytes.AsSpan().Slice(40, 4)));
+ Assert.Equal(OpCodes.Call.Value, bodyBytes[44]);
+ // Bytes 24, 46, 47, 48 are token for writeLineObj, but it is not same as the value before save
+ Assert.Equal(OpCodes.Ret.Value, bodyBytes[49]);
+ }
}
}
@@ -667,13 +699,13 @@ public void ReferenceConstructedGenericMethod()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo saveMethod);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
ConstructorBuilder ctor = type.DefineDefaultConstructor(MethodAttributes.Public);
MethodBuilder genericMethod = type.DefineMethod("GM", MethodAttributes.Public | MethodAttributes.Static);
GenericTypeParameterBuilder[] methodParams = genericMethod.DefineGenericParameters("U");
genericMethod.SetSignature(null, null, null, new[] { methodParams[0] }, null, null);
ILGenerator ilg = genericMethod.GetILGenerator();
- MethodInfo writeLineObj = typeof(Console).GetMethod("WriteLine", new[] { typeof(object) });
+ MethodInfo writeLineObj = typeof(Console).GetMethod("WriteLine", [typeof(object)]);
ilg.Emit(OpCodes.Ldarg_0);
ilg.EmitCall(OpCodes.Call, writeLineObj, null);
ilg.Emit(OpCodes.Ret);
@@ -684,17 +716,20 @@ public void ReferenceConstructedGenericMethod()
ilg.EmitCall(OpCodes.Call, GMOfString, null);
ilg.Emit(OpCodes.Ret);
type.CreateType();
- saveMethod.Invoke(ab, new[] { file.Path });
-
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
- MethodInfo genericMethodFromDisk = typeFromDisk.GetMethod("GM");
- Assert.True(genericMethodFromDisk.IsGenericMethod);
- Assert.True(genericMethodFromDisk.IsGenericMethodDefinition);
- byte[] ilBytes = typeFromDisk.GetMethod("Main").GetMethodBody().GetILAsByteArray();
- Assert.Equal(OpCodes.Ldstr.Value, ilBytes[0]);
- Assert.Equal(OpCodes.Call.Value, ilBytes[5]);
- Assert.Equal(OpCodes.Ret.Value, ilBytes[10]);
+ ab.Save(file.Path);
+
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
+ MethodInfo genericMethodFromDisk = typeFromDisk.GetMethod("GM");
+ Assert.True(genericMethodFromDisk.IsGenericMethod);
+ Assert.True(genericMethodFromDisk.IsGenericMethodDefinition);
+ byte[] ilBytes = typeFromDisk.GetMethod("Main").GetMethodBody().GetILAsByteArray();
+ Assert.Equal(OpCodes.Ldstr.Value, ilBytes[0]);
+ Assert.Equal(OpCodes.Call.Value, ilBytes[5]);
+ Assert.Equal(OpCodes.Ret.Value, ilBytes[10]);
+ }
}
}
@@ -703,8 +738,8 @@ public void ReferenceConstructedGenericMethodFieldOfConstructedType()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo saveMethod);
- GenericTypeParameterBuilder[] typeParams = type.DefineGenericParameters(new[] { "T" });
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
+ GenericTypeParameterBuilder[] typeParams = type.DefineGenericParameters(["T"]);
ConstructorBuilder ctor = type.DefineDefaultConstructor(MethodAttributes.PrivateScope | MethodAttributes.Public |
MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);
FieldBuilder myField = type.DefineField("Field", typeParams[0], FieldAttributes.Public);
@@ -724,7 +759,7 @@ public void ReferenceConstructedGenericMethodFieldOfConstructedType()
ilg.Emit(OpCodes.Ldloc_0);
ilg.Emit(OpCodes.Ldfld, FieldOfU);
ilg.Emit(OpCodes.Box, methodParams[0]);
- MethodInfo writeLineObj = typeof(Console).GetMethod("WriteLine", new[] { typeof(object) });
+ MethodInfo writeLineObj = typeof(Console).GetMethod("WriteLine", [typeof(object)]);
ilg.EmitCall(OpCodes.Call, writeLineObj, null);
ilg.Emit(OpCodes.Ret);
type.CreateType();
@@ -758,34 +793,38 @@ public static void Main()
MyType.GM("HelloWorld");
}
} */
- saveMethod.Invoke(ab, new[] { file.Path });
-
- Module module = AssemblySaveTools.LoadAssemblyFromPath(file.Path).Modules.First();
- Type myTypeFromDisk = module.GetType("MyType");
- Assert.True(myTypeFromDisk.IsGenericType);
- Assert.True(myTypeFromDisk.IsGenericTypeDefinition);
- Assert.Equal("T", myTypeFromDisk.GetGenericArguments()[0].Name);
- Assert.Equal("T", myTypeFromDisk.GetField("Field").FieldType.Name);
- MethodInfo genericMethodFromDisk = myTypeFromDisk.GetMethod("GM");
- Assert.True(genericMethodFromDisk.IsGenericMethod);
- Assert.True(genericMethodFromDisk.IsGenericMethodDefinition);
- Assert.Equal(1, genericMethodFromDisk.GetMethodBody().LocalVariables.Count);
- Assert.Equal("MyType[U]", genericMethodFromDisk.GetMethodBody().LocalVariables[0].LocalType.ToString());
- byte[] gmIlBytes = genericMethodFromDisk.GetMethodBody().GetILAsByteArray();
- Assert.Equal(OpCodes.Newobj.Value, gmIlBytes[0]);
- Assert.Equal(OpCodes.Stloc_0.Value, gmIlBytes[5]);
- Assert.Equal(OpCodes.Ldloc_0.Value, gmIlBytes[6]);
- Assert.Equal(OpCodes.Ldarg_0.Value, gmIlBytes[7]);
- Assert.Equal(OpCodes.Stfld.Value, gmIlBytes[8]);
- Assert.Equal(OpCodes.Ldloc_0.Value, gmIlBytes[13]);
- Assert.Equal(OpCodes.Ldfld.Value, gmIlBytes[14]);
- Assert.Equal(OpCodes.Box.Value, gmIlBytes[19]);
- Assert.Equal(OpCodes.Call.Value, gmIlBytes[24]);
- Assert.Equal(OpCodes.Ret.Value, gmIlBytes[29]);
- byte[] ilBytes = module.GetType("Dummy").GetMethod("Main").GetMethodBody().GetILAsByteArray();
- Assert.Equal(OpCodes.Ldstr.Value, ilBytes[0]);
- Assert.Equal(OpCodes.Call.Value, ilBytes[5]);
- Assert.Equal(OpCodes.Ret.Value, ilBytes[10]);
+ ab.Save(file.Path);
+
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Module module = assemblyFromDisk.Modules.First();
+ Type myTypeFromDisk = module.GetType("MyType");
+ Assert.True(myTypeFromDisk.IsGenericType);
+ Assert.True(myTypeFromDisk.IsGenericTypeDefinition);
+ Assert.Equal("T", myTypeFromDisk.GetGenericArguments()[0].Name);
+ Assert.Equal("T", myTypeFromDisk.GetField("Field").FieldType.Name);
+ MethodInfo genericMethodFromDisk = myTypeFromDisk.GetMethod("GM");
+ Assert.True(genericMethodFromDisk.IsGenericMethod);
+ Assert.True(genericMethodFromDisk.IsGenericMethodDefinition);
+ Assert.Equal(1, genericMethodFromDisk.GetMethodBody().LocalVariables.Count);
+ Assert.Equal("MyType[U]", genericMethodFromDisk.GetMethodBody().LocalVariables[0].LocalType.ToString());
+ byte[] gmIlBytes = genericMethodFromDisk.GetMethodBody().GetILAsByteArray();
+ Assert.Equal(OpCodes.Newobj.Value, gmIlBytes[0]);
+ Assert.Equal(OpCodes.Stloc_0.Value, gmIlBytes[5]);
+ Assert.Equal(OpCodes.Ldloc_0.Value, gmIlBytes[6]);
+ Assert.Equal(OpCodes.Ldarg_0.Value, gmIlBytes[7]);
+ Assert.Equal(OpCodes.Stfld.Value, gmIlBytes[8]);
+ Assert.Equal(OpCodes.Ldloc_0.Value, gmIlBytes[13]);
+ Assert.Equal(OpCodes.Ldfld.Value, gmIlBytes[14]);
+ Assert.Equal(OpCodes.Box.Value, gmIlBytes[19]);
+ Assert.Equal(OpCodes.Call.Value, gmIlBytes[24]);
+ Assert.Equal(OpCodes.Ret.Value, gmIlBytes[29]);
+ byte[] ilBytes = module.GetType("Dummy").GetMethod("Main").GetMethodBody().GetILAsByteArray();
+ Assert.Equal(OpCodes.Ldstr.Value, ilBytes[0]);
+ Assert.Equal(OpCodes.Call.Value, ilBytes[5]);
+ Assert.Equal(OpCodes.Ret.Value, ilBytes[10]);
+ }
}
}
@@ -794,7 +833,7 @@ public void EmitWriteLineMacroTest()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type1, out MethodInfo saveMethod);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type1);
MethodBuilder method = type1.DefineMethod("meth", MethodAttributes.Public, typeof(int), Type.EmptyTypes);
FieldBuilder field = type1.DefineField("field", typeof(int), FieldAttributes.Public | FieldAttributes.Static);
ILGenerator ilGenerator = method.GetILGenerator();
@@ -809,28 +848,31 @@ public void EmitWriteLineMacroTest()
ilGenerator.Emit(OpCodes.Ldsfld, field);
ilGenerator.Emit(OpCodes.Ret);
type1.CreateType();
- saveMethod.Invoke(ab, new object[] { file.Path });
-
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
- byte[]? bodyBytes = typeFromDisk.GetMethod("meth").GetMethodBody().GetILAsByteArray();
- Assert.Equal(OpCodes.Ldc_I4_1.Value, bodyBytes[0]);
- Assert.Equal(OpCodes.Stloc_0.Value, bodyBytes[1]);
- Assert.Equal(OpCodes.Ldloc_0.Value, bodyBytes[2]);
- Assert.Equal(OpCodes.Stsfld.Value, bodyBytes[3]);
- Assert.Equal(field.MetadataToken, BinaryPrimitives.ReadInt32LittleEndian(bodyBytes.AsSpan().Slice(4, 4)));
- Assert.Equal(OpCodes.Call.Value, bodyBytes[8]);
- Assert.Equal(OpCodes.Ldsfld.Value, bodyBytes[13]);
- Assert.Equal(field.MetadataToken, BinaryPrimitives.ReadInt32LittleEndian(bodyBytes.AsSpan().Slice(14, 4)));
- Assert.Equal(OpCodes.Callvirt.Value, bodyBytes[18]);
- Assert.Equal(OpCodes.Ldstr.Value, bodyBytes[23]);
- Assert.Equal(OpCodes.Call.Value, bodyBytes[28]);
- Assert.Equal(OpCodes.Call.Value, bodyBytes[33]);
- Assert.Equal(OpCodes.Ldloc_0.Value, bodyBytes[38]);
- Assert.Equal(OpCodes.Callvirt.Value, bodyBytes[39]);
- Assert.Equal(OpCodes.Ldsfld.Value, bodyBytes[44]);
- Assert.Equal(field.MetadataToken, BinaryPrimitives.ReadInt32LittleEndian(bodyBytes.AsSpan().Slice(45, 4)));
- Assert.Equal(OpCodes.Ret.Value, bodyBytes[49]);
+ ab.Save(file.Path);
+
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
+ byte[]? bodyBytes = typeFromDisk.GetMethod("meth").GetMethodBody().GetILAsByteArray();
+ Assert.Equal(OpCodes.Ldc_I4_1.Value, bodyBytes[0]);
+ Assert.Equal(OpCodes.Stloc_0.Value, bodyBytes[1]);
+ Assert.Equal(OpCodes.Ldloc_0.Value, bodyBytes[2]);
+ Assert.Equal(OpCodes.Stsfld.Value, bodyBytes[3]);
+ Assert.Equal(field.MetadataToken, BinaryPrimitives.ReadInt32LittleEndian(bodyBytes.AsSpan().Slice(4, 4)));
+ Assert.Equal(OpCodes.Call.Value, bodyBytes[8]);
+ Assert.Equal(OpCodes.Ldsfld.Value, bodyBytes[13]);
+ Assert.Equal(field.MetadataToken, BinaryPrimitives.ReadInt32LittleEndian(bodyBytes.AsSpan().Slice(14, 4)));
+ Assert.Equal(OpCodes.Callvirt.Value, bodyBytes[18]);
+ Assert.Equal(OpCodes.Ldstr.Value, bodyBytes[23]);
+ Assert.Equal(OpCodes.Call.Value, bodyBytes[28]);
+ Assert.Equal(OpCodes.Call.Value, bodyBytes[33]);
+ Assert.Equal(OpCodes.Ldloc_0.Value, bodyBytes[38]);
+ Assert.Equal(OpCodes.Callvirt.Value, bodyBytes[39]);
+ Assert.Equal(OpCodes.Ldsfld.Value, bodyBytes[44]);
+ Assert.Equal(field.MetadataToken, BinaryPrimitives.ReadInt32LittleEndian(bodyBytes.AsSpan().Slice(45, 4)));
+ Assert.Equal(OpCodes.Ret.Value, bodyBytes[49]);
+ }
}
}
@@ -839,8 +881,8 @@ public void ReferenceStaticFieldAndMethodsInIL()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder tb, out MethodInfo saveMethod);
- MethodBuilder methodMain = tb.DefineMethod("Main", MethodAttributes.Public, typeof(int), new[] { typeof(int) });
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder tb);
+ MethodBuilder methodMain = tb.DefineMethod("Main", MethodAttributes.Public, typeof(int), [typeof(int)]);
TypeBuilder anotherType = ab.GetDynamicModule("MyModule").DefineType("AnotherType", TypeAttributes.Public);
FieldBuilder field = anotherType.DefineField("StaticField", typeof(int), FieldAttributes.Public | FieldAttributes.Static);
MethodBuilder staticMethod = anotherType.DefineMethod("StaticMethod", MethodAttributes.Public | MethodAttributes.Static, typeof(void), Type.EmptyTypes);
@@ -868,19 +910,22 @@ void static StaticMethod() { }
il.Emit(OpCodes.Ret);
tb.CreateType();
anotherType.CreateType();
- saveMethod.Invoke(ab, new object[] { file.Path });
-
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
- byte[]? bodyBytes = typeFromDisk.GetMethod("Main").GetMethodBody().GetILAsByteArray();
- Assert.Equal(OpCodes.Call.Value, bodyBytes[0]);
- Assert.Equal(staticMethod.MetadataToken, BinaryPrimitives.ReadInt32LittleEndian(bodyBytes.AsSpan().Slice(1, 4)));
- Assert.Equal(OpCodes.Ldarg_1.Value, bodyBytes[5]);
- Assert.Equal(OpCodes.Stsfld.Value, bodyBytes[6]);
- Assert.Equal(field.MetadataToken, BinaryPrimitives.ReadInt32LittleEndian(bodyBytes.AsSpan().Slice(7, 4)));
- Assert.Equal(OpCodes.Ldsfld.Value, bodyBytes[11]);
- Assert.Equal(field.MetadataToken, BinaryPrimitives.ReadInt32LittleEndian(bodyBytes.AsSpan().Slice(12, 4)));
- Assert.Equal(OpCodes.Ret.Value, bodyBytes[16]);
+ ab.Save(file.Path);
+
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
+ byte[]? bodyBytes = typeFromDisk.GetMethod("Main").GetMethodBody().GetILAsByteArray();
+ Assert.Equal(OpCodes.Call.Value, bodyBytes[0]);
+ Assert.Equal(staticMethod.MetadataToken, BinaryPrimitives.ReadInt32LittleEndian(bodyBytes.AsSpan().Slice(1, 4)));
+ Assert.Equal(OpCodes.Ldarg_1.Value, bodyBytes[5]);
+ Assert.Equal(OpCodes.Stsfld.Value, bodyBytes[6]);
+ Assert.Equal(field.MetadataToken, BinaryPrimitives.ReadInt32LittleEndian(bodyBytes.AsSpan().Slice(7, 4)));
+ Assert.Equal(OpCodes.Ldsfld.Value, bodyBytes[11]);
+ Assert.Equal(field.MetadataToken, BinaryPrimitives.ReadInt32LittleEndian(bodyBytes.AsSpan().Slice(12, 4)));
+ Assert.Equal(OpCodes.Ret.Value, bodyBytes[16]);
+ }
}
}
@@ -889,9 +934,9 @@ public void ReferenceConstructorInIL()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder tb, out MethodInfo saveMethod);
- MethodBuilder methodBuilder = tb.DefineMethod("Method1", MethodAttributes.Public, typeof(Version), new[] { typeof(int), typeof(int) });
- ConstructorInfo ctor = typeof(Version).GetConstructor(new[] { typeof(int), typeof(int) });
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder tb);
+ MethodBuilder methodBuilder = tb.DefineMethod("Method1", MethodAttributes.Public, typeof(Version), [typeof(int), typeof(int)]);
+ ConstructorInfo ctor = typeof(Version).GetConstructor([typeof(int), typeof(int)]);
ILGenerator il = methodBuilder.GetILGenerator();
il.Emit(OpCodes.Ldarg_1);
@@ -899,15 +944,18 @@ public void ReferenceConstructorInIL()
il.Emit(OpCodes.Newobj, ctor);
il.Emit(OpCodes.Ret);
tb.CreateType();
- saveMethod.Invoke(ab, new object[] { file.Path });
-
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
- byte[]? bodyBytes = typeFromDisk.GetMethod("Method1").GetMethodBody().GetILAsByteArray();
- Assert.Equal(OpCodes.Ldarg_1.Value, bodyBytes[0]);
- Assert.Equal(OpCodes.Ldarg_2.Value, bodyBytes[1]);
- Assert.Equal(OpCodes.Newobj.Value, bodyBytes[2]);
- Assert.Equal(OpCodes.Ret.Value, bodyBytes[7]);
+ ab.Save(file.Path);
+
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
+ byte[]? bodyBytes = typeFromDisk.GetMethod("Method1").GetMethodBody().GetILAsByteArray();
+ Assert.Equal(OpCodes.Ldarg_1.Value, bodyBytes[0]);
+ Assert.Equal(OpCodes.Ldarg_2.Value, bodyBytes[1]);
+ Assert.Equal(OpCodes.Newobj.Value, bodyBytes[2]);
+ Assert.Equal(OpCodes.Ret.Value, bodyBytes[7]);
+ }
}
}
@@ -916,7 +964,7 @@ public void ReferenceAType()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder tb, out MethodInfo saveMethod);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder tb);
MethodBuilder method = tb.DefineMethod("meth1", MethodAttributes.Public | MethodAttributes.Static, typeof(bool), Type.EmptyTypes);
ILGenerator ilGenerator = method.GetILGenerator();
LocalBuilder lb0 = ilGenerator.DeclareLocal(typeof(ValueTuple));
@@ -925,24 +973,27 @@ public void ReferenceAType()
ilGenerator.Emit(OpCodes.Ldc_I4, 1);
ilGenerator.Emit(OpCodes.Ret);
tb.CreateType();
- saveMethod.Invoke(ab, new object[] { file.Path });
-
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
- byte[]? bodyBytes = typeFromDisk.GetMethod("meth1").GetMethodBody().GetILAsByteArray();
- Assert.Equal(OpCodes.Ldloca_S.Value, bodyBytes[0]); // short form of Ldloca
- Assert.Equal(0, bodyBytes[1]);
- Assert.Equal(0xFE, bodyBytes[2]); // Initobj = 0xfe15
- Assert.Equal(0x15, bodyBytes[3]);
- Assert.Equal(OpCodes.Ldc_I4_1.Value, bodyBytes[8]);
- Assert.Equal(OpCodes.Ret.Value, bodyBytes[9]);
+ ab.Save(file.Path);
+
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
+ byte[]? bodyBytes = typeFromDisk.GetMethod("meth1").GetMethodBody().GetILAsByteArray();
+ Assert.Equal(OpCodes.Ldloca_S.Value, bodyBytes[0]); // short form of Ldloca
+ Assert.Equal(0, bodyBytes[1]);
+ Assert.Equal(0xFE, bodyBytes[2]); // Initobj = 0xfe15
+ Assert.Equal(0x15, bodyBytes[3]);
+ Assert.Equal(OpCodes.Ldc_I4_1.Value, bodyBytes[8]);
+ Assert.Equal(OpCodes.Ret.Value, bodyBytes[9]);
+ }
}
}
[Fact]
public void MemberReferenceExceptions()
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo saveMethod);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
MethodBuilder method = type.DefineMethod("Method1", MethodAttributes.Public);
ILGenerator il = method.GetILGenerator();
MethodInfo nullMethod = null;
@@ -975,8 +1026,8 @@ public void SimpleTryCatchBlock()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder tb, out MethodInfo saveMethod);
- MethodBuilder method = tb.DefineMethod("Method", MethodAttributes.Public | MethodAttributes.Static, typeof(float), new[] { typeof(int), typeof(int) });
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder tb);
+ MethodBuilder method = tb.DefineMethod("Method", MethodAttributes.Public | MethodAttributes.Static, typeof(float), [typeof(int), typeof(int)]);
Type dBZException = typeof(DivideByZeroException);
ILGenerator ilGenerator = method.GetILGenerator();
LocalBuilder local = ilGenerator.DeclareLocal(typeof(float));
@@ -996,28 +1047,31 @@ public void SimpleTryCatchBlock()
tb.CreateType();
Assert.Equal(3, getMaxStackMethod.Invoke(ilGenerator, null));
- saveMethod.Invoke(ab, new object[] { file.Path });
-
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
- MethodBody body = typeFromDisk.GetMethod("Method").GetMethodBody();
- Assert.Equal(1, body.ExceptionHandlingClauses.Count);
- Assert.Equal(dBZException.FullName, body.ExceptionHandlingClauses[0].CatchType.FullName);
- Assert.Equal(ExceptionHandlingClauseOptions.Clause, body.ExceptionHandlingClauses[0].Flags);
- byte[] bodyBytes = body.GetILAsByteArray();
- Assert.Equal(OpCodes.Ldarg_0.Value, bodyBytes[0]);
- Assert.Equal(OpCodes.Ldarg_1.Value, bodyBytes[1]);
- Assert.Equal(OpCodes.Div.Value, bodyBytes[2]);
- Assert.Equal(OpCodes.Stloc_0.Value, bodyBytes[3]);
- Assert.Equal(OpCodes.Leave.Value, bodyBytes[4]);
- // Next 4 bytes 'exBlock' label location
- Assert.Equal(OpCodes.Ldstr.Value, bodyBytes[9]); // "Error: division by zero"
- Assert.Equal(OpCodes.Call.Value, bodyBytes[14]); // Calls Console.WriteLine
- Assert.Equal(OpCodes.Ldc_R4.Value, bodyBytes[19]);
- Assert.Equal(OpCodes.Stloc_0.Value, bodyBytes[24]);
- Assert.Equal(OpCodes.Leave.Value, bodyBytes[25]);
- Assert.Equal(OpCodes.Ldloc_0.Value, bodyBytes[30]);
- Assert.Equal(OpCodes.Ret.Value, bodyBytes[31]);
+ ab.Save(file.Path);
+
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
+ MethodBody body = typeFromDisk.GetMethod("Method").GetMethodBody();
+ Assert.Equal(1, body.ExceptionHandlingClauses.Count);
+ Assert.Equal(dBZException.FullName, body.ExceptionHandlingClauses[0].CatchType.FullName);
+ Assert.Equal(ExceptionHandlingClauseOptions.Clause, body.ExceptionHandlingClauses[0].Flags);
+ byte[] bodyBytes = body.GetILAsByteArray();
+ Assert.Equal(OpCodes.Ldarg_0.Value, bodyBytes[0]);
+ Assert.Equal(OpCodes.Ldarg_1.Value, bodyBytes[1]);
+ Assert.Equal(OpCodes.Div.Value, bodyBytes[2]);
+ Assert.Equal(OpCodes.Stloc_0.Value, bodyBytes[3]);
+ Assert.Equal(OpCodes.Leave.Value, bodyBytes[4]);
+ // Next 4 bytes 'exBlock' label location
+ Assert.Equal(OpCodes.Ldstr.Value, bodyBytes[9]); // "Error: division by zero"
+ Assert.Equal(OpCodes.Call.Value, bodyBytes[14]); // Calls Console.WriteLine
+ Assert.Equal(OpCodes.Ldc_R4.Value, bodyBytes[19]);
+ Assert.Equal(OpCodes.Stloc_0.Value, bodyBytes[24]);
+ Assert.Equal(OpCodes.Leave.Value, bodyBytes[25]);
+ Assert.Equal(OpCodes.Ldloc_0.Value, bodyBytes[30]);
+ Assert.Equal(OpCodes.Ret.Value, bodyBytes[31]);
+ }
}
}
@@ -1026,8 +1080,8 @@ public void TryMultipleCatchBlocks()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder tb, out MethodInfo saveMethod);
- MethodBuilder method = tb.DefineMethod("Method", MethodAttributes.Public | MethodAttributes.Static, typeof(float), new[] { typeof(int), typeof(int) });
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder tb);
+ MethodBuilder method = tb.DefineMethod("Method", MethodAttributes.Public | MethodAttributes.Static, typeof(float), [typeof(int), typeof(int)]);
Type dBZException = typeof(DivideByZeroException);
Type exception = typeof(Exception);
ILGenerator ilGenerator = method.GetILGenerator();
@@ -1057,40 +1111,43 @@ public void TryMultipleCatchBlocks()
ilGenerator.Emit(OpCodes.Ldloc_0);
ilGenerator.Emit(OpCodes.Ret);
tb.CreateType();
- saveMethod.Invoke(ab, new object[] { file.Path });
+ ab.Save(file.Path);
Assert.Equal(2, maxStackField.GetValue(ilGenerator));
MethodInfo getMaxStackMethod = GetMaxStackMethod();
Assert.Equal(2, getMaxStackMethod.Invoke(ilGenerator, null));
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
- MethodBody body = typeFromDisk.GetMethod("Method").GetMethodBody();
- Assert.Equal(2, body.ExceptionHandlingClauses.Count);
- Assert.Equal(ExceptionHandlingClauseOptions.Clause, body.ExceptionHandlingClauses[0].Flags);
- Assert.Equal(ExceptionHandlingClauseOptions.Clause, body.ExceptionHandlingClauses[1].Flags);
- Assert.Equal(dBZException.FullName, body.ExceptionHandlingClauses[0].CatchType.FullName);
- Assert.Equal(exception.FullName, body.ExceptionHandlingClauses[1].CatchType.FullName);
- byte[] bodyBytes = body.GetILAsByteArray();
- Assert.Equal(OpCodes.Ldarg_0.Value, bodyBytes[0]);
- Assert.Equal(OpCodes.Ldarg_1.Value, bodyBytes[1]);
- Assert.Equal(OpCodes.Div.Value, bodyBytes[2]);
- Assert.Equal(OpCodes.Stloc_0.Value, bodyBytes[3]);
- Assert.Equal(OpCodes.Leave.Value, bodyBytes[4]);
- Assert.Equal(OpCodes.Ldstr.Value, bodyBytes[9]); // "Error: division by zero"
- Assert.Equal(OpCodes.Call.Value, bodyBytes[14]); // Calls Console.WriteLine
- Assert.Equal(OpCodes.Ldc_R4.Value, bodyBytes[19]);
- Assert.Equal(OpCodes.Stloc_0.Value, bodyBytes[24]);
- Assert.Equal(OpCodes.Pop.Value, bodyBytes[25]);
- Assert.Equal(OpCodes.Leave.Value, bodyBytes[26]);
- Assert.Equal(OpCodes.Ldstr.Value, bodyBytes[31]); // "Error: division by zero"
- Assert.Equal(OpCodes.Call.Value, bodyBytes[36]); // Calls Console.WriteLine
- Assert.Equal(OpCodes.Ldc_R4.Value, bodyBytes[41]);
- Assert.Equal(OpCodes.Stloc_0.Value, bodyBytes[46]);
- Assert.Equal(OpCodes.Pop.Value, bodyBytes[47]);
- Assert.Equal(OpCodes.Leave.Value, bodyBytes[48]);
- Assert.Equal(OpCodes.Ldloc_0.Value, bodyBytes[53]);
- Assert.Equal(OpCodes.Ret.Value, bodyBytes[54]);
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
+ MethodBody body = typeFromDisk.GetMethod("Method").GetMethodBody();
+ Assert.Equal(2, body.ExceptionHandlingClauses.Count);
+ Assert.Equal(ExceptionHandlingClauseOptions.Clause, body.ExceptionHandlingClauses[0].Flags);
+ Assert.Equal(ExceptionHandlingClauseOptions.Clause, body.ExceptionHandlingClauses[1].Flags);
+ Assert.Equal(dBZException.FullName, body.ExceptionHandlingClauses[0].CatchType.FullName);
+ Assert.Equal(exception.FullName, body.ExceptionHandlingClauses[1].CatchType.FullName);
+ byte[] bodyBytes = body.GetILAsByteArray();
+ Assert.Equal(OpCodes.Ldarg_0.Value, bodyBytes[0]);
+ Assert.Equal(OpCodes.Ldarg_1.Value, bodyBytes[1]);
+ Assert.Equal(OpCodes.Div.Value, bodyBytes[2]);
+ Assert.Equal(OpCodes.Stloc_0.Value, bodyBytes[3]);
+ Assert.Equal(OpCodes.Leave.Value, bodyBytes[4]);
+ Assert.Equal(OpCodes.Ldstr.Value, bodyBytes[9]); // "Error: division by zero"
+ Assert.Equal(OpCodes.Call.Value, bodyBytes[14]); // Calls Console.WriteLine
+ Assert.Equal(OpCodes.Ldc_R4.Value, bodyBytes[19]);
+ Assert.Equal(OpCodes.Stloc_0.Value, bodyBytes[24]);
+ Assert.Equal(OpCodes.Pop.Value, bodyBytes[25]);
+ Assert.Equal(OpCodes.Leave.Value, bodyBytes[26]);
+ Assert.Equal(OpCodes.Ldstr.Value, bodyBytes[31]); // "Error: division by zero"
+ Assert.Equal(OpCodes.Call.Value, bodyBytes[36]); // Calls Console.WriteLine
+ Assert.Equal(OpCodes.Ldc_R4.Value, bodyBytes[41]);
+ Assert.Equal(OpCodes.Stloc_0.Value, bodyBytes[46]);
+ Assert.Equal(OpCodes.Pop.Value, bodyBytes[47]);
+ Assert.Equal(OpCodes.Leave.Value, bodyBytes[48]);
+ Assert.Equal(OpCodes.Ldloc_0.Value, bodyBytes[53]);
+ Assert.Equal(OpCodes.Ret.Value, bodyBytes[54]);
+ }
}
}
@@ -1099,8 +1156,8 @@ public void TryFilterCatchBlock()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder tb, out MethodInfo saveMethod);
- MethodBuilder method = tb.DefineMethod("Method", MethodAttributes.Public | MethodAttributes.Static, typeof(float), new[] { typeof(int), typeof(int) });
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder tb);
+ MethodBuilder method = tb.DefineMethod("Method", MethodAttributes.Public | MethodAttributes.Static, typeof(float), [typeof(int), typeof(int)]);
Type dBZException = typeof(DivideByZeroException);
Type exception = typeof(Exception);
ILGenerator ilGenerator = method.GetILGenerator();
@@ -1139,18 +1196,21 @@ public void TryFilterCatchBlock()
ilGenerator.Emit(OpCodes.Ldloc_0);
ilGenerator.Emit(OpCodes.Ret);
tb.CreateType();
- saveMethod.Invoke(ab, new object[] { file.Path });
+ ab.Save(file.Path);
MethodInfo getMaxStackMethod = GetMaxStackMethod();
Assert.Equal(2, getMaxStackMethod.Invoke(ilGenerator, null));
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
- MethodBody body = typeFromDisk.GetMethod("Method").GetMethodBody();
- Assert.Equal(2, body.ExceptionHandlingClauses.Count);
- Assert.Equal(ExceptionHandlingClauseOptions.Filter, body.ExceptionHandlingClauses[0].Flags);
- Assert.Equal(ExceptionHandlingClauseOptions.Clause, body.ExceptionHandlingClauses[1].Flags);
- Assert.Equal(exception.FullName, body.ExceptionHandlingClauses[1].CatchType.FullName);
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
+ MethodBody body = typeFromDisk.GetMethod("Method").GetMethodBody();
+ Assert.Equal(2, body.ExceptionHandlingClauses.Count);
+ Assert.Equal(ExceptionHandlingClauseOptions.Filter, body.ExceptionHandlingClauses[0].Flags);
+ Assert.Equal(ExceptionHandlingClauseOptions.Clause, body.ExceptionHandlingClauses[1].Flags);
+ Assert.Equal(exception.FullName, body.ExceptionHandlingClauses[1].CatchType.FullName);
+ }
}
}
@@ -1159,8 +1219,8 @@ public void TryCatchFilterCatchBlock()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder tb, out MethodInfo saveMethod);
- MethodBuilder method = tb.DefineMethod("Method", MethodAttributes.Public | MethodAttributes.Static, typeof(float), new[] { typeof(int), typeof(int) });
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder tb);
+ MethodBuilder method = tb.DefineMethod("Method", MethodAttributes.Public | MethodAttributes.Static, typeof(float), [typeof(int), typeof(int)]);
Type dBZException = typeof(DivideByZeroException);
Type overflowException = typeof(OverflowException);
Type exception = typeof(Exception);
@@ -1209,20 +1269,23 @@ public void TryCatchFilterCatchBlock()
ilGenerator.Emit(OpCodes.Ldloc_0);
ilGenerator.Emit(OpCodes.Ret);
tb.CreateType();
- saveMethod.Invoke(ab, new object[] { file.Path });
+ ab.Save(file.Path);
MethodInfo getMaxStackMethod = GetMaxStackMethod();
Assert.Equal(2, getMaxStackMethod.Invoke(ilGenerator, null));
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
- MethodBody body = typeFromDisk.GetMethod("Method").GetMethodBody();
- Assert.Equal(3, body.ExceptionHandlingClauses.Count);
- Assert.Equal(ExceptionHandlingClauseOptions.Clause, body.ExceptionHandlingClauses[0].Flags);
- Assert.Equal(ExceptionHandlingClauseOptions.Filter, body.ExceptionHandlingClauses[1].Flags);
- Assert.Equal(ExceptionHandlingClauseOptions.Clause, body.ExceptionHandlingClauses[2].Flags);
- Assert.Equal(overflowException.FullName, body.ExceptionHandlingClauses[0].CatchType.FullName);
- Assert.Equal(exception.FullName, body.ExceptionHandlingClauses[2].CatchType.FullName);
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
+ MethodBody body = typeFromDisk.GetMethod("Method").GetMethodBody();
+ Assert.Equal(3, body.ExceptionHandlingClauses.Count);
+ Assert.Equal(ExceptionHandlingClauseOptions.Clause, body.ExceptionHandlingClauses[0].Flags);
+ Assert.Equal(ExceptionHandlingClauseOptions.Filter, body.ExceptionHandlingClauses[1].Flags);
+ Assert.Equal(ExceptionHandlingClauseOptions.Clause, body.ExceptionHandlingClauses[2].Flags);
+ Assert.Equal(overflowException.FullName, body.ExceptionHandlingClauses[0].CatchType.FullName);
+ Assert.Equal(exception.FullName, body.ExceptionHandlingClauses[2].CatchType.FullName);
+ }
}
}
@@ -1231,8 +1294,8 @@ public void TryFinallyBlock()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder tb, out MethodInfo saveMethod);
- MethodBuilder method = tb.DefineMethod("Method", MethodAttributes.Public | MethodAttributes.Static, typeof(float), new[] { typeof(int), typeof(int) });
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder tb);
+ MethodBuilder method = tb.DefineMethod("Method", MethodAttributes.Public | MethodAttributes.Static, typeof(float), [typeof(int), typeof(int)]);
ILGenerator ilGenerator = method.GetILGenerator();
LocalBuilder local = ilGenerator.DeclareLocal(typeof(float));
Label exBlock = ilGenerator.BeginExceptionBlock();
@@ -1246,27 +1309,30 @@ public void TryFinallyBlock()
ilGenerator.Emit(OpCodes.Ldloc_0);
ilGenerator.Emit(OpCodes.Ret);
tb.CreateType();
- saveMethod.Invoke(ab, new object[] { file.Path });
+ ab.Save(file.Path);
MethodInfo getMaxStackMethod = GetMaxStackMethod();
Assert.Equal(2, getMaxStackMethod.Invoke(ilGenerator, null));
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
- MethodBody body = typeFromDisk.GetMethod("Method").GetMethodBody();
- Assert.Equal(1, body.ExceptionHandlingClauses.Count);
- Assert.Equal(ExceptionHandlingClauseOptions.Finally, body.ExceptionHandlingClauses[0].Flags);
- byte[] bodyBytes = body.GetILAsByteArray();
- Assert.Equal(OpCodes.Ldarg_0.Value, bodyBytes[0]);
- Assert.Equal(OpCodes.Ldarg_1.Value, bodyBytes[1]);
- Assert.Equal(OpCodes.Div.Value, bodyBytes[2]);
- Assert.Equal(OpCodes.Stloc_0.Value, bodyBytes[3]);
- Assert.Equal(OpCodes.Leave.Value, bodyBytes[4]);
- Assert.Equal(OpCodes.Ldstr.Value, bodyBytes[9]);
- Assert.Equal(OpCodes.Call.Value, bodyBytes[14]);
- Assert.Equal(OpCodes.Endfinally.Value, bodyBytes[19]);
- Assert.Equal(OpCodes.Ldloc_0.Value, bodyBytes[20]);
- Assert.Equal(OpCodes.Ret.Value, bodyBytes[21]);
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
+ MethodBody body = typeFromDisk.GetMethod("Method").GetMethodBody();
+ Assert.Equal(1, body.ExceptionHandlingClauses.Count);
+ Assert.Equal(ExceptionHandlingClauseOptions.Finally, body.ExceptionHandlingClauses[0].Flags);
+ byte[] bodyBytes = body.GetILAsByteArray();
+ Assert.Equal(OpCodes.Ldarg_0.Value, bodyBytes[0]);
+ Assert.Equal(OpCodes.Ldarg_1.Value, bodyBytes[1]);
+ Assert.Equal(OpCodes.Div.Value, bodyBytes[2]);
+ Assert.Equal(OpCodes.Stloc_0.Value, bodyBytes[3]);
+ Assert.Equal(OpCodes.Leave.Value, bodyBytes[4]);
+ Assert.Equal(OpCodes.Ldstr.Value, bodyBytes[9]);
+ Assert.Equal(OpCodes.Call.Value, bodyBytes[14]);
+ Assert.Equal(OpCodes.Endfinally.Value, bodyBytes[19]);
+ Assert.Equal(OpCodes.Ldloc_0.Value, bodyBytes[20]);
+ Assert.Equal(OpCodes.Ret.Value, bodyBytes[21]);
+ }
}
}
@@ -1275,8 +1341,8 @@ public void TryCatchFinallyBlock()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder tb, out MethodInfo saveMethod);
- MethodBuilder method = tb.DefineMethod("Method", MethodAttributes.Public | MethodAttributes.Static, typeof(void), new[] { typeof(int), typeof(int) });
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder tb);
+ MethodBuilder method = tb.DefineMethod("Method", MethodAttributes.Public | MethodAttributes.Static, typeof(void), [typeof(int), typeof(int)]);
Type exception = typeof(Exception);
ILGenerator ilGenerator = method.GetILGenerator();
ilGenerator.BeginExceptionBlock();
@@ -1290,18 +1356,21 @@ public void TryCatchFinallyBlock()
ilGenerator.EndExceptionBlock();
ilGenerator.Emit(OpCodes.Ret);
tb.CreateType();
- saveMethod.Invoke(ab, new object[] { file.Path });
+ ab.Save(file.Path);
MethodInfo getMaxStackMethod = GetMaxStackMethod();
Assert.Equal(2, getMaxStackMethod.Invoke(ilGenerator, null));
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
- MethodBody body = typeFromDisk.GetMethod("Method").GetMethodBody();
- Assert.Equal(2, body.ExceptionHandlingClauses.Count);
- Assert.Equal(ExceptionHandlingClauseOptions.Clause, body.ExceptionHandlingClauses[0].Flags);
- Assert.Equal(ExceptionHandlingClauseOptions.Finally, body.ExceptionHandlingClauses[1].Flags);
- Assert.Equal(exception.FullName, body.ExceptionHandlingClauses[0].CatchType.FullName);
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
+ MethodBody body = typeFromDisk.GetMethod("Method").GetMethodBody();
+ Assert.Equal(2, body.ExceptionHandlingClauses.Count);
+ Assert.Equal(ExceptionHandlingClauseOptions.Clause, body.ExceptionHandlingClauses[0].Flags);
+ Assert.Equal(ExceptionHandlingClauseOptions.Finally, body.ExceptionHandlingClauses[1].Flags);
+ Assert.Equal(exception.FullName, body.ExceptionHandlingClauses[0].CatchType.FullName);
+ }
}
}
@@ -1310,12 +1379,12 @@ public void TryFilterCatchFinallyBlock()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder tb, out MethodInfo saveMethod);
- MethodBuilder method = tb.DefineMethod("Method", MethodAttributes.Public | MethodAttributes.Static, typeof(int), new[] { typeof(int), typeof(int) });
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder tb);
+ MethodBuilder method = tb.DefineMethod("Method", MethodAttributes.Public | MethodAttributes.Static, typeof(int), [typeof(int), typeof(int)]);
Type overflowEType = typeof(OverflowException);
- ConstructorInfo myConstructorInfo = overflowEType.GetConstructor(new[] { typeof(string) });
+ ConstructorInfo myConstructorInfo = overflowEType.GetConstructor([typeof(string)]);
MethodInfo myExToStrMI = overflowEType.GetMethod("ToString");
- MethodInfo myWriteLineMI = typeof(Console).GetMethod("WriteLine", new[] { typeof(string), typeof(object) });
+ MethodInfo myWriteLineMI = typeof(Console).GetMethod("WriteLine", [typeof(string), typeof(object)]);
ILGenerator ilGenerator = method.GetILGenerator();
LocalBuilder myLocalBuilder1 = ilGenerator.DeclareLocal(typeof(int));
LocalBuilder myLocalBuilder2 = ilGenerator.DeclareLocal(overflowEType);
@@ -1359,19 +1428,22 @@ public void TryFilterCatchFinallyBlock()
ilGenerator.Emit(OpCodes.Ldloc_S, myLocalBuilder1);
ilGenerator.Emit(OpCodes.Ret);
tb.CreateType();
- saveMethod.Invoke(ab, new object[] { file.Path });
+ ab.Save(file.Path);
MethodInfo getMaxStackMethod = GetMaxStackMethod();
Assert.Equal(2, getMaxStackMethod.Invoke(ilGenerator, null));
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
- MethodBody body = typeFromDisk.GetMethod("Method").GetMethodBody();
- Assert.Equal(3, body.ExceptionHandlingClauses.Count);
- Assert.Equal(ExceptionHandlingClauseOptions.Filter, body.ExceptionHandlingClauses[0].Flags);
- Assert.Equal(ExceptionHandlingClauseOptions.Clause, body.ExceptionHandlingClauses[1].Flags);
- Assert.Equal(ExceptionHandlingClauseOptions.Finally, body.ExceptionHandlingClauses[2].Flags);
- Assert.Equal(overflowEType.FullName, body.ExceptionHandlingClauses[1].CatchType.FullName);
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
+ MethodBody body = typeFromDisk.GetMethod("Method").GetMethodBody();
+ Assert.Equal(3, body.ExceptionHandlingClauses.Count);
+ Assert.Equal(ExceptionHandlingClauseOptions.Filter, body.ExceptionHandlingClauses[0].Flags);
+ Assert.Equal(ExceptionHandlingClauseOptions.Clause, body.ExceptionHandlingClauses[1].Flags);
+ Assert.Equal(ExceptionHandlingClauseOptions.Finally, body.ExceptionHandlingClauses[2].Flags);
+ Assert.Equal(overflowEType.FullName, body.ExceptionHandlingClauses[1].CatchType.FullName);
+ }
}
}
@@ -1380,8 +1452,8 @@ public void TryFaultBlock()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder tb, out MethodInfo saveMethod);
- MethodBuilder method = tb.DefineMethod("Method", MethodAttributes.Public | MethodAttributes.Static, typeof(float), new[] { typeof(int), typeof(int) });
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder tb);
+ MethodBuilder method = tb.DefineMethod("Method", MethodAttributes.Public | MethodAttributes.Static, typeof(float), [typeof(int), typeof(int)]);
ILGenerator ilGenerator = method.GetILGenerator();
Label exBlock = ilGenerator.BeginExceptionBlock();
ilGenerator.Emit(OpCodes.Ldarg_0);
@@ -1396,29 +1468,32 @@ public void TryFaultBlock()
ilGenerator.Emit(OpCodes.Ldloc_0);
ilGenerator.Emit(OpCodes.Ret);
tb.CreateType();
- saveMethod.Invoke(ab, new object[] { file.Path });
+ ab.Save(file.Path);
MethodInfo getMaxStackMethod = GetMaxStackMethod();
Assert.Equal(2, getMaxStackMethod.Invoke(ilGenerator, null));
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
- MethodBody body = typeFromDisk.GetMethod("Method").GetMethodBody();
- Assert.Equal(1, body.ExceptionHandlingClauses.Count);
- Assert.Equal(ExceptionHandlingClauseOptions.Fault, body.ExceptionHandlingClauses[0].Flags);
- byte[] bodyBytes = body.GetILAsByteArray();
- Assert.Equal(OpCodes.Ldarg_0.Value, bodyBytes[0]);
- Assert.Equal(OpCodes.Ldarg_1.Value, bodyBytes[1]);
- Assert.Equal(OpCodes.Div.Value, bodyBytes[2]);
- Assert.Equal(OpCodes.Stloc_0.Value, bodyBytes[3]);
- Assert.Equal(OpCodes.Leave.Value, bodyBytes[4]);
- Assert.Equal(OpCodes.Ldstr.Value, bodyBytes[9]);
- Assert.Equal(OpCodes.Call.Value, bodyBytes[14]);
- Assert.Equal(OpCodes.Ldc_R4.Value, bodyBytes[19]);
- Assert.Equal(OpCodes.Stloc_0.Value, bodyBytes[24]);
- Assert.Equal(OpCodes.Endfinally.Value, bodyBytes[25]);
- Assert.Equal(OpCodes.Ldloc_0.Value, bodyBytes[26]);
- Assert.Equal(OpCodes.Ret.Value, bodyBytes[27]);
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
+ MethodBody body = typeFromDisk.GetMethod("Method").GetMethodBody();
+ Assert.Equal(1, body.ExceptionHandlingClauses.Count);
+ Assert.Equal(ExceptionHandlingClauseOptions.Fault, body.ExceptionHandlingClauses[0].Flags);
+ byte[] bodyBytes = body.GetILAsByteArray();
+ Assert.Equal(OpCodes.Ldarg_0.Value, bodyBytes[0]);
+ Assert.Equal(OpCodes.Ldarg_1.Value, bodyBytes[1]);
+ Assert.Equal(OpCodes.Div.Value, bodyBytes[2]);
+ Assert.Equal(OpCodes.Stloc_0.Value, bodyBytes[3]);
+ Assert.Equal(OpCodes.Leave.Value, bodyBytes[4]);
+ Assert.Equal(OpCodes.Ldstr.Value, bodyBytes[9]);
+ Assert.Equal(OpCodes.Call.Value, bodyBytes[14]);
+ Assert.Equal(OpCodes.Ldc_R4.Value, bodyBytes[19]);
+ Assert.Equal(OpCodes.Stloc_0.Value, bodyBytes[24]);
+ Assert.Equal(OpCodes.Endfinally.Value, bodyBytes[25]);
+ Assert.Equal(OpCodes.Ldloc_0.Value, bodyBytes[26]);
+ Assert.Equal(OpCodes.Ret.Value, bodyBytes[27]);
+ }
}
}
@@ -1427,8 +1502,8 @@ public void NestedTryCatchBlocks()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder tb, out MethodInfo saveMethod);
- MethodBuilder method = tb.DefineMethod("Method", MethodAttributes.Public | MethodAttributes.Static, typeof(void), new[] { typeof(int), typeof(int) });
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder tb);
+ MethodBuilder method = tb.DefineMethod("Method", MethodAttributes.Public | MethodAttributes.Static, typeof(void), [typeof(int), typeof(int)]);
Type exception = typeof(Exception);
ILGenerator ilGenerator = method.GetILGenerator();
MethodInfo getMaxStackMethod = GetMaxStackMethod();
@@ -1472,20 +1547,23 @@ public void NestedTryCatchBlocks()
ilGenerator.EndExceptionBlock();
ilGenerator.Emit(OpCodes.Ret);
tb.CreateType();
- saveMethod.Invoke(ab, new object[] { file.Path });
+ ab.Save(file.Path);
Assert.Equal(5, getMaxStackMethod.Invoke(ilGenerator, null));
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
- MethodBody body = typeFromDisk.GetMethod("Method").GetMethodBody();
- Assert.Equal(3, body.ExceptionHandlingClauses.Count);
- Assert.Equal(ExceptionHandlingClauseOptions.Clause, body.ExceptionHandlingClauses[0].Flags);
- Assert.Equal(ExceptionHandlingClauseOptions.Clause, body.ExceptionHandlingClauses[1].Flags);
- Assert.Equal(ExceptionHandlingClauseOptions.Clause, body.ExceptionHandlingClauses[2].Flags);
- Assert.Equal(exception.FullName, body.ExceptionHandlingClauses[0].CatchType.FullName);
- Assert.Equal(exception.FullName, body.ExceptionHandlingClauses[1].CatchType.FullName);
- Assert.Equal(exception.FullName, body.ExceptionHandlingClauses[2].CatchType.FullName);
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
+ MethodBody body = typeFromDisk.GetMethod("Method").GetMethodBody();
+ Assert.Equal(3, body.ExceptionHandlingClauses.Count);
+ Assert.Equal(ExceptionHandlingClauseOptions.Clause, body.ExceptionHandlingClauses[0].Flags);
+ Assert.Equal(ExceptionHandlingClauseOptions.Clause, body.ExceptionHandlingClauses[1].Flags);
+ Assert.Equal(ExceptionHandlingClauseOptions.Clause, body.ExceptionHandlingClauses[2].Flags);
+ Assert.Equal(exception.FullName, body.ExceptionHandlingClauses[0].CatchType.FullName);
+ Assert.Equal(exception.FullName, body.ExceptionHandlingClauses[1].CatchType.FullName);
+ Assert.Equal(exception.FullName, body.ExceptionHandlingClauses[2].CatchType.FullName);
+ }
}
}
@@ -1494,8 +1572,8 @@ public void DeeperNestedTryCatchFilterFinallyBlocks()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder tb, out MethodInfo saveMethod);
- MethodBuilder method = tb.DefineMethod("Method", MethodAttributes.Public | MethodAttributes.Static, typeof(int), new[] { typeof(int), typeof(int) });
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder tb);
+ MethodBuilder method = tb.DefineMethod("Method", MethodAttributes.Public | MethodAttributes.Static, typeof(int), [typeof(int), typeof(int)]);
Type exception = typeof(Exception);
ILGenerator ilGenerator = method.GetILGenerator();
MethodInfo getMaxStackMethod = GetMaxStackMethod();
@@ -1569,20 +1647,23 @@ public void DeeperNestedTryCatchFilterFinallyBlocks()
ilGenerator.Emit(OpCodes.Ldloc_0);
ilGenerator.Emit(OpCodes.Ret);
tb.CreateType();
- saveMethod.Invoke(ab, new object[] { file.Path });
+ ab.Save(file.Path);
Assert.Equal(5, getMaxStackMethod.Invoke(ilGenerator, null));
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
- MethodBody body = typeFromDisk.GetMethod("Method").GetMethodBody();
- Assert.Equal(6, body.ExceptionHandlingClauses.Count);
- Assert.Equal(ExceptionHandlingClauseOptions.Finally, body.ExceptionHandlingClauses[0].Flags);
- Assert.Equal(ExceptionHandlingClauseOptions.Filter, body.ExceptionHandlingClauses[1].Flags);
- Assert.Equal(ExceptionHandlingClauseOptions.Clause, body.ExceptionHandlingClauses[2].Flags);
- Assert.Equal(ExceptionHandlingClauseOptions.Finally, body.ExceptionHandlingClauses[3].Flags);
- Assert.Equal(ExceptionHandlingClauseOptions.Clause, body.ExceptionHandlingClauses[4].Flags);
- Assert.Equal(ExceptionHandlingClauseOptions.Clause, body.ExceptionHandlingClauses[5].Flags);
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
+ MethodBody body = typeFromDisk.GetMethod("Method").GetMethodBody();
+ Assert.Equal(6, body.ExceptionHandlingClauses.Count);
+ Assert.Equal(ExceptionHandlingClauseOptions.Finally, body.ExceptionHandlingClauses[0].Flags);
+ Assert.Equal(ExceptionHandlingClauseOptions.Filter, body.ExceptionHandlingClauses[1].Flags);
+ Assert.Equal(ExceptionHandlingClauseOptions.Clause, body.ExceptionHandlingClauses[2].Flags);
+ Assert.Equal(ExceptionHandlingClauseOptions.Finally, body.ExceptionHandlingClauses[3].Flags);
+ Assert.Equal(ExceptionHandlingClauseOptions.Clause, body.ExceptionHandlingClauses[4].Flags);
+ Assert.Equal(ExceptionHandlingClauseOptions.Clause, body.ExceptionHandlingClauses[5].Flags);
+ }
}
}
@@ -1597,7 +1678,7 @@ public void EmitCalliBlittable()
int a = 1, b = 1, result = 2;
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndSaveMethod(new AssemblyName("EmitCalliBlittable"), out MethodInfo saveMethod);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilder(new AssemblyName("EmitCalliBlittable"));
TypeBuilder tb = ab.DefineDynamicModule("MyModule").DefineType("MyType", TypeAttributes.Public | TypeAttributes.Class);
Type returnType = typeof(int);
MethodBuilder methodBuilder = tb.DefineMethod("F", MethodAttributes.Public | MethodAttributes.Static, returnType, [typeof(IntPtr), typeof(int), typeof(int)]);
@@ -1609,7 +1690,7 @@ public void EmitCalliBlittable()
il.EmitCalli(OpCodes.Calli, CallingConvention.StdCall, returnType, [typeof(int), typeof(int)]);
il.Emit(OpCodes.Ret);
tb.CreateType();
- saveMethod.Invoke(ab, [file.Path]);
+ ab.Save(file.Path);
TestAssemblyLoadContext tlc = new TestAssemblyLoadContext();
Assembly assemblyFromDisk = tlc.LoadFromAssemblyPath(file.Path);
@@ -1631,7 +1712,7 @@ public void EmitCalliManagedBlittable()
int a = 1, b = 1, result = 2;
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndSaveMethod(new AssemblyName("EmitCalliManagedBlittable"), out MethodInfo saveMethod);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilder(new AssemblyName("EmitCalliManagedBlittable"));
TypeBuilder tb = ab.DefineDynamicModule("MyModule").DefineType("MyType", TypeAttributes.Public | TypeAttributes.Class);
Type returnType = typeof(int);
MethodBuilder methodBuilder = tb.DefineMethod("F", MethodAttributes.Public | MethodAttributes.Static, returnType, [typeof(IntPtr), typeof(int), typeof(int)]);
@@ -1645,7 +1726,7 @@ public void EmitCalliManagedBlittable()
il.EmitCalli(OpCodes.Calli, CallingConventions.Standard, returnType, [typeof(int), typeof(int)], null);
il.Emit(OpCodes.Ret);
tb.CreateType();
- saveMethod.Invoke(ab, [file.Path]);
+ ab.Save(file.Path);
TestAssemblyLoadContext tlc = new TestAssemblyLoadContext();
Assembly assemblyFromDisk = tlc.LoadFromAssemblyPath(file.Path);
@@ -1666,10 +1747,10 @@ public void EmitCalliManagedBlittable()
[Fact]
public void EmitCalliNonBlittable()
{
- string input = "Test string!", result = "!gnirts tseT";
+ string input = "Test string!", result = "!gnirts tseT";
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndSaveMethod(new AssemblyName("EmitCalliNonBlittable"), out MethodInfo saveMethod);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilder(new AssemblyName("EmitCalliNonBlittable"));
TypeBuilder tb = ab.DefineDynamicModule("MyModule").DefineType("MyType", TypeAttributes.Public | TypeAttributes.Class);
Type returnType = typeof(string);
MethodBuilder methodBuilder = tb.DefineMethod("F", MethodAttributes.Public | MethodAttributes.Static, returnType, [typeof(IntPtr), typeof(string)]);
@@ -1680,7 +1761,7 @@ public void EmitCalliNonBlittable()
il.EmitCalli(OpCodes.Calli, CallingConvention.Cdecl, returnType, [typeof(string)]);
il.Emit(OpCodes.Ret);
tb.CreateType();
- saveMethod.Invoke(ab, [file.Path]);
+ ab.Save(file.Path);
TestAssemblyLoadContext tlc = new TestAssemblyLoadContext();
Assembly assemblyFromDisk = tlc.LoadFromAssemblyPath(file.Path);
@@ -1702,7 +1783,7 @@ public void EmitCall_VarArgsMethodInIL()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder tb, out MethodInfo saveMethod);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder tb);
MethodBuilder mb1 = tb.DefineMethod("VarArgMethod", MethodAttributes.Public | MethodAttributes.Static, CallingConventions.VarArgs, null, [typeof(string)]);
ILGenerator il1 = mb1.GetILGenerator();
LocalBuilder locAi = il1.DeclareLocal(typeof(ArgIterator));
@@ -1755,24 +1836,27 @@ public void EmitCall_VarArgsMethodInIL()
il2.EmitCall(OpCodes.Call, mb1, [typeof(string), typeof(int)]);
il2.Emit(OpCodes.Ret);
Type type = tb.CreateType();
- saveMethod.Invoke(ab, [file.Path]);
-
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
- MethodInfo varArgMethodFromDisk = typeFromDisk.GetMethod("VarArgMethod");
- Assert.Equal(CallingConventions.VarArgs, varArgMethodFromDisk.CallingConvention);
- ParameterInfo[] parameters = varArgMethodFromDisk.GetParameters();
- Assert.Equal(1, parameters.Length); // TODO: how to get the vararg parameter?
- IList locals = varArgMethodFromDisk.GetMethodBody().LocalVariables;
- Assert.Equal(2, locals.Count);
- Assert.Equal(typeof(ArgIterator).FullName, locals[0].LocalType.FullName);
- Assert.Equal(typeof(bool).FullName, locals[1].LocalType.FullName);
-
- byte[] callingMethodBody = typeFromDisk.GetMethod("CallVarArgMethod").GetMethodBody().GetILAsByteArray();
- Assert.Equal(OpCodes.Ldstr.Value, callingMethodBody[0]);
- Assert.Equal(OpCodes.Ldstr.Value, callingMethodBody[5]);
- Assert.Equal(OpCodes.Ldc_I4.Value, callingMethodBody[10]);
- Assert.Equal(OpCodes.Call.Value, callingMethodBody[15]);
+ ab.Save(file.Path);
+
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
+ MethodInfo varArgMethodFromDisk = typeFromDisk.GetMethod("VarArgMethod");
+ Assert.Equal(CallingConventions.VarArgs, varArgMethodFromDisk.CallingConvention);
+ ParameterInfo[] parameters = varArgMethodFromDisk.GetParameters();
+ Assert.Equal(1, parameters.Length); // TODO: how to get the vararg parameter?
+ IList locals = varArgMethodFromDisk.GetMethodBody().LocalVariables;
+ Assert.Equal(2, locals.Count);
+ Assert.Equal(typeof(ArgIterator).FullName, locals[0].LocalType.FullName);
+ Assert.Equal(typeof(bool).FullName, locals[1].LocalType.FullName);
+
+ byte[] callingMethodBody = typeFromDisk.GetMethod("CallVarArgMethod").GetMethodBody().GetILAsByteArray();
+ Assert.Equal(OpCodes.Ldstr.Value, callingMethodBody[0]);
+ Assert.Equal(OpCodes.Ldstr.Value, callingMethodBody[5]);
+ Assert.Equal(OpCodes.Ldc_I4.Value, callingMethodBody[10]);
+ Assert.Equal(OpCodes.Call.Value, callingMethodBody[15]);
+ }
}
}
@@ -1788,7 +1872,7 @@ public void Emit_CallBySignature()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder tb, out MethodInfo saveMethod);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder tb);
MethodBuilder mb1 = tb.DefineMethod("VarArgMethod", MethodAttributes.Public | MethodAttributes.Static, CallingConventions.VarArgs, null, [typeof(string)]);
ILGenerator il1 = mb1.GetILGenerator();
FieldInfo maxStack = GetMaxStackDepthAndCurrentStackDepthField(out FieldInfo currentStack);
@@ -1862,19 +1946,22 @@ public void Emit_CallBySignature()
Assert.Equal(0, depthAdjustment.GetValue(il2));
Assert.Equal(4, getMaxStackMethod.Invoke(il2, null));
Type type = tb.CreateType();
- saveMethod.Invoke(ab, [file.Path]);
-
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
- Assert.Equal(CallingConventions.VarArgs, typeFromDisk.GetMethod("VarArgMethod").CallingConvention);
-
- byte[] callingMethodBody = typeFromDisk.GetMethod("CallingMethod").GetMethodBody().GetILAsByteArray();
- Assert.Equal(OpCodes.Ldstr.Value, callingMethodBody[0]);
- Assert.Equal(OpCodes.Ldstr.Value, callingMethodBody[5]);
- Assert.Equal(OpCodes.Ldc_I4.Value, callingMethodBody[10]);
- Assert.Equal(0xFE, callingMethodBody[15]); // Ldftn = 0xfe06
- Assert.Equal(0x06, callingMethodBody[16]);
- Assert.Equal(OpCodes.Calli.Value, callingMethodBody[21]);
+ ab.Save(file.Path);
+
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
+ Assert.Equal(CallingConventions.VarArgs, typeFromDisk.GetMethod("VarArgMethod").CallingConvention);
+
+ byte[] callingMethodBody = typeFromDisk.GetMethod("CallingMethod").GetMethodBody().GetILAsByteArray();
+ Assert.Equal(OpCodes.Ldstr.Value, callingMethodBody[0]);
+ Assert.Equal(OpCodes.Ldstr.Value, callingMethodBody[5]);
+ Assert.Equal(OpCodes.Ldc_I4.Value, callingMethodBody[10]);
+ Assert.Equal(0xFE, callingMethodBody[15]); // Ldftn = 0xfe06
+ Assert.Equal(0x06, callingMethodBody[16]);
+ Assert.Equal(OpCodes.Calli.Value, callingMethodBody[21]);
+ }
}
}
@@ -1895,7 +1982,7 @@ public void MaxStackOverflowTest()
///
static void GetCode(int num)
{
- AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo _);
+ AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
MethodBuilder method = type.DefineMethod("meth1", MethodAttributes.Public | MethodAttributes.Static, typeof(int), Type.EmptyTypes);
var ilg = method.GetILGenerator();
@@ -1941,7 +2028,7 @@ public void MaxStackNonEmptyForward()
static void GetCode(int num)
{
- AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo _);
+ AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
MethodBuilder method = type.DefineMethod("meth1", MethodAttributes.Public | MethodAttributes.Static, typeof(int), null);
var ilg = method.GetILGenerator();
@@ -1990,7 +2077,7 @@ public void MaxStackNonEmptyBackward()
static void GetCode(int num)
{
- AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo _);
+ AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
MethodBuilder method = type.DefineMethod("meth1", MethodAttributes.Public | MethodAttributes.Static, typeof(int), Type.EmptyTypes);
var ilg = method.GetILGenerator();
@@ -2044,8 +2131,8 @@ public void AmbiguousDepth()
static void GetCode()
{
- AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo _);
- MethodBuilder method = type.DefineMethod("meth1", MethodAttributes.Public | MethodAttributes.Static, typeof(int), new[] { typeof(bool) });
+ AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
+ MethodBuilder method = type.DefineMethod("meth1", MethodAttributes.Public | MethodAttributes.Static, typeof(int), [typeof(bool)]);
var ilg = method.GetILGenerator();
// The label is targeted with stack depth zero.
@@ -2075,7 +2162,7 @@ public void UnreachableDepth()
static void GetCode()
{
- AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo _);
+ AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
MethodBuilder method = type.DefineMethod("meth1", MethodAttributes.Public | MethodAttributes.Static, typeof(int), Type.EmptyTypes);
var ilg = method.GetILGenerator();
@@ -2104,7 +2191,7 @@ public void SimpleForLoopTest()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder tb, out MethodInfo saveMethod);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder tb);
MethodBuilder mb2 = tb.DefineMethod("SumMethod", MethodAttributes.Public | MethodAttributes.Static, typeof(int), [typeof(int)]);
ILGenerator il = mb2.GetILGenerator();
LocalBuilder sum = il.DeclareLocal(typeof(int));
@@ -2132,7 +2219,7 @@ public void SimpleForLoopTest()
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Ret);
tb.CreateType();
- saveMethod.Invoke(ab, [file.Path]);
+ ab.Save(file.Path);
MethodInfo getMaxStackMethod = GetMaxStackMethod();
Assert.Equal(2, getMaxStackMethod.Invoke(il, null));
@@ -2151,7 +2238,8 @@ public void RecursiveSumTest()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder tb, out MethodInfo saveMethod);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilder(new AssemblyName("RecursiveSumTest"));
+ TypeBuilder tb = ab.DefineDynamicModule("MyModule").DefineType("MyType", TypeAttributes.Public | TypeAttributes.Class);
MethodBuilder mb2 = tb.DefineMethod("RecursiveMethod", MethodAttributes.Public | MethodAttributes.Static, typeof(int), [typeof(int)]);
ILGenerator il = mb2.GetILGenerator();
Label loopEnd = il.DefineLabel();
@@ -2169,7 +2257,7 @@ public void RecursiveSumTest()
il.Emit(OpCodes.Ldc_I4_0);
il.Emit(OpCodes.Ret);
tb.CreateType();
- saveMethod.Invoke(ab, [file.Path]);
+ ab.Save(file.Path);
MethodInfo getMaxStackMethod = GetMaxStackMethod();
Assert.Equal(3, getMaxStackMethod.Invoke(il, null));
@@ -2189,7 +2277,7 @@ public void CallOpenGenericMembersFromConstructedGenericType()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo saveMethod);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
MethodBuilder method = type.DefineMethod("M1", MethodAttributes.Public, typeof(string), null);
ILGenerator ilGenerator = method.GetILGenerator();
@@ -2209,7 +2297,7 @@ public void CallOpenGenericMembersFromConstructedGenericType()
ilGenerator.Emit(OpCodes.Ret);
type.CreateType();
- saveMethod.Invoke(ab, [file.Path]);
+ ab.Save(file.Path);
TestAssemblyLoadContext tlc = new TestAssemblyLoadContext();
Type typeFromDisk = tlc.LoadFromAssemblyPath(file.Path).GetType("MyType");
diff --git a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveModuleBuilderTests.cs b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveModuleBuilderTests.cs
index 6a3bb1e4dcbcbc..e6b5405ed81cb0 100644
--- a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveModuleBuilderTests.cs
+++ b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveModuleBuilderTests.cs
@@ -15,7 +15,7 @@ public void DefineGlobalMethodAndCreateGlobalFunctionsTest()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndSaveMethod(new AssemblyName("MyAssembly"), out MethodInfo saveMethod);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilder(new AssemblyName("MyAssembly"));
ModuleBuilder module = ab.DefineDynamicModule("MyModule");
MethodBuilder method = module.DefineGlobalMethod("TestMethod", MethodAttributes.Static | MethodAttributes.Public, null, null);
ILGenerator ilGenerator = method.GetILGenerator();
@@ -36,7 +36,7 @@ public void DefineGlobalMethodAndCreateGlobalFunctionsTest()
Assert.Equal(method2, module.GetMethod("MyMethod", [typeof(string), typeof(int)]));
Assert.Equal(2, module.GetMethods().Length);
- saveMethod.Invoke(ab, [file.Path]);
+ ab.Save(file.Path);
using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
{
@@ -63,7 +63,7 @@ public void DefineGlobalMethodAndCreateGlobalFunctionsTest()
[Fact]
public void DefineGlobalMethodAndCreateGlobalFunctions_Validations()
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndSaveMethod(new AssemblyName("MyAssembly"), out MethodInfo _);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilder(new AssemblyName("MyAssembly"));
ModuleBuilder module = ab.DefineDynamicModule("MyModule");
Assert.Throws(() => module.DefineGlobalMethod("TestMethod", MethodAttributes.Public, null, null)); // must be static
MethodBuilder method = module.DefineGlobalMethod("TestMethod", MethodAttributes.Static | MethodAttributes.Public, null, null);
@@ -85,7 +85,7 @@ public static void DefinePInvokeMethodTest()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndSaveMethod(new AssemblyName("MyAssembly"), out MethodInfo saveMethod);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilder(new AssemblyName("MyAssembly"));
DpmParams p = new DpmParams() { MethodName = "A2", LibName = "Foo2.dll", EntrypointName = "Wha2", ReturnType = typeof(int),
ParameterTypes = [typeof(int)], NativeCallConv = CallingConvention.Cdecl };
@@ -95,7 +95,7 @@ public static void DefinePInvokeMethodTest()
mb.SetImplementationFlags(mb.GetMethodImplementationFlags() | MethodImplAttributes.PreserveSig);
modb.CreateGlobalFunctions();
- saveMethod.Invoke(ab, [file.Path]);
+ ab.Save(file.Path);
MethodInfo m = modb.GetMethod(p.MethodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static, null, CallingConventions.Any, p.ParameterTypes, null);
Assert.NotNull(m);
@@ -117,7 +117,7 @@ public static void DefinePInvokeMethodTest()
[InlineData(FieldAttributes.Assembly | FieldAttributes.SpecialName)]
public void DefineUninitializedDataTest(FieldAttributes attributes)
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndSaveMethod(new AssemblyName("MyAssembly"), out MethodInfo _);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilder(new AssemblyName("MyAssembly"));
ModuleBuilder module = ab.DefineDynamicModule("MyModule");
foreach (int size in new int[] { 1, 2, 0x003f0000 - 1 })
{
@@ -133,7 +133,7 @@ public void DefineUninitializedDataTest(FieldAttributes attributes)
[Fact]
public void DefineUninitializedData_Validations()
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndSaveMethod(new AssemblyName("MyAssembly"), out MethodInfo _);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilder(new AssemblyName("MyAssembly"));
ModuleBuilder module = ab.DefineDynamicModule("MyModule");
AssertExtensions.Throws("name", () => module.DefineUninitializedData(null, 1, FieldAttributes.Family));
@@ -154,7 +154,7 @@ public void DefineUninitializedData_Validations()
[InlineData(FieldAttributes.Private)]
public void DefineInitializedDataTest(FieldAttributes attributes)
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndSaveMethod(new AssemblyName("MyAssembly"), out MethodInfo _);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilder(new AssemblyName("MyAssembly"));
ModuleBuilder module = ab.DefineDynamicModule("MyModule");
FieldBuilder field = module.DefineInitializedData("MyField", [01, 00, 01], attributes);
@@ -167,7 +167,7 @@ public void DefineInitializedDataTest(FieldAttributes attributes)
[Fact]
public void DefineInitializedData_Validations()
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndSaveMethod(new AssemblyName("MyAssembly"), out MethodInfo _);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilder(new AssemblyName("MyAssembly"));
ModuleBuilder module = ab.DefineDynamicModule("MyModule");
AssertExtensions.Throws("name", () => module.DefineInitializedData(null, [1, 0, 1], FieldAttributes.Public));
@@ -190,7 +190,7 @@ public void DefineInitializedData_EnsureAlignmentIsMinimumNeededForUseOfCreateSp
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndSaveMethod(new AssemblyName("MyAssembly"), out MethodInfo saveMethod);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilder(new AssemblyName("MyAssembly"));
ModuleBuilder module = ab.DefineDynamicModule("MyModule");
TypeBuilder tb = module.DefineType("MyType", TypeAttributes.Public);
// Create static field data in a variety of orders that requires the runtime to actively apply alignment
@@ -232,7 +232,7 @@ void CreateLoadAddressMethod(string name, FieldBuilder fieldBuilder)
}
checkTypeBuilder.CreateType();
- saveMethod.Invoke(ab, [file.Path]);
+ ab.Save(file.Path);
TestAssemblyLoadContext tlc = new TestAssemblyLoadContext();
Assembly assemblyFromDisk = tlc.LoadFromAssemblyPath(file.Path);
@@ -265,7 +265,7 @@ void CheckMethod(string name, int minAlignmentRequired, byte[] dataToVerify)
[ActiveIssue("https://github.com/dotnet/runtime/issues/96389", TestRuntimes.Mono)]
public void GetABCMetadataToken_Validations()
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndSaveMethod(new AssemblyName("MyAssembly"), out MethodInfo _);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilder(new AssemblyName("MyAssembly"));
ModuleBuilder module = ab.DefineDynamicModule("MyModule");
TypeBuilder type = module.DefineType("MyType", TypeAttributes.Public);
MethodBuilder method = type.DefineMethod("TestMethod", MethodAttributes.Static | MethodAttributes.Public);
diff --git a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySavePropertyBuilderTests.cs b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySavePropertyBuilderTests.cs
index e478827125e7c7..c18eb017c14284 100644
--- a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySavePropertyBuilderTests.cs
+++ b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySavePropertyBuilderTests.cs
@@ -18,7 +18,7 @@ public void SetPropertyAccessorsAndOtherValues()
{
using (TempFile file = TempFile.Create())
{
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo saveMethod);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
FieldBuilder field = type.DefineField("TestField", typeof(int), FieldAttributes.Private);
PropertyBuilder property = type.DefineProperty("TestProperty", PropertyAttributes.SpecialName | PropertyAttributes.HasDefault, typeof(int), null);
MethodBuilder getMethod = type.DefineMethod("GetMethod", MethodAttributes.Public | MethodAttributes.HideBySig, typeof(int), null);
@@ -44,29 +44,32 @@ public void SetPropertyAccessorsAndOtherValues()
otherILGenerator.Emit(OpCodes.Ret);
property.AddOtherMethod(otherMethod);
type.CreateType();
- saveMethod.Invoke(ab, new [] { file.Path });
-
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
- PropertyInfo propertyFromDisk = typeFromDisk.GetProperty("TestProperty", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
- MethodInfo getMethodFromFile = propertyFromDisk.GetGetMethod(true);
- MethodInfo setMethodFromFile = propertyFromDisk.GetSetMethod(true);
- Assert.Equal(getMethod.Name, getMethodFromFile.Name);
- Assert.Equal(setMethod.Name, setMethodFromFile.Name);
- // Not sure how other methods should have loaded/tested
- // 'propertyFromDisk.GetAccessors(true)' did not return other method
- Assert.NotNull(typeFromDisk.GetMethod("OtherMethod", BindingFlags.NonPublic | BindingFlags.Instance));
- Assert.True(property.CanRead);
- Assert.True(property.CanWrite);
- Assert.Equal(property.CanRead, propertyFromDisk.CanRead);
- Assert.Equal(property.CanWrite, propertyFromDisk.CanWrite);
- Assert.Equal(property.Attributes, propertyFromDisk.Attributes);
- Assert.Equal(property.DeclaringType.FullName, propertyFromDisk.DeclaringType.FullName);
- IList caData = propertyFromDisk.GetCustomAttributesData();
- Assert.Equal(1, caData.Count);
- Assert.Equal(typeof(IntPropertyAttribute).FullName, caData[0].AttributeType.FullName);
- Assert.Equal(1, caData[0].ConstructorArguments.Count);
- Assert.Equal(9, caData[0].ConstructorArguments[0].Value);
+ ab.Save(file.Path);
+
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
+ {
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
+ PropertyInfo propertyFromDisk = typeFromDisk.GetProperty("TestProperty", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
+ MethodInfo getMethodFromFile = propertyFromDisk.GetGetMethod(true);
+ MethodInfo setMethodFromFile = propertyFromDisk.GetSetMethod(true);
+ Assert.Equal(getMethod.Name, getMethodFromFile.Name);
+ Assert.Equal(setMethod.Name, setMethodFromFile.Name);
+ // Not sure how other methods should have loaded/tested
+ // 'propertyFromDisk.GetAccessors(true)' did not return other method
+ Assert.NotNull(typeFromDisk.GetMethod("OtherMethod", BindingFlags.NonPublic | BindingFlags.Instance));
+ Assert.True(property.CanRead);
+ Assert.True(property.CanWrite);
+ Assert.Equal(property.CanRead, propertyFromDisk.CanRead);
+ Assert.Equal(property.CanWrite, propertyFromDisk.CanWrite);
+ Assert.Equal(property.Attributes, propertyFromDisk.Attributes);
+ Assert.Equal(property.DeclaringType.FullName, propertyFromDisk.DeclaringType.FullName);
+ IList caData = propertyFromDisk.GetCustomAttributesData();
+ Assert.Equal(1, caData.Count);
+ Assert.Equal(typeof(IntPropertyAttribute).FullName, caData[0].AttributeType.FullName);
+ Assert.Equal(1, caData[0].ConstructorArguments.Count);
+ Assert.Equal(9, caData[0].ConstructorArguments[0].Value);
+ }
}
}
@@ -81,7 +84,7 @@ public void SetVariousCustomAttributes_ForProperty()
PropertyInfo prop = typeof(CustomAttributeBuilder).GetProperty("Data", BindingFlags.NonPublic | BindingFlags.Instance);
byte[] binaryData = (byte[])prop.GetValue(customAttrBuilder, null);
- AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderTypeBuilderAndSaveMethod(out TypeBuilder type, out MethodInfo saveMethod);
+ AssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type);
PropertyBuilder property = type.DefineProperty("TestProperty", PropertyAttributes.HasDefault, typeof(int), null);
property.SetCustomAttribute(con, binaryData);
property.SetCustomAttribute(new CustomAttributeBuilder(typeof(SpecialNameAttribute).GetConstructor(Type.EmptyTypes), []));
@@ -93,30 +96,33 @@ public void SetVariousCustomAttributes_ForProperty()
methodILGenerator.Emit(OpCodes.Ret);
property.SetGetMethod(method);
type.CreateType();
- saveMethod.Invoke(ab, [file.Path]);
-
- Assembly assemblyFromDisk = AssemblySaveTools.LoadAssemblyFromPath(file.Path);
- Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
- PropertyInfo propertyFromDisk = typeFromDisk.GetProperty("TestProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
- Assert.True(propertyFromDisk.Attributes.HasFlag(PropertyAttributes.SpecialName));
- IList attributes = propertyFromDisk.GetCustomAttributesData();
- Assert.Equal(2, attributes.Count);
- if (typeof(MaybeNullAttribute).FullName == attributes[0].AttributeType.FullName)
- {
- Assert.Equal(0, attributes[0].ConstructorArguments.Count);
- Assert.Equal(1, attributes[1].ConstructorArguments.Count);
- Assert.Equal(typeof(IntPropertyAttribute).FullName, attributes[1].AttributeType.FullName);
- Assert.Equal(expectedValue, attributes[1].ConstructorArguments[0].Value);
- }
- else
+ ab.Save(file.Path);
+
+ using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
{
- Assert.Equal(0, attributes[1].ConstructorArguments.Count);
- Assert.Equal(1, attributes[0].ConstructorArguments.Count);
- Assert.Equal(typeof(IntPropertyAttribute).FullName, attributes[0].AttributeType.FullName);
- Assert.Equal(expectedValue, attributes[0].ConstructorArguments[0].Value);
+ Assembly assemblyFromDisk = mlc.LoadFromAssemblyPath(file.Path);
+ Type typeFromDisk = assemblyFromDisk.Modules.First().GetType("MyType");
+ PropertyInfo propertyFromDisk = typeFromDisk.GetProperty("TestProperty", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
+ Assert.True(propertyFromDisk.Attributes.HasFlag(PropertyAttributes.SpecialName));
+ IList attributes = propertyFromDisk.GetCustomAttributesData();
+ Assert.Equal(2, attributes.Count);
+ if (typeof(MaybeNullAttribute).FullName == attributes[0].AttributeType.FullName)
+ {
+ Assert.Equal(0, attributes[0].ConstructorArguments.Count);
+ Assert.Equal(1, attributes[1].ConstructorArguments.Count);
+ Assert.Equal(typeof(IntPropertyAttribute).FullName, attributes[1].AttributeType.FullName);
+ Assert.Equal(expectedValue, attributes[1].ConstructorArguments[0].Value);
+ }
+ else
+ {
+ Assert.Equal(0, attributes[1].ConstructorArguments.Count);
+ Assert.Equal(1, attributes[0].ConstructorArguments.Count);
+ Assert.Equal(typeof(IntPropertyAttribute).FullName, attributes[0].AttributeType.FullName);
+ Assert.Equal(expectedValue, attributes[0].ConstructorArguments[0].Value);
+ }
+ Assert.Empty(attributes[0].NamedArguments);
+ Assert.Empty(attributes[1].NamedArguments);
}
- Assert.Empty(attributes[0].NamedArguments);
- Assert.Empty(attributes[1].NamedArguments);
}
}
@@ -149,7 +155,7 @@ public static IEnumerable