@@ -16,7 +16,7 @@ public class TypeMappingStep : BaseStep
1616{
1717 const string AssemblyName = "Microsoft.Android.Runtime.NativeAOT" ;
1818 const string TypeName = "Microsoft.Android.Runtime.NativeAotTypeManager" ;
19- readonly IDictionary < string , TypeDefinition > TypeMappings = new Dictionary < string , TypeDefinition > ( StringComparer . Ordinal ) ;
19+ readonly IDictionary < string , List < TypeDefinition > > TypeMappings = new Dictionary < string , List < TypeDefinition > > ( StringComparer . Ordinal ) ;
2020 AssemblyDefinition ? MicrosoftAndroidRuntimeNativeAot ;
2121
2222 protected override void ProcessAssembly ( AssemblyDefinition assembly )
@@ -66,7 +66,7 @@ protected override void EndProcess ()
6666 var il = method . Body . GetILProcessor ( ) ;
6767 var addMethod = module . ImportReference ( typeof ( IDictionary < string , Type > ) . GetMethod ( "Add" ) ) ;
6868 var getTypeFromHandle = module . ImportReference ( typeof ( Type ) . GetMethod ( "GetTypeFromHandle" ) ) ;
69- foreach ( var ( javaKey , typeDefinition ) in TypeMappings ) {
69+ foreach ( var ( javaName , list ) in TypeMappings ) {
7070 /*
7171 * IL_0000: ldarg.0
7272 * IL_0001: ldfld class [System.Runtime]System.Collections.Generic.IDictionary`2<string, class [System.Runtime]System.Type> Microsoft.Android.Runtime.NativeAotTypeManager::TypeMappings
@@ -77,22 +77,47 @@ protected override void EndProcess ()
7777 */
7878 il . Emit ( Mono . Cecil . Cil . OpCodes . Ldarg_0 ) ;
7979 il . Emit ( Mono . Cecil . Cil . OpCodes . Ldfld , field ) ;
80- il . Emit ( Mono . Cecil . Cil . OpCodes . Ldstr , javaKey ) ;
81- il . Emit ( Mono . Cecil . Cil . OpCodes . Ldtoken , module . ImportReference ( typeDefinition ) ) ;
80+ il . Emit ( Mono . Cecil . Cil . OpCodes . Ldstr , javaName ) ;
81+ il . Emit ( Mono . Cecil . Cil . OpCodes . Ldtoken , module . ImportReference ( SelectTypeDefinition ( javaName , list ) ) ) ;
8282 il . Emit ( Mono . Cecil . Cil . OpCodes . Call , getTypeFromHandle ) ;
8383 il . Emit ( Mono . Cecil . Cil . OpCodes . Callvirt , addMethod ) ;
8484 }
8585
8686 il . Emit ( Mono . Cecil . Cil . OpCodes . Ret ) ;
8787 }
8888
89+ TypeDefinition SelectTypeDefinition ( string javaName , List < TypeDefinition > list )
90+ {
91+ if ( list . Count == 1 )
92+ return list [ 0 ] ;
93+
94+ var best = list [ 0 ] ;
95+ foreach ( var type in list ) {
96+ if ( type == best )
97+ continue ;
98+ if ( ( type . IsAbstract || type . IsInterface ) &&
99+ ! best . IsAbstract &&
100+ ! best . IsInterface &&
101+ type . IsAssignableFrom ( best , Context ) ) {
102+ best = type ;
103+ }
104+ }
105+ foreach ( var type in list ) {
106+ if ( type == best )
107+ continue ;
108+ Context . LogMessage ( $ "Duplicate typemap entry for { javaName } => { type . FullName } ") ;
109+ }
110+ return best ;
111+ }
112+
89113 void ProcessType ( AssemblyDefinition assembly , TypeDefinition type )
90114 {
91115 if ( type . HasJavaPeer ( Context ) ) {
92116 var javaName = JavaNativeTypeManager . ToJniName ( type , Context ) ;
93- if ( ! TypeMappings . TryAdd ( javaName , type ) ) {
94- Context . LogMessage ( $ "Duplicate typemap entry for { javaName } " ) ;
117+ if ( ! TypeMappings . TryGetValue ( javaName , out var list ) ) {
118+ TypeMappings . Add ( javaName , list = new List < TypeDefinition > ( ) ) ;
95119 }
120+ list . Add ( type ) ;
96121 }
97122
98123 if ( ! type . HasNestedTypes )
0 commit comments