1
+ #nullable enable
1
2
using System ;
2
3
using System . Collections . Generic ;
3
- using System . IO ;
4
4
using System . Linq ;
5
5
using Java . Interop . Tools . JavaCallableWrappers ;
6
6
using Java . Interop . Tools . JavaCallableWrappers . Adapters ;
7
7
using Java . Interop . Tools . JavaCallableWrappers . CallableWrapperMembers ;
8
8
using Microsoft . Android . Build . Tasks ;
9
-
10
9
using Microsoft . Build . Utilities ;
11
10
using Mono . Cecil ;
12
11
using Mono . Linker ;
13
12
using Mono . Linker . Steps ;
14
13
using Xamarin . Android . Tasks ;
15
- using Xamarin . Android . Tasks . Utilities ;
16
14
17
15
namespace MonoDroid . Tuner ;
18
16
17
+ /// <summary>
18
+ /// Scans an assembly for JLOs that need JCWs generated and writes them to an XML file.
19
+ /// </summary>
19
20
public class FindJavaObjectsStep : BaseStep
20
21
{
21
- public string ApplicationJavaClass { get ; set ; }
22
-
23
- public bool Debug { get ; set ; }
22
+ public string ApplicationJavaClass { get ; set ; } = "" ;
24
23
25
24
public bool ErrorOnCustomJavaObject { get ; set ; }
26
25
27
26
public bool UseMarshalMethods { get ; set ; }
28
27
29
- public List < string > UserAssemblies { get ; set ; } = [ ] ;
30
-
31
- public JavaPeerStyle CodeGenerationTarget { get ; set ; }
32
-
33
28
public TaskLoggingHelper Log { get ; set ; }
34
29
35
- // Names of assemblies which don't have Mono.Android.dll references, or are framework assemblies, but which must
36
- // be scanned for Java types.
37
- static readonly HashSet < string > SpecialAssemblies = new HashSet < string > ( StringComparer . OrdinalIgnoreCase ) {
38
- "Java.Interop" ,
39
- "Mono.Android" ,
40
- "Mono.Android.Runtime" ,
41
- } ;
30
+ public FindJavaObjectsStep ( TaskLoggingHelper log ) => Log = log ;
42
31
43
- public bool ProcessAssembly ( AssemblyDefinition assembly , string destination , bool hasMonoAndroidReference )
32
+ public bool ProcessAssembly ( AssemblyDefinition assembly , string destinationJLOXml )
44
33
{
45
34
var action = Annotations . HasAction ( assembly ) ? Annotations . GetAction ( assembly ) : AssemblyAction . Skip ;
46
35
47
36
if ( action == AssemblyAction . Delete )
48
37
return false ;
49
38
50
- var destinationJLOXml = destination ;
51
-
52
- // See if we should process this assembly
53
- //if (!ShouldProcessAssembly (assembly, hasMonoAndroidReference)) {
54
- // // We need to write an empty file for incremental builds
55
- // WriteEmptyXmlFile (destinationJLOXml);
56
- // return false;
57
- //}
58
-
59
39
var types = ScanForJavaTypes ( assembly ) ;
60
40
var initial_count = types . Count ;
61
41
62
42
// Filter out Java types we don't care about
63
43
types = types . Where ( t => ! t . IsInterface && ! JavaTypeScanner . ShouldSkipJavaCallableWrapperGeneration ( t , Context ) ) . ToList ( ) ;
64
44
65
- LogMessage ( $ "{ assembly . Name . Name } - Found { initial_count } Java types, filtered to { types . Count } ") ;
66
- ExportAsCallableWrappers ( destinationJLOXml , types ) ;
67
- //ExportAsJavaTypeSystem (destination + "2", types);
68
-
69
- return true ;
70
- }
71
-
72
- bool ShouldProcessAssembly ( AssemblyDefinition assembly , bool hasMonoAndroidReference )
73
- {
74
- // Don't bother scanning the assembly if it doesn't have a Java.Lang.Object reference
75
- if ( ! hasMonoAndroidReference && ! SpecialAssemblies . Contains ( assembly . Name . Name ) && ! assembly . MainModule . HasTypeReference ( "Java.Lang.Object" ) && ! assembly . MainModule . AssemblyReferences . Any ( r => r . Name == "Mono.Android" || r . Name == "Java.Interop" ) ) {
76
- LogMessage ( $ "Skipping assembly '{ assembly . Name . Name } ' because it doesn't reference Java.Lang.Object") ;
77
- return false ;
78
- }
79
-
80
- // If we don't need JLOs from non-user assemblies, skip scanning them
81
- var shouldSkipNonUserAssemblies = ( Debug || ! UseMarshalMethods ) && CodeGenerationTarget == JavaPeerStyle . XAJavaInterop1 ;
82
-
83
- if ( shouldSkipNonUserAssemblies && ! UserAssemblies . Contains ( assembly . Name . Name ) ) {
84
- LogMessage ( $ "Skipping assembly '{ assembly . Name . Name } ' because it is not a user assembly and we don't need JLOs from non-user assemblies") ;
85
- return false ;
86
- }
87
-
88
- return true ;
89
- }
45
+ Log . LogDebugMessage ( $ "{ assembly . Name . Name } - Found { initial_count } Java types, filtered to { types . Count } ") ;
90
46
91
- void ExportAsCallableWrappers ( string destination , List < TypeDefinition > types )
92
- {
93
47
var wrappers = ConvertToCallableWrappers ( types ) ;
94
- XmlExporter . Export ( destination , wrappers , true ) ;
95
- }
48
+ XmlExporter . Export ( destinationJLOXml , wrappers , true ) ;
96
49
97
- void LogMessage ( string message )
98
- {
99
- Console . WriteLine ( message ) ;
50
+ return true ;
100
51
}
101
52
102
53
public static void WriteEmptyXmlFile ( string destination )
@@ -127,14 +78,11 @@ List<CallableWrapperType> ConvertToCallableWrappers (List<TypeDefinition> types)
127
78
128
79
var reader_options = new CallableWrapperReaderOptions {
129
80
DefaultApplicationJavaClass = ApplicationJavaClass ,
130
- DefaultGenerateOnCreateOverrides = false , // this was used only when targetting Android API <= 10, which is no longer supported
131
81
DefaultMonoRuntimeInitialization = "mono.MonoPackageManager.LoadApplication (context);" ,
132
82
} ;
133
83
134
- if ( UseMarshalMethods ) {
135
- Log . LogDebugMessage ( "Using MarshalMethodsClassifier" ) ;
136
- reader_options . MethodClassifier = MakeClassifier ( ) ;
137
- }
84
+ if ( UseMarshalMethods )
85
+ reader_options . MethodClassifier = new MarshalMethodsClassifier ( Context , Context . Resolver , Log ) ;
138
86
139
87
foreach ( var type in types ) {
140
88
var wrapper = CecilImporter . CreateType ( type , Context , reader_options ) ;
@@ -143,6 +91,4 @@ List<CallableWrapperType> ConvertToCallableWrappers (List<TypeDefinition> types)
143
91
144
92
return wrappers ;
145
93
}
146
-
147
- MarshalMethodsClassifier MakeClassifier ( ) => new MarshalMethodsClassifier ( Context , Context . Resolver , Log ) ;
148
94
}
0 commit comments