@@ -25,40 +25,9 @@ public enum JavaPeerStyle {
2525 JavaInterop1 ,
2626 }
2727
28- public class OverriddenMethodDescriptor
28+ public interface IJCWMethodClassifier
2929 {
30- static readonly char [ ] methodDescSplitChars = new char [ ] { ':' } ;
31-
32- public string JavaPackageName { get ; }
33- public string NativeName { get ; }
34- public string JniSignature { get ; }
35- public string Connector { get ; }
36- public string ManagedTypeName { get ; }
37- public string OriginalDescString { get ; }
38-
39- public OverriddenMethodDescriptor ( string javaPackageName , string methodDescription , string fallbackManagedTypeName )
40- {
41- OriginalDescString = methodDescription ;
42- JavaPackageName = javaPackageName ;
43- string [ ] parts = methodDescription . Split ( methodDescSplitChars , 4 ) ;
44-
45- if ( parts . Length < 2 ) {
46- throw new InvalidOperationException ( $ "Unexpected format for method description. Expected at least 2 parts, got { parts . Length } from: '{ methodDescription } '") ;
47- }
48-
49- NativeName = parts [ 0 ] ;
50- JniSignature = parts [ 1 ] ;
51- if ( parts . Length > 2 ) {
52- Connector = parts [ 2 ] ;
53- if ( parts . Length > 3 ) {
54- ManagedTypeName = TypeDefinitionRocks . CecilTypeNameToReflectionTypeName ( parts [ 3 ] ) ;
55- }
56- }
57-
58- if ( String . IsNullOrEmpty ( ManagedTypeName ) ) {
59- ManagedTypeName = fallbackManagedTypeName ;
60- }
61- }
30+ bool ShouldBeDynamicallyRegistered ( MethodDefinition registeredMethod , MethodDefinition implementedMethod , CustomAttribute registerAttribute ) ;
6231 }
6332
6433 public class JavaCallableWrapperGenerator {
@@ -95,36 +64,38 @@ public string GetJavaAccess ()
9564 List < Signature > methods = new List < Signature > ( ) ;
9665 List < Signature > ctors = new List < Signature > ( ) ;
9766 List < JavaCallableWrapperGenerator > children ;
98- List < OverriddenMethodDescriptor > overriddenMethodDescriptors ;
67+
9968 readonly IMetadataResolver cache ;
69+ readonly IJCWMethodClassifier methodClassifier ;
10070
10171 [ Obsolete ( "Use the TypeDefinitionCache overload for better performance." ) ]
10272 public JavaCallableWrapperGenerator ( TypeDefinition type , Action < string , object [ ] > log )
10373 : this ( type , null , log , resolver : null )
10474 { }
10575
106- public JavaCallableWrapperGenerator ( TypeDefinition type , Action < string , object [ ] > log , TypeDefinitionCache cache )
107- : this ( type , log , ( IMetadataResolver ) cache )
76+ public JavaCallableWrapperGenerator ( TypeDefinition type , Action < string , object [ ] > log , TypeDefinitionCache cache , IJCWMethodClassifier methodClassifier = null )
77+ : this ( type , log , ( IMetadataResolver ) cache , methodClassifier )
10878 {
10979 }
11080
111- public JavaCallableWrapperGenerator ( TypeDefinition type , Action < string , object [ ] > log , IMetadataResolver resolver )
112- : this ( type , null , log , resolver )
81+ public JavaCallableWrapperGenerator ( TypeDefinition type , Action < string , object [ ] > log , IMetadataResolver resolver , IJCWMethodClassifier methodClassifier = null )
82+ : this ( type , null , log , resolver , methodClassifier )
11383 {
11484 if ( type . HasNestedTypes ) {
11585 children = new List < JavaCallableWrapperGenerator > ( ) ;
11686 AddNestedTypes ( type ) ;
11787 }
11888 }
11989
120- public IList < OverriddenMethodDescriptor > OverriddenMethodDescriptors => overriddenMethodDescriptors ;
12190 public string ApplicationJavaClass { get ; set ; }
12291 public JavaPeerStyle CodeGenerationTarget { get ; set ; }
12392
12493 public bool GenerateOnCreateOverrides { get ; set ; }
12594
12695 public bool HasExport { get ; private set ; }
12796
97+ public bool HasDynamicallyRegisteredMethods => methods . Any ( ( Signature sig ) => sig . IsDynamicallyRegistered ) ;
98+
12899 /// <summary>
129100 /// The Java source code to be included in Instrumentation.onCreate
130101 ///
@@ -152,8 +123,9 @@ void AddNestedTypes (TypeDefinition type)
152123 HasExport |= children . Any ( t => t . HasExport ) ;
153124 }
154125
155- JavaCallableWrapperGenerator ( TypeDefinition type , string outerType , Action < string , object [ ] > log , IMetadataResolver resolver )
126+ JavaCallableWrapperGenerator ( TypeDefinition type , string outerType , Action < string , object [ ] > log , IMetadataResolver resolver , IJCWMethodClassifier methodClassifier = null )
156127 {
128+ this . methodClassifier = methodClassifier ;
157129 this . type = type ;
158130 this . log = log ;
159131 this . cache = resolver ?? new TypeDefinitionCache ( ) ;
@@ -366,12 +338,13 @@ internal static RegisterAttribute ToRegisterAttribute (CustomAttribute attr)
366338 // attr.Resolve ();
367339 RegisterAttribute r = null ;
368340 if ( attr . ConstructorArguments . Count == 1 )
369- r = new RegisterAttribute ( ( string ) attr . ConstructorArguments [ 0 ] . Value ) ;
341+ r = new RegisterAttribute ( ( string ) attr . ConstructorArguments [ 0 ] . Value , attr ) ;
370342 else if ( attr . ConstructorArguments . Count == 3 )
371343 r = new RegisterAttribute (
372344 ( string ) attr . ConstructorArguments [ 0 ] . Value ,
373345 ( string ) attr . ConstructorArguments [ 1 ] . Value ,
374- ( string ) attr . ConstructorArguments [ 2 ] . Value ) ;
346+ ( string ) attr . ConstructorArguments [ 2 ] . Value ,
347+ attr ) ;
375348 if ( r != null ) {
376349 var v = attr . Properties . FirstOrDefault ( p => p . Name == "DoNotGenerateAcw" ) ;
377350 r . DoNotGenerateAcw = v . Name == null ? false : ( bool ) v . Argument . Value ;
@@ -384,7 +357,7 @@ internal static RegisterAttribute RegisterFromJniTypeSignatureAttribute (CustomA
384357 // attr.Resolve ();
385358 RegisterAttribute r = null ;
386359 if ( attr . ConstructorArguments . Count == 1 )
387- r = new RegisterAttribute ( ( string ) attr . ConstructorArguments [ 0 ] . Value ) ;
360+ r = new RegisterAttribute ( ( string ) attr . ConstructorArguments [ 0 ] . Value , attr ) ;
388361 if ( r != null ) {
389362 var v = attr . Properties . FirstOrDefault ( p => p . Name == "GenerateJavaPeer" ) ;
390363 if ( v . Name == null ) {
@@ -403,7 +376,8 @@ internal static RegisterAttribute RegisterFromJniMethodSignatureAttribute (Custo
403376 if ( attr . ConstructorArguments . Count == 2 )
404377 r = new RegisterAttribute ( ( string ) attr . ConstructorArguments [ 0 ] . Value ,
405378 ( string ) attr . ConstructorArguments [ 1 ] . Value ,
406- "" ) ;
379+ "" ,
380+ attr ) ;
407381 return r ;
408382 }
409383
@@ -467,7 +441,8 @@ void AddMethod (MethodDefinition registeredMethod, MethodDefinition implementedM
467441 if ( attr . Name . Contains ( "-impl" ) || ( attr . Name . Length > 7 && attr . Name [ attr . Name . Length - 8 ] == '-' ) )
468442 Diagnostic . Error ( 4217 , LookupSource ( implementedMethod ) , Localization . Resources . JavaCallableWrappers_XA4217 , attr . Name ) ;
469443
470- var msig = new Signature ( implementedMethod , attr ) ;
444+ bool shouldBeDynamicallyRegistered = methodClassifier ? . ShouldBeDynamicallyRegistered ( registeredMethod , implementedMethod , attr . OriginAttribute ) ?? false ;
445+ var msig = new Signature ( implementedMethod , attr , shouldBeDynamicallyRegistered ) ;
471446 if ( ! registeredMethod . IsConstructor && ! methods . Any ( m => m . Name == msig . Name && m . Params == msig . Params ) )
472447 methods . Add ( msig ) ;
473448 }
@@ -542,21 +517,38 @@ public void Generate (TextWriter writer)
542517
543518 GenerateHeader ( writer ) ;
544519
545- writer . WriteLine ( "/** @hide */" ) ;
546- writer . WriteLine ( "\t public static final String __md_methods;" ) ;
520+ bool needCtor = false ;
521+ if ( HasDynamicallyRegisteredMethods ) {
522+ needCtor = true ;
523+ writer . WriteLine ( "/** @hide */" ) ;
524+ writer . WriteLine ( "\t public static final String __md_methods;" ) ;
525+ }
526+
547527 if ( children != null ) {
548- foreach ( var i in Enumerable . Range ( 1 , children . Count ) )
528+ for ( int i = 0 ; i < children . Count ; i ++ ) {
529+ if ( ! children [ i ] . HasDynamicallyRegisteredMethods ) {
530+ continue ;
531+ }
532+ needCtor = true ;
549533 writer . WriteLine ( "\t static final String __md_{0}_methods;" , i ) ;
534+ }
550535 }
551- writer . WriteLine ( "\t static {" ) ;
552- GenerateRegisterType ( writer , this , "__md_methods" ) ;
553- if ( children != null ) {
554- for ( int i = 0 ; i < children . Count ; ++ i ) {
555- string methods = string . Format ( "__md_{0}_methods" , i + 1 ) ;
556- GenerateRegisterType ( writer , children [ i ] , methods ) ;
536+
537+ if ( needCtor ) {
538+ writer . WriteLine ( "\t static {" ) ;
539+
540+ if ( HasDynamicallyRegisteredMethods ) {
541+ GenerateRegisterType ( writer , this , "__md_methods" ) ;
542+ }
543+
544+ if ( children != null ) {
545+ for ( int i = 0 ; i < children . Count ; ++ i ) {
546+ string methods = string . Format ( "__md_{0}_methods" , i + 1 ) ;
547+ GenerateRegisterType ( writer , children [ i ] , methods ) ;
548+ }
557549 }
550+ writer . WriteLine ( "\t }" ) ;
558551 }
559- writer . WriteLine ( "\t }" ) ;
560552
561553 GenerateBody ( writer ) ;
562554
@@ -710,16 +702,19 @@ void GenerateBody (TextWriter sw)
710702
711703 void GenerateRegisterType ( TextWriter sw , JavaCallableWrapperGenerator self , string field )
712704 {
713- if ( overriddenMethodDescriptors == null ) {
714- overriddenMethodDescriptors = new List < OverriddenMethodDescriptor > ( ) ;
705+ string managedTypeName = self . type . GetPartialAssemblyQualifiedName ( cache ) ;
706+ string javaTypeName = $ "{ package } .{ name } ";
707+
708+ if ( ! self . HasDynamicallyRegisteredMethods ) {
709+ return ;
715710 }
716711
717712 sw . WriteLine ( "\t \t {0} = " , field ) ;
718- string managedTypeName = self . type . GetPartialAssemblyQualifiedName ( cache ) ;
719- string javaTypeName = $ "{ package } .{ name } ";
713+
720714 foreach ( Signature method in self . methods ) {
721- sw . WriteLine ( "\t \t \t \" {0}\\ n\" +" , method . Method ) ;
722- overriddenMethodDescriptors . Add ( new OverriddenMethodDescriptor ( javaTypeName , method . Method , managedTypeName ) ) ;
715+ if ( method . IsDynamicallyRegistered ) {
716+ sw . WriteLine ( "\t \t \t \" {0}\\ n\" +" , method . Method ) ;
717+ }
723718 }
724719 sw . WriteLine ( "\t \t \t \" \" ;" ) ;
725720 if ( CannotRegisterInStaticConstructor ( self . type ) )
@@ -772,12 +767,13 @@ bool CannotRegisterInStaticConstructor (TypeDefinition type)
772767
773768 class Signature {
774769
775- public Signature ( MethodDefinition method , RegisterAttribute register ) : this ( method , register , null , null ) { }
770+ public Signature ( MethodDefinition method , RegisterAttribute register , bool shouldBeDynamicallyRegistered = true ) : this ( method , register , null , null , shouldBeDynamicallyRegistered ) { }
776771
777- public Signature ( MethodDefinition method , RegisterAttribute register , string managedParameters , string outerType )
772+ public Signature ( MethodDefinition method , RegisterAttribute register , string managedParameters , string outerType , bool shouldBeDynamicallyRegistered = true )
778773 : this ( register . Name , register . Signature , register . Connector , managedParameters , outerType , null )
779774 {
780775 Annotations = JavaCallableWrapperGenerator . GetAnnotationsString ( "\t " , method . CustomAttributes ) ;
776+ IsDynamicallyRegistered = shouldBeDynamicallyRegistered ;
781777 }
782778
783779 public Signature ( MethodDefinition method , ExportAttribute export , IMetadataResolver cache )
@@ -880,6 +876,7 @@ public string ThrowsDeclaration {
880876 public readonly string Method ;
881877 public readonly bool IsExport ;
882878 public readonly bool IsStatic ;
879+ public readonly bool IsDynamicallyRegistered = true ;
883880 public readonly string [ ] ThrownTypeNames ;
884881 public readonly string Annotations ;
885882 }
0 commit comments