From 5925fe26375d2ffde62665997bdeb180890ccddb Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Mon, 9 May 2022 06:55:58 -0700 Subject: [PATCH 1/2] Fix for issue 67533 --- .../TypeInfos/RuntimeTypeInfo.GetMember.cs | 18 ++++++++-- src/libraries/tests.proj | 2 ++ .../SmokeTests/Reflection/Reflection.cs | 33 +++++++++++++++++++ 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.GetMember.cs b/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.GetMember.cs index 9c5741413ba55d..975b72b6e72832 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.GetMember.cs +++ b/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.GetMember.cs @@ -123,6 +123,21 @@ public sealed override MemberInfo GetMemberWithSameMetadataDefinitionAs(MemberIn if (member is null) throw new ArgumentNullException(nameof(member)); + // Need to walk up the inheritance chain if member is not found + // Leverage the existing cache mechanism of per type to store members + RuntimeTypeInfo? runtimeType = this; + while (runtimeType != null) + { + MemberInfo result = runtimeType.GetMemberWithSameMetadataDefinitionAsInternal(member); + if (result != null) + return result; + runtimeType = runtimeType.BaseType as RuntimeTypeInfo; + } + throw new ArgumentException(SR.Format(SR.Arg_MemberInfoNotFound, member.Name), nameof(member)); + } + + private MemberInfo GetMemberWithSameMetadataDefinitionAsInternal(MemberInfo member) + { MemberInfo result = member.MemberType switch { MemberTypes.Method => QueryMemberWithSameMetadataDefinitionAs(member), @@ -134,9 +149,6 @@ public sealed override MemberInfo GetMemberWithSameMetadataDefinitionAs(MemberIn _ => null, }; - if (result is null) - throw new ArgumentException(SR.Format(SR.Arg_MemberInfoNotFound, member.Name), nameof(member)); - return result; } diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index 344e383b58cf84..9bb500957f5649 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -382,6 +382,8 @@ + + diff --git a/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs b/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs index e8cf15ce7cf855..e98e83d91823c2 100644 --- a/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs +++ b/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs @@ -63,6 +63,7 @@ private static int Main() TestInvokeMemberParamsCornerCase.Run(); TestDefaultInterfaceInvoke.Run(); TestCovariantReturnInvoke.Run(); + TestGetMemberWithSameMetadataDefinitionAs.Run(); #if !CODEGEN_CPP TypeConstructionTest.Run(); TestThreadStaticFields.Run(); @@ -395,6 +396,38 @@ public static void Run() } } + class TestGetMemberWithSameMetadataDefinitionAs + { + public class B_T + { + static B_T() { } + } + + public class D_T : B_T + { + } + + public static void Run() + { + Console.WriteLine(nameof(TestGetMemberWithSameMetadataDefinitionAs)); + + TestGetMemberWithSameMetadataDefinitionAs p = new TestGetMemberWithSameMetadataDefinitionAs(); + p.GetMemberWithSameMetadataDefinitionAs(typeof(B_T<>), typeof(D_T)); + } + + public void GetMemberWithSameMetadataDefinitionAs(Type openGenericType, Type closedGenericType) + { + BindingFlags all = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly; + foreach (MemberInfo openGenericMember in openGenericType.GetMembers(all)) + { + MemberInfo closedGenericMember = closedGenericType.GetMemberWithSameMetadataDefinitionAs(openGenericMember); + if (!closedGenericMember.Name.Equals(openGenericMember.Name)) + throw new Exception(); + + } + } + } + class TestInstanceFields { public class FieldInvokeSample From a9170d56ed0ccd837db2a4703c1704f5e6d43182 Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Mon, 9 May 2022 11:30:25 -0700 Subject: [PATCH 2/2] FB --- .../TypeInfos/RuntimeTypeInfo.GetMember.cs | 8 ++--- .../System.Reflection/tests/TypeInfoTests.cs | 1 - .../SmokeTests/Reflection/Reflection.cs | 33 ------------------- 3 files changed, 3 insertions(+), 39 deletions(-) diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.GetMember.cs b/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.GetMember.cs index 975b72b6e72832..e79e6c0b7092c1 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.GetMember.cs +++ b/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.GetMember.cs @@ -128,7 +128,7 @@ public sealed override MemberInfo GetMemberWithSameMetadataDefinitionAs(MemberIn RuntimeTypeInfo? runtimeType = this; while (runtimeType != null) { - MemberInfo result = runtimeType.GetMemberWithSameMetadataDefinitionAsInternal(member); + MemberInfo result = runtimeType.GetDeclaredMemberWithSameMetadataDefinitionAs(member); if (result != null) return result; runtimeType = runtimeType.BaseType as RuntimeTypeInfo; @@ -136,9 +136,9 @@ public sealed override MemberInfo GetMemberWithSameMetadataDefinitionAs(MemberIn throw new ArgumentException(SR.Format(SR.Arg_MemberInfoNotFound, member.Name), nameof(member)); } - private MemberInfo GetMemberWithSameMetadataDefinitionAsInternal(MemberInfo member) + private MemberInfo GetDeclaredMemberWithSameMetadataDefinitionAs(MemberInfo member) { - MemberInfo result = member.MemberType switch + return member.MemberType switch { MemberTypes.Method => QueryMemberWithSameMetadataDefinitionAs(member), MemberTypes.Constructor => QueryMemberWithSameMetadataDefinitionAs(member), @@ -148,8 +148,6 @@ private MemberInfo GetMemberWithSameMetadataDefinitionAsInternal(MemberInfo memb MemberTypes.NestedType => QueryMemberWithSameMetadataDefinitionAs(member), _ => null, }; - - return result; } private M QueryMemberWithSameMetadataDefinitionAs(MemberInfo member) where M : MemberInfo diff --git a/src/libraries/System.Reflection/tests/TypeInfoTests.cs b/src/libraries/System.Reflection/tests/TypeInfoTests.cs index fb0bccb86c4708..6a94e0f4606765 100644 --- a/src/libraries/System.Reflection/tests/TypeInfoTests.cs +++ b/src/libraries/System.Reflection/tests/TypeInfoTests.cs @@ -1656,7 +1656,6 @@ private static (Type, Type) CreateGeneratedTypes() } [Theory, MemberData(nameof(GetMemberWithSameMetadataDefinitionAsData))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/67533", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public void GetMemberWithSameMetadataDefinitionAs(Type openGenericType, Type closedGenericType, bool checkDeclaringType) { BindingFlags all = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly; diff --git a/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs b/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs index e98e83d91823c2..e8cf15ce7cf855 100644 --- a/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs +++ b/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs @@ -63,7 +63,6 @@ private static int Main() TestInvokeMemberParamsCornerCase.Run(); TestDefaultInterfaceInvoke.Run(); TestCovariantReturnInvoke.Run(); - TestGetMemberWithSameMetadataDefinitionAs.Run(); #if !CODEGEN_CPP TypeConstructionTest.Run(); TestThreadStaticFields.Run(); @@ -396,38 +395,6 @@ public static void Run() } } - class TestGetMemberWithSameMetadataDefinitionAs - { - public class B_T - { - static B_T() { } - } - - public class D_T : B_T - { - } - - public static void Run() - { - Console.WriteLine(nameof(TestGetMemberWithSameMetadataDefinitionAs)); - - TestGetMemberWithSameMetadataDefinitionAs p = new TestGetMemberWithSameMetadataDefinitionAs(); - p.GetMemberWithSameMetadataDefinitionAs(typeof(B_T<>), typeof(D_T)); - } - - public void GetMemberWithSameMetadataDefinitionAs(Type openGenericType, Type closedGenericType) - { - BindingFlags all = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly; - foreach (MemberInfo openGenericMember in openGenericType.GetMembers(all)) - { - MemberInfo closedGenericMember = closedGenericType.GetMemberWithSameMetadataDefinitionAs(openGenericMember); - if (!closedGenericMember.Name.Equals(openGenericMember.Name)) - throw new Exception(); - - } - } - } - class TestInstanceFields { public class FieldInvokeSample