Skip to content

Commit dae6453

Browse files
committed
Scanned assemblies match, begin cleanup and Java output verification.
1 parent 22831f8 commit dae6453

File tree

7 files changed

+133
-429
lines changed

7 files changed

+133
-429
lines changed
Lines changed: 12 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,102 +1,53 @@
1+
#nullable enable
12
using System;
23
using System.Collections.Generic;
3-
using System.IO;
44
using System.Linq;
55
using Java.Interop.Tools.JavaCallableWrappers;
66
using Java.Interop.Tools.JavaCallableWrappers.Adapters;
77
using Java.Interop.Tools.JavaCallableWrappers.CallableWrapperMembers;
88
using Microsoft.Android.Build.Tasks;
9-
109
using Microsoft.Build.Utilities;
1110
using Mono.Cecil;
1211
using Mono.Linker;
1312
using Mono.Linker.Steps;
1413
using Xamarin.Android.Tasks;
15-
using Xamarin.Android.Tasks.Utilities;
1614

1715
namespace MonoDroid.Tuner;
1816

17+
/// <summary>
18+
/// Scans an assembly for JLOs that need JCWs generated and writes them to an XML file.
19+
/// </summary>
1920
public class FindJavaObjectsStep : BaseStep
2021
{
21-
public string ApplicationJavaClass { get; set; }
22-
23-
public bool Debug { get; set; }
22+
public string ApplicationJavaClass { get; set; } = "";
2423

2524
public bool ErrorOnCustomJavaObject { get; set; }
2625

2726
public bool UseMarshalMethods { get; set; }
2827

29-
public List<string> UserAssemblies { get; set; } = [];
30-
31-
public JavaPeerStyle CodeGenerationTarget { get; set; }
32-
3328
public TaskLoggingHelper Log { get; set; }
3429

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;
4231

43-
public bool ProcessAssembly (AssemblyDefinition assembly, string destination, bool hasMonoAndroidReference)
32+
public bool ProcessAssembly (AssemblyDefinition assembly, string destinationJLOXml)
4433
{
4534
var action = Annotations.HasAction (assembly) ? Annotations.GetAction (assembly) : AssemblyAction.Skip;
4635

4736
if (action == AssemblyAction.Delete)
4837
return false;
4938

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-
5939
var types = ScanForJavaTypes (assembly);
6040
var initial_count = types.Count;
6141

6242
// Filter out Java types we don't care about
6343
types = types.Where (t => !t.IsInterface && !JavaTypeScanner.ShouldSkipJavaCallableWrapperGeneration (t, Context)).ToList ();
6444

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}");
9046

91-
void ExportAsCallableWrappers (string destination, List<TypeDefinition> types)
92-
{
9347
var wrappers = ConvertToCallableWrappers (types);
94-
XmlExporter.Export (destination, wrappers, true);
95-
}
48+
XmlExporter.Export (destinationJLOXml, wrappers, true);
9649

97-
void LogMessage (string message)
98-
{
99-
Console.WriteLine (message);
50+
return true;
10051
}
10152

10253
public static void WriteEmptyXmlFile (string destination)
@@ -127,14 +78,11 @@ List<CallableWrapperType> ConvertToCallableWrappers (List<TypeDefinition> types)
12778

12879
var reader_options = new CallableWrapperReaderOptions {
12980
DefaultApplicationJavaClass = ApplicationJavaClass,
130-
DefaultGenerateOnCreateOverrides = false, // this was used only when targetting Android API <= 10, which is no longer supported
13181
DefaultMonoRuntimeInitialization = "mono.MonoPackageManager.LoadApplication (context);",
13282
};
13383

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);
13886

13987
foreach (var type in types) {
14088
var wrapper = CecilImporter.CreateType (type, Context, reader_options);
@@ -143,6 +91,4 @@ List<CallableWrapperType> ConvertToCallableWrappers (List<TypeDefinition> types)
14391

14492
return wrappers;
14593
}
146-
147-
MarshalMethodsClassifier MakeClassifier () => new MarshalMethodsClassifier (Context, Context.Resolver, Log);
14894
}

src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaCallableWrappers.cs

Lines changed: 13 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using Java.Interop.Tools.TypeNameMappings;
1111
using Microsoft.Android.Build.Tasks;
1212
using Microsoft.Build.Framework;
13+
using Microsoft.Build.Utilities;
1314
using PackageNamingPolicyEnum = Java.Interop.Tools.TypeNameMappings.PackageNamingPolicy;
1415

1516
namespace Xamarin.Android.Tasks;
@@ -36,10 +37,8 @@ public class GenerateJavaCallableWrappers : AndroidTask
3637
[Required]
3738
public string [] SupportedAbis { get; set; } = [];
3839

