33
44using Java . Interop . Tools . Cecil ;
55using Java . Interop . Tools . JavaCallableWrappers ;
6+ using Java . Interop . Tools . TypeNameMappings ;
67using Microsoft . Android . Build . Tasks ;
78using Microsoft . Build . Utilities ;
89using Mono . Cecil ;
@@ -12,17 +13,29 @@ namespace Xamarin.Android.Tasks
1213#if ENABLE_MARSHAL_METHODS
1314 public sealed class MarshalMethodEntry
1415 {
15- public MethodDefinition NativeCallback { get ; }
16- public MethodDefinition Connector { get ; }
17- public MethodDefinition TargetMethod { get ; }
18- public FieldDefinition CallbackField { get ; }
19-
20- public MarshalMethodEntry ( MethodDefinition nativeCallback , MethodDefinition connector , MethodDefinition targetMethod , FieldDefinition callbackField )
16+ public TypeDefinition TopType { get ; }
17+ public MethodDefinition NativeCallback { get ; }
18+ public MethodDefinition Connector { get ; }
19+ public MethodDefinition RegisteredMethod { get ; }
20+ public MethodDefinition ImplementedMethod { get ; }
21+ public FieldDefinition CallbackField { get ; }
22+ public string JniTypeName { get ; }
23+ public string JniMethodName { get ; }
24+ public string JniMethodSignature { get ; }
25+
26+ public MarshalMethodEntry ( TypeDefinition topType , MethodDefinition nativeCallback , MethodDefinition connector , MethodDefinition
27+ registeredMethod , MethodDefinition implementedMethod , FieldDefinition callbackField , string jniTypeName ,
28+ string jniName , string jniSignature )
2129 {
30+ TopType = topType ?? throw new ArgumentNullException ( nameof ( topType ) ) ;
2231 NativeCallback = nativeCallback ?? throw new ArgumentNullException ( nameof ( nativeCallback ) ) ;
2332 Connector = connector ?? throw new ArgumentNullException ( nameof ( connector ) ) ;
24- TargetMethod = targetMethod ?? throw new ArgumentNullException ( nameof ( targetMethod ) ) ;
33+ RegisteredMethod = registeredMethod ?? throw new ArgumentNullException ( nameof ( registeredMethod ) ) ;
34+ ImplementedMethod = implementedMethod ?? throw new ArgumentNullException ( nameof ( implementedMethod ) ) ;
2535 CallbackField = callbackField ;
36+ JniTypeName = jniTypeName ;
37+ JniMethodName = jniName ;
38+ JniMethodSignature = jniSignature ;
2639 }
2740 }
2841#endif
@@ -129,12 +142,12 @@ public bool Matches (MethodDefinition method)
129142
130143 TypeDefinitionCache tdCache ;
131144 DirectoryAssemblyResolver resolver ;
132- Dictionary < string , MarshalMethodEntry > marshalMethods ;
145+ Dictionary < string , IList < MarshalMethodEntry > > marshalMethods ;
133146 HashSet < AssemblyDefinition > assemblies ;
134147 TaskLoggingHelper log ;
135148 bool haveDynamicMethods ;
136149
137- public IDictionary < string , MarshalMethodEntry > MarshalMethods => marshalMethods ;
150+ public IDictionary < string , IList < MarshalMethodEntry > > MarshalMethods => marshalMethods ;
138151 public ICollection < AssemblyDefinition > Assemblies => assemblies ;
139152 public bool FoundDynamicallyRegisteredMethods => haveDynamicMethods ;
140153#endif
@@ -145,12 +158,12 @@ public MarshalMethodsClassifier (TypeDefinitionCache tdCache, DirectoryAssemblyR
145158 this . log = log ?? throw new ArgumentNullException ( nameof ( log ) ) ;
146159 this . tdCache = tdCache ?? throw new ArgumentNullException ( nameof ( tdCache ) ) ;
147160 resolver = res ?? throw new ArgumentNullException ( nameof ( tdCache ) ) ;
148- marshalMethods = new Dictionary < string , MarshalMethodEntry > ( StringComparer . Ordinal ) ;
161+ marshalMethods = new Dictionary < string , IList < MarshalMethodEntry > > ( StringComparer . Ordinal ) ;
149162 assemblies = new HashSet < AssemblyDefinition > ( ) ;
150163#endif
151164 }
152165
153- public override bool ShouldBeDynamicallyRegistered ( MethodDefinition registeredMethod , MethodDefinition implementedMethod , CustomAttribute registerAttribute )
166+ public override bool ShouldBeDynamicallyRegistered ( TypeDefinition topType , MethodDefinition registeredMethod , MethodDefinition implementedMethod , CustomAttribute registerAttribute )
154167 {
155168#if ENABLE_MARSHAL_METHODS
156169 if ( registeredMethod == null ) {
@@ -165,7 +178,7 @@ public override bool ShouldBeDynamicallyRegistered (MethodDefinition registeredM
165178 throw new ArgumentNullException ( nameof ( registerAttribute ) ) ;
166179 }
167180
168- if ( ! IsDynamicallyRegistered ( registeredMethod , implementedMethod , registerAttribute ) ) {
181+ if ( ! IsDynamicallyRegistered ( topType , registeredMethod , implementedMethod , registerAttribute ) ) {
169182 return false ;
170183 }
171184
@@ -175,10 +188,10 @@ public override bool ShouldBeDynamicallyRegistered (MethodDefinition registeredM
175188 }
176189
177190#if ENABLE_MARSHAL_METHODS
178- bool IsDynamicallyRegistered ( MethodDefinition registeredMethod , MethodDefinition implementedMethod , CustomAttribute registerAttribute )
191+ bool IsDynamicallyRegistered ( TypeDefinition topType , MethodDefinition registeredMethod , MethodDefinition implementedMethod , CustomAttribute registerAttribute )
179192 {
180193 Console . WriteLine ( $ "Classifying:\n \t method: { implementedMethod . FullName } \n \t registered method: { registeredMethod . FullName } )\n \t Attr: { registerAttribute . AttributeType . FullName } (parameter count: { registerAttribute . ConstructorArguments . Count } )") ;
181- Console . WriteLine ( $ "\t Managed type: { registeredMethod . DeclaringType . FullName } , { registeredMethod . DeclaringType . GetPartialAssemblyName ( tdCache ) } ") ;
194+ Console . WriteLine ( $ "\t Top type: { topType . FullName } \n \ t Managed type: { registeredMethod . DeclaringType . FullName } , { registeredMethod . DeclaringType . GetPartialAssemblyName ( tdCache ) } ") ;
182195 if ( registerAttribute . ConstructorArguments . Count != 3 ) {
183196 log . LogWarning ( $ "Method '{ registeredMethod . FullName } ' will be registered dynamically, not enough arguments to the [Register] attribute to generate marshal method.") ;
184197 return true ;
@@ -188,7 +201,7 @@ bool IsDynamicallyRegistered (MethodDefinition registeredMethod, MethodDefinitio
188201
189202 Console . WriteLine ( $ "\t connector: { connector . MethodName } (from spec: '{ ( string ) registerAttribute . ConstructorArguments [ 2 ] . Value } ')") ;
190203
191- if ( IsStandardHandler ( connector , registeredMethod ) ) {
204+ if ( IsStandardHandler ( topType , connector , registeredMethod , implementedMethod , jniName : ( string ) registerAttribute . ConstructorArguments [ 0 ] . Value , jniSignature : ( string ) registerAttribute . ConstructorArguments [ 1 ] . Value ) ) {
192205 return false ;
193206 }
194207
@@ -197,7 +210,7 @@ bool IsDynamicallyRegistered (MethodDefinition registeredMethod, MethodDefinitio
197210 }
198211
199212 // TODO: Probably should check if all the methods and fields are private and static - only then it is safe(ish) to remove them
200- bool IsStandardHandler ( ConnectorInfo connector , MethodDefinition registeredMethod )
213+ bool IsStandardHandler ( TypeDefinition topType , ConnectorInfo connector , MethodDefinition registeredMethod , MethodDefinition implementedMethod , string jniName , string jniSignature )
201214 {
202215 const string HandlerNameStart = "Get" ;
203216 const string HandlerNameEnd = "Handler" ;
@@ -245,7 +258,24 @@ bool IsStandardHandler (ConnectorInfo connector, MethodDefinition registeredMeth
245258 }
246259 }
247260
248- StoreMethod ( connectorName , registeredMethod , new MarshalMethodEntry ( nativeCallbackMethod , connectorMethod , registeredMethod , delegateField ) ) ;
261+ Console . WriteLine ( $ "##G1: { implementedMethod . DeclaringType . FullName } -> { JavaNativeTypeManager . ToJniName ( implementedMethod . DeclaringType , tdCache ) } ") ;
262+ Console . WriteLine ( $ "##G1: top type: { topType . FullName } -> { JavaNativeTypeManager . ToJniName ( topType , tdCache ) } ") ;
263+
264+ StoreMethod (
265+ connectorName ,
266+ registeredMethod ,
267+ new MarshalMethodEntry (
268+ topType ,
269+ nativeCallbackMethod ,
270+ connectorMethod ,
271+ registeredMethod ,
272+ implementedMethod ,
273+ delegateField ,
274+ JavaNativeTypeManager . ToJniName ( topType , tdCache ) ,
275+ jniName ,
276+ jniSignature )
277+ ) ;
278+
249279 StoreAssembly ( connectorMethod . Module . Assembly ) ;
250280 StoreAssembly ( nativeCallbackMethod . Module . Assembly ) ;
251281 if ( delegateField != null ) {
@@ -338,7 +368,11 @@ void StoreMethod (string connectorName, MethodDefinition registeredMethod, Marsh
338368 return ;
339369 }
340370
341- marshalMethods . Add ( key , entry ) ;
371+ if ( ! marshalMethods . TryGetValue ( key , out IList < MarshalMethodEntry > list ) || list == null ) {
372+ list = new List < MarshalMethodEntry > ( ) ;
373+ marshalMethods . Add ( key , list ) ;
374+ }
375+ list . Add ( entry ) ;
342376 }
343377
344378 void StoreAssembly ( AssemblyDefinition asm )
0 commit comments