Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix some core typeof(...) references #105903

Merged
merged 3 commits into from
Aug 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ internal sealed class ArrayMethod : MethodInfo

#region Constructor
// This is a kind of MethodInfo to represent methods for array type of unbaked type
internal ArrayMethod(ModuleBuilder module, Type arrayClass, string methodName,
internal ArrayMethod(ModuleBuilderImpl module, Type arrayClass, string methodName,
CallingConventions callingConvention, Type? returnType, Type[]? parameterTypes)
{
_returnType = returnType ?? typeof(void);
_returnType = returnType ?? module.GetTypeFromCoreAssembly(CoreTypeId.Void);
if (parameterTypes != null)
{
_parameterTypes = new Type[parameterTypes.Length];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,7 @@ protected override FieldBuilder DefineUninitializedDataCore(string name, int siz
return DefineDataHelper(name, new byte[size], size, attributes);
}

[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2072:DynamicallyAccessedMembers", Justification = "The members of 'ValueType' are not referenced in this context")]
private FieldBuilder DefineDataHelper(string name, byte[] data, int size, FieldAttributes attributes)
{
ArgumentException.ThrowIfNullOrEmpty(name);
Expand All @@ -456,7 +457,7 @@ private FieldBuilder DefineDataHelper(string name, byte[] data, int size, FieldA
TypeAttributes typeAttributes = TypeAttributes.Public | TypeAttributes.ExplicitLayout | TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.AnsiClass;

// Define the backing value class
valueClassType = (TypeBuilderImpl)_module.DefineType(strValueClassName, typeAttributes, typeof(ValueType), PackingSize.Size1, size);
valueClassType = (TypeBuilderImpl)_module.DefineType(strValueClassName, typeAttributes, _module.GetTypeFromCoreAssembly(CoreTypeId.ValueType), PackingSize.Size1, size);
valueClassType.CreateType();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public void DefineLiteral(Type underlyingType, object literalValue)
EnumBuilder enumBuilder = CreateAssemblyAndDefineEnum(out PersistedAssemblyBuilder assemblyBuilder, out TypeBuilder type, underlyingType);
FieldBuilder literal = enumBuilder.DefineLiteral("FieldOne", literalValue);
enumBuilder.CreateTypeInfo();
Assert.True(enumBuilder.IsEnum);
type.CreateTypeInfo();
assemblyBuilder.Save(file.Path);

Expand All @@ -79,15 +80,49 @@ public void DefineLiteral(Type underlyingType, object literalValue)
Assert.True(testEnum.IsEnum);
AssemblySaveTools.AssertTypeProperties(enumBuilder, testEnum);
Assert.Equal(underlyingType.FullName, testEnum.GetEnumUnderlyingType().FullName);
Assert.Equal(mlc.CoreAssembly.GetType("System.Enum"), testEnum.BaseType);

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);
Assert.Equal(testEnum, testField.FieldType);
}
}
}

[Fact]
public void CreateEnumWithMlc()
{
using (var stream = new MemoryStream())
using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
{
PersistedAssemblyBuilder ab = new PersistedAssemblyBuilder(PopulateAssemblyName(), mlc.CoreAssembly);
ModuleBuilder mb = ab.DefineDynamicModule("My Module");
Type intType = mlc.CoreAssembly.GetType("System.Int32");
EnumBuilder enumBuilder = mb.DefineEnum("TestEnum", TypeAttributes.Public, typeof(int));
FieldBuilder field = enumBuilder.DefineLiteral("Default", 0);

enumBuilder.CreateTypeInfo();
Assert.True(enumBuilder.IsEnum);
Assert.Equal(enumBuilder, field.FieldType);

ab.Save(stream);
Assembly assemblyFromStream = mlc.LoadFromStream(stream);
Type createdEnum = assemblyFromStream.GetType("TestEnum");

Assert.True(createdEnum.IsEnum);
AssemblySaveTools.AssertTypeProperties(enumBuilder, createdEnum);
Assert.Equal(mlc.CoreAssembly.GetType("System.Enum"), createdEnum.BaseType);
Assert.Equal(intType, createdEnum.GetEnumUnderlyingType());

FieldInfo testField = createdEnum.GetField("Default");
Assert.Equal(createdEnum, testField.FieldType);
Assert.Equal(typeof(int), enumBuilder.GetEnumUnderlyingType());
Assert.Equal(FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal | FieldAttributes.HasDefault, testField.Attributes);
}
}

[Theory]
[InlineData(0, "TestEnum[]")]
[InlineData(1, "TestEnum[]")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,25 @@ public void DefineUninitializedDataTest(FieldAttributes attributes)
Assert.True(field.IsStatic);
Assert.True((field.Attributes & FieldAttributes.HasFieldRVA) != 0);
Assert.Equal(attributes | FieldAttributes.Static | FieldAttributes.HasFieldRVA, field.Attributes);
Assert.Equal(typeof(ValueType), field.FieldType.BaseType);
}
}

[Fact]
public void DefineUninitializedDataFromMLC()
{
using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
{
PersistedAssemblyBuilder ab = new PersistedAssemblyBuilder(new AssemblyName("MyAssembly"), mlc.CoreAssembly);
ModuleBuilder module = ab.DefineDynamicModule("MyModule");
FieldBuilder field = module.DefineUninitializedData("UninitializedDataField", 100, FieldAttributes.Public);

Assert.Equal("UninitializedDataField", field.Name);
Assert.True(field.IsStatic);
Assert.True((field.Attributes & FieldAttributes.HasFieldRVA) != 0);
Assert.Equal(FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.HasFieldRVA, field.Attributes);
Assert.NotEqual(typeof(ValueType), field.FieldType.BaseType);
Assert.Equal(mlc.CoreAssembly.GetType("System.ValueType"), field.FieldType.BaseType);
}
}

Expand Down Expand Up @@ -354,5 +373,34 @@ public void GetArrayMethod_InvalidArgument_ThrowsArgumentException()
AssertExtensions.Throws<ArgumentNullException>("parameterTypes", () => module.GetArrayMethod(typeof(string[]), "TestMethod", CallingConventions.Standard, null, [null]));
AssertExtensions.Throws<ArgumentException>(null, () => module.GetArrayMethod(typeof(Array), "TestMethod", CallingConventions.Standard, null, null));
}

