diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs index 1ca07d381f96df..01c2826ab6bf5d 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs @@ -66,8 +66,8 @@ public void Bake(ModuleBuilder module, int token) Justification = "MakeGenericType is only called on a TypeBuilder which is not subject to trimming")] public static MethodInfo GetMethod(Type type, MethodInfo method) { - if (!(type is TypeBuilder) && !(type is TypeBuilderInstantiation)) - throw new ArgumentException(SR.Argument_MustBeTypeBuilder); + if (type is not TypeBuilder && type is not TypeBuilderInstantiation) + throw new ArgumentException(SR.Argument_MustBeTypeBuilder, nameof(type)); // The following checks establishes invariants that more simply put require type to be generic and // method to be a generic method definition declared on the generic type definition of type. @@ -91,56 +91,56 @@ public static MethodInfo GetMethod(Type type, MethodInfo method) if (type.IsGenericTypeDefinition) type = type.MakeGenericType(type.GetGenericArguments()); - if (!(type is TypeBuilderInstantiation)) + if (type is not TypeBuilderInstantiation typeBuilderInstantiation) throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(type)); - return MethodOnTypeBuilderInstantiation.GetMethod(method, (type as TypeBuilderInstantiation)!); + return MethodOnTypeBuilderInstantiation.GetMethod(method, typeBuilderInstantiation); } [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2055:UnrecognizedReflectionPattern", Justification = "MakeGenericType is only called on a TypeBuilder which is not subject to trimming")] public static ConstructorInfo GetConstructor(Type type, ConstructorInfo constructor) { - if (!(type is TypeBuilder) && !(type is TypeBuilderInstantiation)) - throw new ArgumentException(SR.Argument_MustBeTypeBuilder); + if (type is not TypeBuilder && type is not TypeBuilderInstantiation) + throw new ArgumentException(SR.Argument_MustBeTypeBuilder, nameof(type)); if (!constructor.DeclaringType!.IsGenericTypeDefinition) throw new ArgumentException(SR.Argument_ConstructorNeedGenericDeclaringType, nameof(constructor)); - if (!(type is TypeBuilderInstantiation)) - throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(type)); + if (type.GetGenericTypeDefinition() != constructor.DeclaringType) + throw new ArgumentException(SR.Argument_InvalidConstructorDeclaringType, nameof(type)); // TypeBuilder G ==> TypeBuilderInstantiation G - if (type is TypeBuilder && type.IsGenericTypeDefinition) + if (type.IsGenericTypeDefinition) type = type.MakeGenericType(type.GetGenericArguments()); - if (type.GetGenericTypeDefinition() != constructor.DeclaringType) - throw new ArgumentException(SR.Argument_InvalidConstructorDeclaringType, nameof(type)); + if (type is not TypeBuilderInstantiation typeBuilderInstantiation) + throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(type)); - return ConstructorOnTypeBuilderInstantiation.GetConstructor(constructor, (type as TypeBuilderInstantiation)!); + return ConstructorOnTypeBuilderInstantiation.GetConstructor(constructor, typeBuilderInstantiation); } [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2055:UnrecognizedReflectionPattern", Justification = "MakeGenericType is only called on a TypeBuilder which is not subject to trimming")] public static FieldInfo GetField(Type type, FieldInfo field) { - if (!(type is TypeBuilder) && !(type is TypeBuilderInstantiation)) - throw new ArgumentException(SR.Argument_MustBeTypeBuilder); + if (type is not TypeBuilder and not TypeBuilderInstantiation) + throw new ArgumentException(SR.Argument_MustBeTypeBuilder, nameof(type)); if (!field.DeclaringType!.IsGenericTypeDefinition) throw new ArgumentException(SR.Argument_FieldNeedGenericDeclaringType, nameof(field)); - if (!(type is TypeBuilderInstantiation)) - throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(type)); + if (type.GetGenericTypeDefinition() != field.DeclaringType) + throw new ArgumentException(SR.Argument_InvalidFieldDeclaringType, nameof(type)); // TypeBuilder G ==> TypeBuilderInstantiation G - if (type is TypeBuilder && type.IsGenericTypeDefinition) + if (type.IsGenericTypeDefinition) type = type.MakeGenericType(type.GetGenericArguments()); - if (type.GetGenericTypeDefinition() != field.DeclaringType) - throw new ArgumentException(SR.Argument_InvalidFieldDeclaringType, nameof(type)); + if (type is not TypeBuilderInstantiation typeBuilderInstantiation) + throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(type)); - return FieldOnTypeBuilderInstantiation.GetField(field, (type as TypeBuilderInstantiation)!); + return FieldOnTypeBuilderInstantiation.GetField(field, typeBuilderInstantiation); } #endregion diff --git a/src/libraries/System.Reflection.Emit/tests/TypeBuilder/TypeBuilderGetConstructor.cs b/src/libraries/System.Reflection.Emit/tests/TypeBuilder/TypeBuilderGetConstructor.cs index 2006e926e896a4..f9c9f4dce579c8 100644 --- a/src/libraries/System.Reflection.Emit/tests/TypeBuilder/TypeBuilderGetConstructor.cs +++ b/src/libraries/System.Reflection.Emit/tests/TypeBuilder/TypeBuilderGetConstructor.cs @@ -8,14 +8,14 @@ namespace System.Reflection.Emit.Tests public class TypeBuilderGetConstructor { [Fact] - public void GetConstructor_DeclaringTypeOfConstructorNotGenericTypeDefinition_ThrowsArgumentException() + public void GetConstructor_DeclaringTypeOfConstructorGenericTypeDefinition() { TypeBuilder type = Helpers.DynamicType(TypeAttributes.Class | TypeAttributes.Public); type.DefineGenericParameters("T"); ConstructorBuilder ctor = type.DefineDefaultConstructor(MethodAttributes.PrivateScope | MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName); - - AssertExtensions.Throws("type", () => TypeBuilder.GetConstructor(type.AsType(), ctor)); + var constructor = TypeBuilder.GetConstructor(type.AsType(), ctor); + Assert.False(constructor.IsGenericMethodDefinition); } [Fact] @@ -32,14 +32,12 @@ public void GetConstructor() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/2389", TestRuntimes.Mono)] public void GetConstructor_TypeNotTypeBuilder_ThrowsArgumentException() { - AssertExtensions.Throws(null, () => TypeBuilder.GetConstructor(typeof(int), typeof(int).GetConstructor(new Type[0]))); + AssertExtensions.Throws("type", () => TypeBuilder.GetConstructor(typeof(int), typeof(int).GetConstructor(new Type[0]))); } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/2389", TestRuntimes.Mono)] public void GetConstructor_DeclaringTypeOfConstructorNotGenericTypeDefinitionOfType_ThrowsArgumentException() { ModuleBuilder module = Helpers.DynamicModule(); @@ -58,7 +56,6 @@ public void GetConstructor_DeclaringTypeOfConstructorNotGenericTypeDefinitionOfT } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/2389", TestRuntimes.Mono)] public void GetConstructor_TypeNotGeneric_ThrowsArgumentException() { TypeBuilder type = Helpers.DynamicType(TypeAttributes.Class | TypeAttributes.Public); diff --git a/src/libraries/System.Reflection.Emit/tests/TypeBuilder/TypeBuilderGetField.cs b/src/libraries/System.Reflection.Emit/tests/TypeBuilder/TypeBuilderGetField.cs index 96081b7b772937..eea868726ad5b0 100644 --- a/src/libraries/System.Reflection.Emit/tests/TypeBuilder/TypeBuilderGetField.cs +++ b/src/libraries/System.Reflection.Emit/tests/TypeBuilder/TypeBuilderGetField.cs @@ -8,13 +8,13 @@ namespace System.Reflection.Emit.Tests public class TypeBuilderGetField { [Fact] - public void GetField_DeclaringTypeOfFieldNotGeneric_ThrowsArgumentException() + public void GetField_DeclaringTypeOfFieldGeneric() { TypeBuilder type = Helpers.DynamicType(TypeAttributes.Class | TypeAttributes.Public); GenericTypeParameterBuilder[] typeParams = type.DefineGenericParameters("T"); FieldBuilder field = type.DefineField("Field", typeParams[0].AsType(), FieldAttributes.Public); - AssertExtensions.Throws("type", () => TypeBuilder.GetField(type.AsType(), field)); + Assert.Equal("Field", TypeBuilder.GetField(type.AsType(), field).Name); } [Fact] @@ -32,14 +32,12 @@ public void GetField() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/2389", TestRuntimes.Mono)] public void GetField_TypeNotTypeBuilder_ThrowsArgumentException() { - AssertExtensions.Throws(null, () => TypeBuilder.GetField(typeof(int), typeof(int).GetField("MaxValue"))); + AssertExtensions.Throws("type", () => TypeBuilder.GetField(typeof(int), typeof(int).GetField("MaxValue"))); } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/2389", TestRuntimes.Mono)] public void GetField_DeclaringTypeOfFieldNotGenericTypeDefinitionOfType_ThrowsArgumentException() { ModuleBuilder module = Helpers.DynamicModule(); @@ -57,7 +55,6 @@ public void GetField_DeclaringTypeOfFieldNotGenericTypeDefinitionOfType_ThrowsAr } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/2389", TestRuntimes.Mono)] public void GetField_TypeNotGeneric_ThrowsArgumentException() { TypeBuilder type = Helpers.DynamicType(TypeAttributes.Class | TypeAttributes.Public); diff --git a/src/libraries/System.Reflection.Emit/tests/TypeBuilder/TypeBuilderGetMethod.cs b/src/libraries/System.Reflection.Emit/tests/TypeBuilder/TypeBuilderGetMethod.cs index 42d42d40f60be1..5661310a8bede0 100644 --- a/src/libraries/System.Reflection.Emit/tests/TypeBuilder/TypeBuilderGetMethod.cs +++ b/src/libraries/System.Reflection.Emit/tests/TypeBuilder/TypeBuilderGetMethod.cs @@ -41,14 +41,12 @@ public void GetMethod_ConstructedTypeMethod() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/2389", TestRuntimes.Mono)] public void GetMethod_TypeNotTypeBuilder_ThrowsArgumentException() { - AssertExtensions.Throws(null, () => TypeBuilder.GetMethod(typeof(int), typeof(int).GetMethod("Parse", new Type[] { typeof(string) }))); + AssertExtensions.Throws("type", () => TypeBuilder.GetMethod(typeof(int), typeof(int).GetMethod("Parse", new Type[] { typeof(string) }))); } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/2389", TestRuntimes.Mono)] public void GetMethod_MethodDefinitionNotInTypeGenericDefinition_ThrowsArgumentException() { TypeBuilder type = Helpers.DynamicType(TypeAttributes.Class | TypeAttributes.Public); @@ -64,7 +62,6 @@ public void GetMethod_MethodDefinitionNotInTypeGenericDefinition_ThrowsArgumentE } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/2389", TestRuntimes.Mono)] public void GetMethod_MethodNotGenericTypeDefinition_ThrowsArgumentException() { ModuleBuilder module = Helpers.DynamicModule(); @@ -87,7 +84,6 @@ public void GetMethod_MethodNotGenericTypeDefinition_ThrowsArgumentException() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/2389", TestRuntimes.Mono)] public void GetMethod_TypeIsNotGeneric_ThrowsArgumentException() { TypeBuilder type = Helpers.DynamicType(TypeAttributes.Class | TypeAttributes.Public); diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.Mono.cs index ccb6a7458a0735..1e73f98f1505f8 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.Mono.cs @@ -1845,25 +1845,21 @@ public GenericTypeParameterBuilder[] DefineGenericParameters(params string[] nam [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern", Justification = "Linker thinks Type.GetConstructor(ConstructorInfo) is one of the public APIs because it doesn't analyze method signatures. We already have ConstructorInfo.")] + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2055:UnrecognizedReflectionPattern", + Justification = "Type.MakeGenericType is used to create a typical instantiation")] public static ConstructorInfo GetConstructor(Type type, ConstructorInfo constructor) { - /*FIXME I would expect the same checks of GetMethod here*/ - if (type == null) - throw new ArgumentException("Type is not generic", nameof(type)); - - if (!type.IsGenericType) - throw new ArgumentException("Type is not a generic type", nameof(type)); - - if (type.IsGenericTypeDefinition) - throw new ArgumentException("Type cannot be a generic type definition", nameof(type)); + if (!IsValidGetMethodType(type)) + throw new ArgumentException(SR.Argument_MustBeTypeBuilder, nameof(type)); - if (constructor == null) - throw new NullReferenceException(); //MS raises this instead of an ArgumentNullException + if (type is TypeBuilder && type.ContainsGenericParameters) + type = type.MakeGenericType(type.GetGenericArguments()); if (!constructor.DeclaringType!.IsGenericTypeDefinition) - throw new ArgumentException("constructor declaring type is not a generic type definition", nameof(constructor)); + throw new ArgumentException(SR.Argument_ConstructorNeedGenericDeclaringType, nameof(constructor)); + if (constructor.DeclaringType != type.GetGenericTypeDefinition()) - throw new ArgumentException("constructor declaring type is not the generic type definition of type", nameof(constructor)); + throw new ArgumentException(SR.Argument_InvalidConstructorDeclaringType, nameof(type)); ConstructorInfo res = type.GetConstructor(constructor); if (res == null) @@ -1874,6 +1870,9 @@ public static ConstructorInfo GetConstructor(Type type, ConstructorInfo construc private static bool IsValidGetMethodType(Type type) { + if (type == null) + return false; + if (type is TypeBuilder || type is TypeBuilderInstantiation) return true; /*GetMethod() must work with TypeBuilders after CreateType() was called.*/ @@ -1898,20 +1897,19 @@ private static bool IsValidGetMethodType(Type type) public static MethodInfo GetMethod(Type type, MethodInfo method) { if (!IsValidGetMethodType(type)) - throw new ArgumentException("type is not TypeBuilder but " + type.GetType(), nameof(type)); + throw new ArgumentException(SR.Argument_MustBeTypeBuilder, nameof(type)); if (type is TypeBuilder && type.ContainsGenericParameters) type = type.MakeGenericType(type.GetGenericArguments()); - if (!type.IsGenericType) - throw new ArgumentException("type is not a generic type", nameof(type)); + if (method.IsGenericMethod && !method.IsGenericMethodDefinition) + throw new ArgumentException(SR.Argument_NeedGenericMethodDefinition, nameof(method)); if (!method.DeclaringType!.IsGenericTypeDefinition) - throw new ArgumentException("method declaring type is not a generic type definition", nameof(method)); + throw new ArgumentException(SR.Argument_MethodNeedGenericDeclaringType, nameof(method)); + if (method.DeclaringType != type.GetGenericTypeDefinition()) - throw new ArgumentException("method declaring type is not the generic type definition of type", nameof(method)); - if (method == null) - throw new NullReferenceException(); //MS raises this instead of an ArgumentNullException + throw new ArgumentException(SR.Argument_InvalidMethodDeclaringType, nameof(type)); MethodInfo res = type.GetMethod(method); if (res == null) @@ -1920,19 +1918,24 @@ public static MethodInfo GetMethod(Type type, MethodInfo method) return res; } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2055:UnrecognizedReflectionPattern", + Justification = "Type.MakeGenericType is used to create a typical instantiation")] public static FieldInfo GetField(Type type, FieldInfo field) { - if (!type.IsGenericType) - throw new ArgumentException("Type is not a generic type", nameof(type)); + if (!IsValidGetMethodType(type)) + throw new ArgumentException(SR.Argument_MustBeTypeBuilder, nameof(type)); - if (type.IsGenericTypeDefinition) - throw new ArgumentException("Type cannot be a generic type definition", nameof(type)); + if (type is TypeBuilder && type.ContainsGenericParameters) + type = type.MakeGenericType(type.GetGenericArguments()); - if (field is FieldOnTypeBuilderInst) - throw new ArgumentException("The specified field must be declared on a generic type definition.", nameof(field)); + if (!field.DeclaringType!.IsGenericTypeDefinition) + throw new ArgumentException(SR.Argument_FieldNeedGenericDeclaringType, nameof(field)); if (field.DeclaringType != type.GetGenericTypeDefinition()) - throw new ArgumentException("field declaring type is not the generic type definition of type", nameof(field)); + throw new ArgumentException(SR.Argument_InvalidFieldDeclaringType, nameof(type)); + + if (field is FieldOnTypeBuilderInst) + throw new ArgumentException("The specified field must be declared on a generic type definition.", nameof(field)); FieldInfo res = type.GetField(field); if (res == null)