Skip to content

Commit 8e1904c

Browse files
authored
Add/update AssemblyBuilder/PersistedAssemblyBuilder tests covering boundary / edge case scenarios (#105782)
1 parent 51e99e1 commit 8e1904c

File tree

15 files changed

+540
-54
lines changed

15 files changed

+540
-54
lines changed

src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimePropertyBuilder.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ internal RuntimePropertyBuilder(
2929
RuntimeModuleBuilder mod, // the module containing this PropertyBuilder
3030
string name, // property name
3131
PropertyAttributes attr, // property attribute such as DefaultProperty, Bindable, DisplayBind, etc
32-
Type returnType, // return type of the property.
32+
Type? returnType, // return type of the property.
3333
int prToken, // the metadata token for this property
3434
RuntimeTypeBuilder containingType) // the containing type
3535
{
@@ -40,7 +40,7 @@ internal RuntimePropertyBuilder(
4040
m_name = name;
4141
m_moduleBuilder = mod;
4242
m_attributes = attr;
43-
m_returnType = returnType;
43+
m_returnType = returnType ?? typeof(void);
4444
m_tkProperty = prToken;
4545
m_containingType = containingType;
4646
}

src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeTypeBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1388,7 +1388,7 @@ protected override FieldBuilder DefineUninitializedDataCore(string name, int siz
13881388
#region Define Properties and Events
13891389

13901390
protected override PropertyBuilder DefinePropertyCore(string name, PropertyAttributes attributes, CallingConventions callingConvention,
1391-
Type returnType, Type[]? returnTypeRequiredCustomModifiers, Type[]? returnTypeOptionalCustomModifiers,
1391+
Type? returnType, Type[]? returnTypeRequiredCustomModifiers, Type[]? returnTypeOptionalCustomModifiers,
13921392
Type[]? parameterTypes, Type[][]? parameterTypeRequiredCustomModifiers, Type[][]? parameterTypeOptionalCustomModifiers)
13931393
{
13941394
lock (SyncRoot)

src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -225,22 +225,22 @@ protected abstract MethodBuilder DefinePInvokeMethodCore(string name, string dll
225225
Type[]? parameterTypes, Type[][]? parameterTypeRequiredCustomModifiers, Type[][]? parameterTypeOptionalCustomModifiers,
226226
CallingConvention nativeCallConv, CharSet nativeCharSet);
227227

228-
public PropertyBuilder DefineProperty(string name, PropertyAttributes attributes, Type returnType, Type[]? parameterTypes)
228+
public PropertyBuilder DefineProperty(string name, PropertyAttributes attributes, Type? returnType, Type[]? parameterTypes)
229229
=> DefineProperty(name, attributes, returnType, null, null, parameterTypes, null, null);
230230

231231
public PropertyBuilder DefineProperty(string name, PropertyAttributes attributes,
232-
CallingConventions callingConvention, Type returnType, Type[]? parameterTypes)
232+
CallingConventions callingConvention, Type? returnType, Type[]? parameterTypes)
233233
=> DefineProperty(name, attributes, callingConvention, returnType, null, null, parameterTypes, null, null);
234234

235235
public PropertyBuilder DefineProperty(string name, PropertyAttributes attributes,
236-
Type returnType, Type[]? returnTypeRequiredCustomModifiers, Type[]? returnTypeOptionalCustomModifiers,
236+
Type? returnType, Type[]? returnTypeRequiredCustomModifiers, Type[]? returnTypeOptionalCustomModifiers,
237237
Type[]? parameterTypes, Type[][]? parameterTypeRequiredCustomModifiers, Type[][]? parameterTypeOptionalCustomModifiers)
238238
=> DefineProperty(name, attributes, default,
239239
returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers,
240240
parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers);
241241

242242
public PropertyBuilder DefineProperty(string name, PropertyAttributes attributes, CallingConventions callingConvention,
243-
Type returnType, Type[]? returnTypeRequiredCustomModifiers, Type[]? returnTypeOptionalCustomModifiers,
243+
Type? returnType, Type[]? returnTypeRequiredCustomModifiers, Type[]? returnTypeOptionalCustomModifiers,
244244
Type[]? parameterTypes, Type[][]? parameterTypeRequiredCustomModifiers, Type[][]? parameterTypeOptionalCustomModifiers)
245245
{
246246
ArgumentException.ThrowIfNullOrEmpty(name);
@@ -251,7 +251,7 @@ public PropertyBuilder DefineProperty(string name, PropertyAttributes attributes
251251
}
252252

253253
protected abstract PropertyBuilder DefinePropertyCore(string name, PropertyAttributes attributes, CallingConventions callingConvention,
254-
Type returnType, Type[]? returnTypeRequiredCustomModifiers, Type[]? returnTypeOptionalCustomModifiers,
254+
Type? returnType, Type[]? returnTypeRequiredCustomModifiers, Type[]? returnTypeOptionalCustomModifiers,
255255
Type[]? parameterTypes, Type[][]? parameterTypeRequiredCustomModifiers, Type[][]? parameterTypeOptionalCustomModifiers);
256256

257257
public ConstructorBuilder DefineTypeInitializer()

src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -608,11 +608,11 @@ public void DefineMethodOverride(System.Reflection.MethodInfo methodInfoBody, Sy
608608
public System.Reflection.Emit.MethodBuilder DefinePInvokeMethod(string name, string dllName, string entryName, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, System.Type? returnType, System.Type[]? returnTypeRequiredCustomModifiers, System.Type[]? returnTypeOptionalCustomModifiers, System.Type[]? parameterTypes, System.Type[][]? parameterTypeRequiredCustomModifiers, System.Type[][]? parameterTypeOptionalCustomModifiers, System.Runtime.InteropServices.CallingConvention nativeCallConv, System.Runtime.InteropServices.CharSet nativeCharSet) { throw null; }
609609
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("P/Invoke marshalling may dynamically access members that could be trimmed.")]
610610
protected abstract System.Reflection.Emit.MethodBuilder DefinePInvokeMethodCore(string name, string dllName, string entryName, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, System.Type? returnType, System.Type[]? returnTypeRequiredCustomModifiers, System.Type[]? returnTypeOptionalCustomModifiers, System.Type[]? parameterTypes, System.Type[][]? parameterTypeRequiredCustomModifiers, System.Type[][]? parameterTypeOptionalCustomModifiers, System.Runtime.InteropServices.CallingConvention nativeCallConv, System.Runtime.InteropServices.CharSet nativeCharSet);
611-
public System.Reflection.Emit.PropertyBuilder DefineProperty(string name, System.Reflection.PropertyAttributes attributes, System.Reflection.CallingConventions callingConvention, System.Type returnType, System.Type[]? parameterTypes) { throw null; }
612-
public System.Reflection.Emit.PropertyBuilder DefineProperty(string name, System.Reflection.PropertyAttributes attributes, System.Reflection.CallingConventions callingConvention, System.Type returnType, System.Type[]? returnTypeRequiredCustomModifiers, System.Type[]? returnTypeOptionalCustomModifiers, System.Type[]? parameterTypes, System.Type[][]? parameterTypeRequiredCustomModifiers, System.Type[][]? parameterTypeOptionalCustomModifiers) { throw null; }
613-
public System.Reflection.Emit.PropertyBuilder DefineProperty(string name, System.Reflection.PropertyAttributes attributes, System.Type returnType, System.Type[]? parameterTypes) { throw null; }
614-
public System.Reflection.Emit.PropertyBuilder DefineProperty(string name, System.Reflection.PropertyAttributes attributes, System.Type returnType, System.Type[]? returnTypeRequiredCustomModifiers, System.Type[]? returnTypeOptionalCustomModifiers, System.Type[]? parameterTypes, System.Type[][]? parameterTypeRequiredCustomModifiers, System.Type[][]? parameterTypeOptionalCustomModifiers) { throw null; }
615-
protected abstract System.Reflection.Emit.PropertyBuilder DefinePropertyCore(string name, System.Reflection.PropertyAttributes attributes, System.Reflection.CallingConventions callingConvention, System.Type returnType, System.Type[]? returnTypeRequiredCustomModifiers, System.Type[]? returnTypeOptionalCustomModifiers, System.Type[]? parameterTypes, System.Type[][]? parameterTypeRequiredCustomModifiers, System.Type[][]? parameterTypeOptionalCustomModifiers);
611+
public System.Reflection.Emit.PropertyBuilder DefineProperty(string name, System.Reflection.PropertyAttributes attributes, System.Reflection.CallingConventions callingConvention, System.Type? returnType, System.Type[]? parameterTypes) { throw null; }
612+
public System.Reflection.Emit.PropertyBuilder DefineProperty(string name, System.Reflection.PropertyAttributes attributes, System.Reflection.CallingConventions callingConvention, System.Type? returnType, System.Type[]? returnTypeRequiredCustomModifiers, System.Type[]? returnTypeOptionalCustomModifiers, System.Type[]? parameterTypes, System.Type[][]? parameterTypeRequiredCustomModifiers, System.Type[][]? parameterTypeOptionalCustomModifiers) { throw null; }
613+
public System.Reflection.Emit.PropertyBuilder DefineProperty(string name, System.Reflection.PropertyAttributes attributes, System.Type? returnType, System.Type[]? parameterTypes) { throw null; }
614+
public System.Reflection.Emit.PropertyBuilder DefineProperty(string name, System.Reflection.PropertyAttributes attributes, System.Type? returnType, System.Type[]? returnTypeRequiredCustomModifiers, System.Type[]? returnTypeOptionalCustomModifiers, System.Type[]? parameterTypes, System.Type[][]? parameterTypeRequiredCustomModifiers, System.Type[][]? parameterTypeOptionalCustomModifiers) { throw null; }
615+
protected abstract System.Reflection.Emit.PropertyBuilder DefinePropertyCore(string name, System.Reflection.PropertyAttributes attributes, System.Reflection.CallingConventions callingConvention, System.Type? returnType, System.Type[]? returnTypeRequiredCustomModifiers, System.Type[]? returnTypeOptionalCustomModifiers, System.Type[]? parameterTypes, System.Type[][]? parameterTypeRequiredCustomModifiers, System.Type[][]? parameterTypeOptionalCustomModifiers);
616616
public System.Reflection.Emit.ConstructorBuilder DefineTypeInitializer() { throw null; }
617617
protected abstract System.Reflection.Emit.ConstructorBuilder DefineTypeInitializerCore();
618618
public System.Reflection.Emit.FieldBuilder DefineUninitializedData(string name, int size, System.Reflection.FieldAttributes attributes) { throw null; }

src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/PropertyBuilderImpl.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,14 @@ internal sealed class PropertyBuilderImpl : PropertyBuilder
2626
internal List<CustomAttributeWrapper>? _customAttributes;
2727
internal object? _defaultValue = DBNull.Value;
2828

29-
internal PropertyBuilderImpl(string name, PropertyAttributes attributes, CallingConventions callingConvention, Type returnType, Type[]? returnTypeRequiredCustomModifiers, Type[]? returnTypeOptionalCustomModifiers, Type[]? parameterTypes, Type[][]? parameterTypeRequiredCustomModifiers, Type[][]? parameterTypeOptionalCustomModifiers, TypeBuilderImpl containingType)
29+
internal PropertyBuilderImpl(string name, PropertyAttributes attributes, CallingConventions callingConvention, Type? returnType, Type[]? returnTypeRequiredCustomModifiers, Type[]? returnTypeOptionalCustomModifiers, Type[]? parameterTypes, Type[][]? parameterTypeRequiredCustomModifiers, Type[][]? parameterTypeOptionalCustomModifiers, TypeBuilderImpl containingType)
3030
{
3131
ArgumentException.ThrowIfNullOrEmpty(name);
3232

3333
_name = name;
3434
_attributes = attributes;
3535
_callingConvention = callingConvention;
36-
_propertyType = returnType;
36+
_propertyType = returnType ?? containingType.GetModuleBuilder().GetTypeFromCoreAssembly(CoreTypeId.Void);
3737
_parameterTypes = parameterTypes;
3838
_containingType = containingType;
3939
_returnTypeRequiredCustomModifiers = returnTypeRequiredCustomModifiers;

src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/TypeBuilderImpl.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ protected override MethodBuilder DefinePInvokeMethodCore(string name, string dll
408408
}
409409

410410
protected override PropertyBuilder DefinePropertyCore(string name, PropertyAttributes attributes, CallingConventions callingConvention,
411-
Type returnType, Type[]? returnTypeRequiredCustomModifiers, Type[]? returnTypeOptionalCustomModifiers, Type[]? parameterTypes,
411+
Type? returnType, Type[]? returnTypeRequiredCustomModifiers, Type[]? returnTypeOptionalCustomModifiers, Type[]? parameterTypes,
412412
Type[][]? parameterTypeRequiredCustomModifiers, Type[][]? parameterTypeOptionalCustomModifiers)
413413
{
414414
PropertyBuilderImpl property = new PropertyBuilderImpl(name, attributes, callingConvention, returnType, returnTypeRequiredCustomModifiers,

src/libraries/System.Reflection.Emit/tests/ModuleBuilder/ModuleBuilderDefineEnum.cs

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System.Collections.Generic;
5-
using System.Runtime.InteropServices;
5+
using System.IO;
66
using Xunit;
77

88
namespace System.Reflection.Emit.Tests
@@ -18,13 +18,13 @@ public static IEnumerable<object[]> DefineEnum_TestData()
1818
yield return new object[] { "a\0b\0c", TypeAttributes.Public, typeof(int) };
1919
yield return new object[] { "Name", TypeAttributes.Public, typeof(uint) };
2020
yield return new object[] { "Name", TypeAttributes.Public, typeof(long) };
21-
yield return new object[] { "Name", TypeAttributes.Public, typeof(char) };
22-
yield return new object[] { "Name", TypeAttributes.Public, typeof(bool) };
23-
yield return new object[] { "Name", TypeAttributes.Public, typeof(ulong) };
21+
yield return new object[] { "N%ame", TypeAttributes.Public, typeof(char) };
22+
yield return new object[] { "N`ame", TypeAttributes.Public, typeof(bool) };
23+
yield return new object[] { "N'ame", TypeAttributes.Public, typeof(ulong) };
2424
yield return new object[] { "Name", TypeAttributes.Public, typeof(float) };
25-
yield return new object[] { "Name", TypeAttributes.Public, typeof(double) };
26-
yield return new object[] { "Name", TypeAttributes.Public, typeof(IntPtr) };
27-
yield return new object[] { "Name", TypeAttributes.Public, typeof(UIntPtr) };
25+
yield return new object[] { "Nam<e>", TypeAttributes.Public, typeof(double) };
26+
yield return new object[] { "Nam~e", TypeAttributes.Public, typeof(IntPtr) };
27+
yield return new object[] { "\rName", TypeAttributes.Public, typeof(UIntPtr) };
2828
yield return new object[] { "Name", TypeAttributes.Public, typeof(Int32Enum) };
2929
}
3030

@@ -76,6 +76,45 @@ public void DefineEnum(string name, TypeAttributes visibility, Type underlyingTy
7676
Assert.Equal(FieldAttributes.Public | FieldAttributes.SpecialName | FieldAttributes.RTSpecialName, createdUnderlyingField.Attributes);
7777
}
7878

79+
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))]
80+
[MemberData(nameof(DefineEnum_TestData))]
81+
public void DefineEnumPersistedAssembly(string name, TypeAttributes visibility, Type underlyingType)
82+
{
83+
PersistedAssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilder(new AssemblyName("MyAssembly"));
84+
ModuleBuilder module = ab.DefineDynamicModule("MyModule");
85+
EnumBuilder enumBuilder = module.DefineEnum(name, visibility, underlyingType);
86+
enumBuilder.CreateType();
87+
88+
Assert.True(enumBuilder.IsEnum);
89+
Assert.Equal(module.Assembly, enumBuilder.Assembly);
90+
Assert.Equal(module, enumBuilder.Module);
91+
Assert.Equal(name, enumBuilder.Name);
92+
Assert.Equal(Helpers.GetFullName(name), enumBuilder.FullName);
93+
Assert.Equal(typeof(Enum), enumBuilder.BaseType);
94+
Assert.Null(enumBuilder.DeclaringType);
95+
Assert.Equal(visibility | TypeAttributes.Sealed, enumBuilder.Attributes);
96+
Assert.Equal("value__", enumBuilder.UnderlyingField.Name);
97+
Assert.Equal(underlyingType, enumBuilder.UnderlyingField.FieldType);
98+
Assert.Equal(FieldAttributes.Public | FieldAttributes.SpecialName, enumBuilder.UnderlyingField.Attributes);
99+
100+
using (var stream = new MemoryStream())
101+
using (MetadataLoadContext mlc = new MetadataLoadContext(new CoreMetadataAssemblyResolver()))
102+
{
103+
ab.Save(stream);
104+
Assembly assemblyFromStream = mlc.LoadFromStream(stream);
105+
Type createdEnum = assemblyFromStream.GetType(name);
106+
if (createdEnum != null) // null when name = "a\0b\0c"
107+
{
108+
Assert.True(createdEnum.IsEnum);
109+
Assert.Equal(Helpers.GetFullName(name), createdEnum.Name);
110+
Assert.Equal(Helpers.GetFullName(name), enumBuilder.FullName);
111+
Assert.Equal(typeof(Enum).FullName, createdEnum.BaseType.FullName);
112+
Assert.Null(createdEnum.DeclaringType);
113+
Assert.Equal(visibility | TypeAttributes.Sealed, createdEnum.Attributes);
114+
}
115+
}
116+
}
117+
79118
[Fact]
80119
[ActiveIssue("https://github.com/dotnet/runtime/issues/2389", TestRuntimes.Mono)]
81120
public void DefineEnum_DynamicUnderlyingType_Works()

0 commit comments

Comments
 (0)