39-
[Required]
40-
public ITaskItem [] LegacyGeneratedJavaFiles { get; set; } = [];
41-
42-
List<string> GeneratedJavaFiles = [];
40+
[Output]
41+
public ITaskItem [] GeneratedJavaFilesOutput { get; set; } = [];
4342

4443
public override bool RunTask ()
4544
{
@@ -52,18 +51,16 @@ public override bool RunTask ()
5251

5352
GenerateWrappers (singleArchAssemblies);
5453

55-
//EnsureSameFilesWritten ();
56-
5754
return !Log.HasLoggedErrors;
5855
}
5956

6057
void GenerateWrappers (List<ITaskItem> assemblies)
6158
{
6259
Directory.CreateDirectory (OutputDirectory);
6360

64-
var sw = Stopwatch.StartNew ();
65-
// Deserialize JavaCallableWrappers
61+
// Deserialize JavaCallableWrappers XML files
6662
var wrappers = new List<CallableWrapperType> ();
63+
var sw = Stopwatch.StartNew ();
6764

6865
foreach (var assembly in assemblies) {
6966
var assemblyPath = assembly.ItemSpec;
@@ -77,56 +74,32 @@ void GenerateWrappers (List<ITaskItem> assemblies)
7774

7875
wrappers.AddRange (XmlImporter.Import (wrappersPath, out var _));
7976
}
80-
Log.LogDebugMessage ($"Deserialized Java callable wrappers in: '{sw.ElapsedMilliseconds}ms'");
8177

78+
Log.LogDebugMessage ($"Deserialized {wrappers.Count} Java callable wrappers in {sw.ElapsedMilliseconds}ms");
8279
sw.Restart ();
80+
81+
// Write JavaCallableWrappers to Java files
8382
var writer_options = new CallableWrapperWriterOptions {
8483
CodeGenerationTarget = MonoAndroidHelper.ParseCodeGenerationTarget (CodeGenerationTarget)
8584
};
8685

86+
var generated_files = new List<ITaskItem> ();
87+
8788
foreach (var generator in wrappers) {
8889
using var writer = MemoryStreamPool.Shared.CreateStreamWriter ();
8990

9091
generator.Generate (writer, writer_options);
9192
writer.Flush ();
9293

93-
9494
var path = generator.GetDestinationPath (OutputDirectory);
9595

96-
//if (Files.HasStreamChanged (writer.BaseStream, path)) {
97-
// Files.CopyIfStreamChanged (writer.BaseStream, path.Replace (@"\src\", @"\src2\"));
98-
// Log.LogError ($"Java callable wrapper code changed: '{path}'");
99-
// continue;
100-
//}
101-
10296
var changed = Files.CopyIfStreamChanged (writer.BaseStream, path);
10397
Log.LogDebugMessage ($"*NEW* Generated Java callable wrapper code: '{path}' (changed: {changed})");
10498

105-
//if (changed)
106-
// Log.LogError ($"Java callable wrapper code changed: '{path}'");
107-
108-
GeneratedJavaFiles.Add (path);
99+
generated_files.Add (new TaskItem (path));
109100
}
110-
Log.LogDebugMessage ($"Wrote Java callable wrappers in: '{sw.ElapsedMilliseconds}ms'");
111-
}
112-
113-
void EnsureSameFilesWritten ()
114-
{
115-
var new_generated_java_files = GeneratedJavaFiles.Select (f => f.Replace ("src2", "src")).ToList ();
116-
var old_generated_java_files = LegacyGeneratedJavaFiles.Select (f => f.ItemSpec).ToList ();
117-
118-
var extra_new_files = new_generated_java_files.Except (old_generated_java_files).ToList ();
119101

120-
if (extra_new_files.Count > 0)
121-
Log.LogWarning ($"The following Java files were generated but not previously generated: {string.Join (", ", extra_new_files)}");
122-
123-
var missing_old_files = old_generated_java_files.Except (new_generated_java_files).ToList ();
124-
125-
if (missing_old_files.Count > 0)
126-
Log.LogWarning ($"The following Java files were previously generated but not generated this time: {string.Join (", ", missing_old_files)}");
127-
128-
if (extra_new_files.Count > 0 || missing_old_files.Count > 0) {
129-
Log.LogError ($"New JCW gen ({new_generated_java_files.Count}) mismatch with old JCW gen ({old_generated_java_files.Count})");
130-
}
102+
Log.LogDebugMessage ($"Generated {generated_files.Count} Java callable wrapper files in {sw.ElapsedMilliseconds}ms");
103+
GeneratedJavaFilesOutput = generated_files.ToArray ();
131104
}
132105
}

0 commit comments

Comments
 (0)