[Fact]
public void GetArrayMethodNullReturnType()
{
ModuleBuilder module = AssemblySaveTools.PopulateAssemblyBuilder(new AssemblyName("MyAssembly")).DefineDynamicModule("MyModule");
MethodInfo method = module.GetArrayMethod(typeof(int[]), "MethodName", CallingConventions.Standard, null, null);

Assert.Equal(typeof(int[]), method.DeclaringType);
Assert.Equal("MethodName", method.Name);
Assert.Equal(CallingConventions.Standard, method.CallingConvention);
Assert.Equal(typeof(void), method.ReturnType);
}

[Fact]
public void GetArrayMethodNullReturnTypeFromMLC()
{
using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
{
ModuleBuilder module = new PersistedAssemblyBuilder(new AssemblyName("MyAssembly"), mlc.CoreAssembly).DefineDynamicModule("MyModule");
Type arrayType = mlc.CoreAssembly.GetType("System.Int32").MakeArrayType();
MethodInfo method = module.GetArrayMethod(arrayType, "MethodName", CallingConventions.Standard, null, null);

Assert.Equal(arrayType, method.DeclaringType);
Assert.Equal("MethodName", method.Name);
Assert.Equal(CallingConventions.Standard, method.CallingConvention);
Assert.NotEqual(typeof(void), method.ReturnType);
Assert.Equal(mlc.CoreAssembly.GetType("System.Void"), method.ReturnType);
}
}
}
}
Loading