From c7cdf36621199d064388ebb103605e73832b0657 Mon Sep 17 00:00:00 2001
From: Jonathan Pobst <jonathan.pobst@microsoft.com>
Date: Mon, 14 Oct 2024 09:58:47 -1000
Subject: [PATCH 1/3] [generator] Only use `[JniTypeSignatureAttribute]` for
 `JavaInterop1`.

---
 .../Adapters/ApiImporterOptions.cs            |  9 +++
 .../Adapters/ManagedApiImporter.cs            | 68 +++++++++----------
 .../Java.Interop.Tools.JavaTypeSystem.csproj  |  1 -
 .../Unit-Tests/ManagedTests.cs                | 26 +++----
 tools/generator/CodeGenerator.cs              |  2 +-
 .../CecilApiImporter.cs                       | 40 ++++++-----
 .../JavaTypeResolutionFixups.cs               |  9 ++-
 7 files changed, 87 insertions(+), 68 deletions(-)
 create mode 100644 src/Java.Interop.Tools.JavaTypeSystem/Adapters/ApiImporterOptions.cs

diff --git a/src/Java.Interop.Tools.JavaTypeSystem/Adapters/ApiImporterOptions.cs b/src/Java.Interop.Tools.JavaTypeSystem/Adapters/ApiImporterOptions.cs
new file mode 100644
index 000000000..7778f3527
--- /dev/null
+++ b/src/Java.Interop.Tools.JavaTypeSystem/Adapters/ApiImporterOptions.cs
@@ -0,0 +1,9 @@
+using System;
+using System.Collections.ObjectModel;
+
+namespace Java.Interop.Tools.JavaTypeSystem;
+
+public class ApiImporterOptions
+{
+	public Collection<string> SupportedRegisterAttributes { get; } = ["Android.Runtime.RegisterAttribute"];
+}
diff --git a/src/Java.Interop.Tools.JavaTypeSystem/Adapters/ManagedApiImporter.cs b/src/Java.Interop.Tools.JavaTypeSystem/Adapters/ManagedApiImporter.cs
index abf05d815..41e57b56a 100644
--- a/src/Java.Interop.Tools.JavaTypeSystem/Adapters/ManagedApiImporter.cs
+++ b/src/Java.Interop.Tools.JavaTypeSystem/Adapters/ManagedApiImporter.cs
@@ -13,13 +13,13 @@ public static class ManagedApiImporter
 		[Obsolete ("Use the TypeDefinitionCache overload for better performance.", error: true)]
 		public static JavaTypeCollection Parse (AssemblyDefinition assembly, JavaTypeCollection collection) => throw new NotSupportedException ();
 
-		public static JavaTypeCollection Parse (AssemblyDefinition assembly, JavaTypeCollection collection, TypeDefinitionCache resolver)
+		public static JavaTypeCollection Parse (AssemblyDefinition assembly, JavaTypeCollection collection, TypeDefinitionCache resolver, ApiImporterOptions options)
 		{
 			var types_to_add = new List<JavaTypeModel> ();
 
 			foreach (var md in assembly.Modules)
 				foreach (var td in md.Types) {
-					if (!ShouldSkipType (td, resolver) && ParseType (td, collection) is JavaTypeModel type)
+					if (!ShouldSkipType (td, resolver, options) && ParseType (td, collection, options) is JavaTypeModel type)
 						types_to_add.Add (type);
 				}
 
@@ -33,7 +33,7 @@ public static JavaTypeCollection Parse (AssemblyDefinition assembly, JavaTypeCol
 			return collection;
 		}
 
-		public static JavaTypeModel? ParseType (TypeDefinition type, JavaTypeCollection collection)
+		public static JavaTypeModel? ParseType (TypeDefinition type, JavaTypeCollection collection, ApiImporterOptions options)
 		{
 			if (!type.IsPublic && !type.IsNested)
 				return null;
@@ -41,13 +41,13 @@ public static JavaTypeCollection Parse (AssemblyDefinition assembly, JavaTypeCol
 			if (!ShouldImport (type))
 				return null;
 
-			var model = type.IsInterface ? (JavaTypeModel?) ParseInterface (type, collection) : ParseClass (type, collection);
+			var model = type.IsInterface ? (JavaTypeModel?) ParseInterface (type, collection, options) : ParseClass (type, collection, options);
 
 			if (model is null)
 				return null;
 
 			foreach (var nested in type.NestedTypes)
-				if (ParseType (nested, collection) is JavaTypeModel nested_model)
+				if (ParseType (nested, collection, options) is JavaTypeModel nested_model)
 					model.NestedTypes.Add (nested_model);
 
 			return model;
@@ -89,11 +89,11 @@ static bool ShouldImport (TypeDefinition td)
 			return true;
 		}
 
-		public static JavaClassModel? ParseClass (TypeDefinition type, JavaTypeCollection collection)
+		public static JavaClassModel? ParseClass (TypeDefinition type, JavaTypeCollection collection, ApiImporterOptions options)
 		{
 			// TODO: type parameters?
 			var obs_attr = GetObsoleteAttribute (type.CustomAttributes);
-			var reg_attr = GetRegisterAttribute (type.CustomAttributes);
+			var reg_attr = GetRegisterAttribute (type.CustomAttributes, options);
 
 			if (reg_attr is null)
 				return null;
@@ -101,7 +101,7 @@ static bool ShouldImport (TypeDefinition td)
 			var encoded_fullname = ((string) reg_attr.ConstructorArguments [0].Value).Replace ('/', '.');
 			var (package, nested_name) = DecodeRegisterJavaFullName (encoded_fullname);
 
-			var base_jni = GetBaseTypeJni (type);
+			var base_jni = GetBaseTypeJni (type, options);
 
 			var model = new JavaClassModel (
 				javaPackage: GetOrCreatePackage (collection, package, type.Namespace),
@@ -118,20 +118,20 @@ static bool ShouldImport (TypeDefinition td)
 				annotatedVisibility: string.Empty
 			); ;
 
-			ParseImplementedInterfaces (type, model);
+			ParseImplementedInterfaces (type, model, options);
 
 			foreach (var method in type.Methods.Where (m => !m.IsConstructor))
-				if (ParseMethod (method, model) is JavaMethodModel m)
+				if (ParseMethod (method, model, options) is JavaMethodModel m)
 					model.Methods.Add (m);
 
 			return model;
 		}
 
-		public static JavaInterfaceModel? ParseInterface (TypeDefinition type, JavaTypeCollection collection)
+		public static JavaInterfaceModel? ParseInterface (TypeDefinition type, JavaTypeCollection collection, ApiImporterOptions options)
 		{
 			// TODO: type paramters?
 			var obs_attr = GetObsoleteAttribute (type.CustomAttributes);
-			var reg_attr = GetRegisterAttribute (type.CustomAttributes);
+			var reg_attr = GetRegisterAttribute (type.CustomAttributes, options);
 
 			if (reg_attr is null)
 				return null;
@@ -149,22 +149,22 @@ static bool ShouldImport (TypeDefinition td)
 				annotatedVisibility: ""
 			);
 
-			ParseImplementedInterfaces (type, model);
+			ParseImplementedInterfaces (type, model, options);
 
 			foreach (var method in type.Methods)
-				if (ParseMethod (method, model) is JavaMethodModel m)
+				if (ParseMethod (method, model, options) is JavaMethodModel m)
 					model.Methods.Add (m);
 
 			return model;
 		}
 
-		public static JavaMethodModel? ParseMethod (MethodDefinition method, JavaTypeModel declaringType)
+		public static JavaMethodModel? ParseMethod (MethodDefinition method, JavaTypeModel declaringType, ApiImporterOptions options)
 		{
 			if (method.IsPrivate || method.IsAssembly)
 				return null;
 
 			var obs_attr = GetObsoleteAttribute (method.CustomAttributes);
-			var reg_attr = GetRegisterAttribute (method.CustomAttributes);
+			var reg_attr = GetRegisterAttribute (method.CustomAttributes, options);
 
 			if (reg_attr is null)
 				return null;
@@ -225,7 +225,7 @@ static void AddReferenceTypeRecursive (JavaTypeModel type, JavaTypeCollection co
 				AddReferenceTypeRecursive (nested, collection);
 		}
 
-		static bool ShouldSkipType (TypeDefinition type, TypeDefinitionCache cache)
+		static bool ShouldSkipType (TypeDefinition type, TypeDefinitionCache cache, ApiImporterOptions options)
 		{
 			// We want to use Java's collection types instead of our managed adapter.
 			// eg: 'Java.Util.ArrayList' over 'Android.Runtime.JavaList'
@@ -246,28 +246,28 @@ static bool ShouldSkipType (TypeDefinition type, TypeDefinitionCache cache)
 				? type.Module.GetType (type.FullName.Substring (0, type.FullName.IndexOf ('`')))
 				: null;
 
-			if (ShouldSkipGeneric (type, non_generic_type, cache))
+			if (ShouldSkipGeneric (type, non_generic_type, cache, options))
 				return true;
 
 			return false;
 		}
 
-		static bool ShouldSkipGeneric (TypeDefinition? a, TypeDefinition? b, TypeDefinitionCache cache)
+		static bool ShouldSkipGeneric (TypeDefinition? a, TypeDefinition? b, TypeDefinitionCache cache, ApiImporterOptions options)
 		{
 			if (a == null || b == null)
 				return false;
 			if (!a.ImplementsInterface ("Android.Runtime.IJavaObject", cache) || !b.ImplementsInterface ("Android.Runtime.IJavaObject", cache))
 				return false;
 
-			return GetRegisteredJavaTypeName (a) == GetRegisteredJavaTypeName (b);
+			return GetRegisteredJavaTypeName (a, options) == GetRegisteredJavaTypeName (b, options);
 		}
 
-		static string? TypeReferenceToJavaType (TypeReference type)
+		static string? TypeReferenceToJavaType (TypeReference type, ApiImporterOptions options)
 		{
-			var retval = GetRegisteredJavaName (type);
+			var retval = GetRegisteredJavaName (type, options);
 
 			if (retval != null && type is GenericInstanceType generic) {
-				var parameters = generic.GenericArguments.Select (ga => GetRegisteredJavaName (ga.Resolve ())).ToArray ();
+				var parameters = generic.GenericArguments.Select (ga => GetRegisteredJavaName (ga.Resolve (), options)).ToArray ();
 
 				if (parameters.WhereNotNull ().Any ())
 					retval += $"<{string.Join (", ", parameters.WhereNotNull ())}>";
@@ -276,14 +276,14 @@ static bool ShouldSkipGeneric (TypeDefinition? a, TypeDefinition? b, TypeDefinit
 			return retval;
 		}
 
-		static string? GetRegisteredJavaName (TypeReference type)
+		static string? GetRegisteredJavaName (TypeReference type, ApiImporterOptions options)
 		{
 			var td = type.Resolve ();
 
-			return GetRegisteredJavaTypeName (td);
+			return GetRegisteredJavaTypeName (td, options);
 		}
 
-		static void ParseImplementedInterfaces (TypeDefinition type, JavaTypeModel model)
+		static void ParseImplementedInterfaces (TypeDefinition type, JavaTypeModel model, ApiImporterOptions options)
 		{
 			foreach (var iface_impl in type.Interfaces) {
 				var iface = iface_impl.InterfaceType;
@@ -292,7 +292,7 @@ static void ParseImplementedInterfaces (TypeDefinition type, JavaTypeModel model
 				if (iface_def is null || iface_def.IsNotPublic)
 					continue;
 
-				if (GetRegisterAttribute (iface_def.CustomAttributes) is CustomAttribute reg_attr) {
+				if (GetRegisterAttribute (iface_def.CustomAttributes, options) is CustomAttribute reg_attr) {
 					var jni = (string) reg_attr.ConstructorArguments [0].Value;
 					var name = jni.Replace ('/', '.').Replace ('$', '.');
 
@@ -301,7 +301,7 @@ static void ParseImplementedInterfaces (TypeDefinition type, JavaTypeModel model
 			}
 		}
 
-		static string GetBaseTypeJni (TypeDefinition type)
+		static string GetBaseTypeJni (TypeDefinition type, ApiImporterOptions options)
 		{
 			// Find a Java base type, ignoring generic types, if nothing else it will be Java.Lang.Object
 			TypeDefinition? base_type = type;
@@ -319,7 +319,7 @@ static string GetBaseTypeJni (TypeDefinition type)
 				if (base_type.HasGenericParameters || base_type.IsGenericInstance)
 					continue;
 
-				if (GetRegisterAttribute (base_type.CustomAttributes) is CustomAttribute reg_attr)
+				if (GetRegisterAttribute (base_type.CustomAttributes, options) is CustomAttribute reg_attr)
 					return (string) reg_attr.ConstructorArguments [0].Value;
 			}
 
@@ -329,19 +329,19 @@ static string GetBaseTypeJni (TypeDefinition type)
 		static CustomAttribute? GetObsoleteAttribute (Collection<CustomAttribute> attributes) =>
 			attributes.FirstOrDefault (a => a.AttributeType.FullNameCorrected () == "System.ObsoleteAttribute");
 
-		static CustomAttribute? GetRegisterAttribute (Collection<CustomAttribute> attributes) =>
+		static CustomAttribute? GetRegisterAttribute (Collection<CustomAttribute> attributes, ApiImporterOptions options) =>
 			attributes.FirstOrDefault (a => {
 				var attrType    = a.AttributeType.FullNameCorrected ();
-				return attrType == "Android.Runtime.RegisterAttribute" ||
-					attrType == "Java.Interop.JniTypeSignatureAttribute";
+
+				return options.SupportedRegisterAttributes.Contains (attrType);
 			});
 
-		static string? GetRegisteredJavaTypeName (TypeDefinition type)
+		static string? GetRegisteredJavaTypeName (TypeDefinition type, ApiImporterOptions options)
 		{
 			if (GetSpecialCase (type) is string s)
 				return s;
 
-			if (GetRegisterAttribute (type.CustomAttributes) is CustomAttribute reg_attr)
+			if (GetRegisterAttribute (type.CustomAttributes, options) is CustomAttribute reg_attr)
 				return ((string) reg_attr.ConstructorArguments [0].Value).Replace ('/', '.');
 
 			return null;
diff --git a/src/Java.Interop.Tools.JavaTypeSystem/Java.Interop.Tools.JavaTypeSystem.csproj b/src/Java.Interop.Tools.JavaTypeSystem/Java.Interop.Tools.JavaTypeSystem.csproj
index bce32d0ca..968d1a813 100644
--- a/src/Java.Interop.Tools.JavaTypeSystem/Java.Interop.Tools.JavaTypeSystem.csproj
+++ b/src/Java.Interop.Tools.JavaTypeSystem/Java.Interop.Tools.JavaTypeSystem.csproj
@@ -3,7 +3,6 @@
   <PropertyGroup>
     <TargetFramework>$(DotNetTargetFramework)</TargetFramework>
     <Nullable>enable</Nullable>
-    <LangVersion>8.0</LangVersion>
   </PropertyGroup>
 
   <Import Project="..\..\TargetFrameworkDependentValues.props" />
diff --git a/tests/generator-Tests/Unit-Tests/ManagedTests.cs b/tests/generator-Tests/Unit-Tests/ManagedTests.cs
index cd24b0b9b..004b2c990 100644
--- a/tests/generator-Tests/Unit-Tests/ManagedTests.cs
+++ b/tests/generator-Tests/Unit-Tests/ManagedTests.cs
@@ -138,7 +138,7 @@ public void Method ()
 		{
 			var type = module.GetType ("Com.Mypackage.Foo");
 			var @class = CecilApiImporter.CreateClass (type, options);
-			var method = CecilApiImporter.CreateMethod (@class, type.Methods.First (m => m.Name == "Bar"));
+			var method = CecilApiImporter.CreateMethod (@class, type.Methods.First (m => m.Name == "Bar"), options);
 			Assert.IsTrue (method.Validate (new CodeGenerationOptions (), new GenericParameterDefinitionList (), new CodeGeneratorContext ()), "method.Validate failed!");
 
 			Assert.AreEqual ("public", method.Visibility);
@@ -159,8 +159,8 @@ public void Method_Matches_True ()
 			var type = module.GetType ("Com.Mypackage.Foo");
 			var @class = CecilApiImporter.CreateClass (type, options);
 			var unknownTypes = type.Methods.First (m => m.Name == "UnknownTypes");
-			var methodA = CecilApiImporter.CreateMethod (@class, unknownTypes);
-			var methodB = CecilApiImporter.CreateMethod (@class, unknownTypes);
+			var methodA = CecilApiImporter.CreateMethod (@class, unknownTypes, options);
+			var methodB = CecilApiImporter.CreateMethod (@class, unknownTypes, options);
 			Assert.IsTrue (methodA.Matches (methodB), "Methods should match!");
 		}
 
@@ -172,8 +172,8 @@ public void Method_Matches_False ()
 			var unknownTypesA = type.Methods.First (m => m.Name == "UnknownTypes");
 			var unknownTypesB = type.Methods.First (m => m.Name == "UnknownTypesReturn");
 			unknownTypesB.Name = "UnknownTypes";
-			var methodA = CecilApiImporter.CreateMethod (@class, unknownTypesA);
-			var methodB = CecilApiImporter.CreateMethod (@class, unknownTypesB);
+			var methodA = CecilApiImporter.CreateMethod (@class, unknownTypesA, options);
+			var methodB = CecilApiImporter.CreateMethod (@class, unknownTypesB, options);
 			//Everything the same besides return type
 			Assert.IsFalse (methodA.Matches (methodB), "Methods should not match!");
 		}
@@ -183,7 +183,7 @@ public void MethodWithParameters ()
 		{
 			var type = module.GetType ("Com.Mypackage.Foo");
 			var @class = CecilApiImporter.CreateClass (type, options);
-			var method = CecilApiImporter.CreateMethod (@class, type.Methods.First (m => m.Name == "BarWithParams"));
+			var method = CecilApiImporter.CreateMethod (@class, type.Methods.First (m => m.Name == "BarWithParams"), options);
 			Assert.IsTrue (method.Validate (new CodeGenerationOptions (), new GenericParameterDefinitionList (), new CodeGeneratorContext ()), "method.Validate failed!");
 			Assert.AreEqual ("(ZID)Ljava/lang/String;", method.JniSignature);
 			Assert.AreEqual ("java.lang.String", method.Return);
@@ -213,7 +213,7 @@ public void Ctor ()
 		{
 			var type = module.GetType ("Com.Mypackage.Foo");
 			var @class = CecilApiImporter.CreateClass (type, options);
-			var ctor = CecilApiImporter.CreateCtor (@class, type.Methods.First (m => m.IsConstructor && !m.IsStatic));
+			var ctor = CecilApiImporter.CreateCtor (@class, type.Methods.First (m => m.IsConstructor && !m.IsStatic), options);
 			Assert.IsTrue (ctor.Validate (new CodeGenerationOptions (), new GenericParameterDefinitionList (), new CodeGeneratorContext ()), "ctor.Validate failed!");
 
 			Assert.AreEqual ("public", ctor.Visibility);
@@ -227,7 +227,7 @@ public void Field ()
 		{
 			var type = module.GetType ("Com.Mypackage.Foo");
 			var @class = CecilApiImporter.CreateClass (type, options);
-			var field = CecilApiImporter.CreateField (type.Fields.First (f => f.Name == "Value"));
+			var field = CecilApiImporter.CreateField (type.Fields.First (f => f.Name == "Value"), options);
 			Assert.IsTrue (field.Validate (new CodeGenerationOptions (), new GenericParameterDefinitionList (), new CodeGeneratorContext ()), "field.Validate failed!");
 
 			Assert.AreEqual ("Value", field.Name);
@@ -279,23 +279,23 @@ public void TypeNullability ()
 			var type = module.GetType ("NullableTestTypes.NullableClass");
 			var gen = CecilApiImporter.CreateClass (module.GetType ("NullableTestTypes.NullableClass"), options);
 
-			var not_null_field = CecilApiImporter.CreateField (type.Fields.First (f => f.Name == "not_null_field"));
+			var not_null_field = CecilApiImporter.CreateField (type.Fields.First (f => f.Name == "not_null_field"), options);
 			Assert.AreEqual (true, not_null_field.NotNull);
 
-			var null_field = CecilApiImporter.CreateField (type.Fields.First (f => f.Name == "null_field"));
+			var null_field = CecilApiImporter.CreateField (type.Fields.First (f => f.Name == "null_field"), options);
 			Assert.AreEqual (false, null_field.NotNull);
 
-			var null_method = CecilApiImporter.CreateMethod (gen, type.Methods.First (f => f.Name == "NullableReturnMethod"));
+			var null_method = CecilApiImporter.CreateMethod (gen, type.Methods.First (f => f.Name == "NullableReturnMethod"), options);
 			Assert.AreEqual (false, null_method.ReturnNotNull);
 			Assert.AreEqual (true, null_method.Parameters.First (f => f.Name == "notnull").NotNull);
 			Assert.AreEqual (false, null_method.Parameters.First (f => f.Name == "nullable").NotNull);
 
-			var not_null_method = CecilApiImporter.CreateMethod (gen, type.Methods.First (f => f.Name == "NotNullReturnMethod"));
+			var not_null_method = CecilApiImporter.CreateMethod (gen, type.Methods.First (f => f.Name == "NotNullReturnMethod"), options);
 			Assert.AreEqual (true, not_null_method.ReturnNotNull);
 			Assert.AreEqual (true, not_null_method.Parameters.First (f => f.Name == "notnull").NotNull);
 			Assert.AreEqual (false, not_null_method.Parameters.First (f => f.Name == "nullable").NotNull);
 
-			var ctor = CecilApiImporter.CreateCtor (gen, type.Methods.First (f => f.Name == ".ctor"));
+			var ctor = CecilApiImporter.CreateCtor (gen, type.Methods.First (f => f.Name == ".ctor"), options);
 			Assert.AreEqual (true, ctor.Parameters.First (f => f.Name == "notnull").NotNull);
 			Assert.AreEqual (false, ctor.Parameters.First (f => f.Name == "nullable").NotNull);
 		}
diff --git a/tools/generator/CodeGenerator.cs b/tools/generator/CodeGenerator.cs
index 927b4e24e..f7dcd14f4 100644
--- a/tools/generator/CodeGenerator.cs
+++ b/tools/generator/CodeGenerator.cs
@@ -113,7 +113,7 @@ static void Run (CodeGeneratorOptions options, DirectoryAssemblyResolver resolve
 			// Resolve types using Java.Interop.Tools.JavaTypeSystem
 			if (is_classparse && !options.UseLegacyJavaResolver) {
 				var output_xml = api_xml_adjuster_output ?? Path.Combine (Path.GetDirectoryName (filename), Path.GetFileName (filename) + ".adjusted");
-				JavaTypeResolutionFixups.Fixup (filename, output_xml, resolver, references.Distinct ().ToArray (), resolverCache);
+				JavaTypeResolutionFixups.Fixup (filename, output_xml, resolver, references.Distinct ().ToArray (), resolverCache, options);
 
 				if (only_xml_adjuster)
 					return;
diff --git a/tools/generator/Java.Interop.Tools.Generator.Importers/CecilApiImporter.cs b/tools/generator/Java.Interop.Tools.Generator.Importers/CecilApiImporter.cs
index ae9fc3fbf..377ec97ee 100644
--- a/tools/generator/Java.Interop.Tools.Generator.Importers/CecilApiImporter.cs
+++ b/tools/generator/Java.Interop.Tools.Generator.Importers/CecilApiImporter.cs
@@ -31,19 +31,19 @@ public static ClassGen CreateClass (TypeDefinition t, CodeGenerationOptions opt)
 				var implements_charsequence = t.Interfaces.Any (it => it.InterfaceType.FullName == "Java.Lang.CharSequence");
 
 				foreach (var m in t.Methods) {
-					if (m.IsPrivate || m.IsAssembly || GetRegisterAttribute (m.CustomAttributes) == null)
+					if (m.IsPrivate || m.IsAssembly || GetRegisterAttribute (m.CustomAttributes, opt) == null)
 						continue;
 					if (implements_charsequence && t.Methods.Any (mm => mm.Name == m.Name + "Formatted"))
 						continue;
 					if (m.IsConstructor)
-						klass.Ctors.Add (CreateCtor (klass, m));
+						klass.Ctors.Add (CreateCtor (klass, m, opt));
 					else
-						klass.AddMethod (CreateMethod (klass, m));
+						klass.AddMethod (CreateMethod (klass, m, opt));
 				}
 
 				foreach (var f in t.Fields)
-					if (!f.IsPrivate && GetRegisterAttribute (f.CustomAttributes) == null)
-						klass.AddField (CreateField (f));
+					if (!f.IsPrivate && GetRegisterAttribute (f.CustomAttributes, opt) == null)
+						klass.AddField (CreateField (f, opt));
 			};
 
 			if (klass.IsShallow)
@@ -61,9 +61,9 @@ public static ClassGen CreateClass (TypeDefinition t, CodeGenerationOptions opt)
 			return klass;
 		}
 
-		public static Ctor CreateCtor (GenBase declaringType, MethodDefinition m)
+		public static Ctor CreateCtor (GenBase declaringType, MethodDefinition m, CodeGenerationOptions opt)
 		{
-			var reg_attr = GetRegisterAttribute (m.CustomAttributes);
+			var reg_attr = GetRegisterAttribute (m.CustomAttributes, opt);
 
 			var ctor = new Ctor (declaringType) {
 				AssemblyName = m.DeclaringType.Module.Assembly.FullName,
@@ -88,10 +88,10 @@ public static Ctor CreateCtor (GenBase declaringType, MethodDefinition m)
 			return ctor;
 		}
 
-		public static Field CreateField (FieldDefinition f)
+		public static Field CreateField (FieldDefinition f, CodeGenerationOptions opt)
 		{
 			var obs_attr = GetObsoleteAttribute (f.CustomAttributes);
-			var reg_attr = GetRegisterAttribute (f.CustomAttributes);
+			var reg_attr = GetRegisterAttribute (f.CustomAttributes, opt);
 
 			var field = new Field {
 				DeprecatedComment = GetObsoleteComment (obs_attr),
@@ -117,7 +117,7 @@ public static Field CreateField (FieldDefinition f)
 		public static GenBaseSupport CreateGenBaseSupport (TypeDefinition t, CodeGenerationOptions opt)
 		{
 			var obs_attr = GetObsoleteAttribute (t.CustomAttributes);
-			var reg_attr = GetRegisterAttribute (t.CustomAttributes);
+			var reg_attr = GetRegisterAttribute (t.CustomAttributes, opt);
 
 			var jn = reg_attr != null ? ((string) reg_attr.ConstructorArguments [0].Value).Replace ('/', '.') : t.FullNameCorrected ();
 			var idx = jn.LastIndexOf ('.');
@@ -164,10 +164,10 @@ public static InterfaceGen CreateInterface (TypeDefinition t, CodeGenerationOpti
 
 			Action populate = () => {
 				foreach (var m in t.Methods) {
-					if (m.IsPrivate || m.IsAssembly || GetRegisterAttribute (m.CustomAttributes) == null)
+					if (m.IsPrivate || m.IsAssembly || GetRegisterAttribute (m.CustomAttributes, opt) == null)
 						continue;
 
-					iface.AddMethod (CreateMethod (iface, m));
+					iface.AddMethod (CreateMethod (iface, m, opt));
 				}
 			};
 
@@ -181,9 +181,9 @@ public static InterfaceGen CreateInterface (TypeDefinition t, CodeGenerationOpti
 			return iface;
 		}
 
-		public static Method CreateMethod (GenBase declaringType, MethodDefinition m)
+		public static Method CreateMethod (GenBase declaringType, MethodDefinition m, CodeGenerationOptions opt)
 		{
-			var reg_attr = GetRegisterAttribute (m.CustomAttributes);
+			var reg_attr = GetRegisterAttribute (m.CustomAttributes, opt);
 
 			var method = new Method (declaringType) {
 				AssemblyName = m.DeclaringType.Module.Assembly.FullName,
@@ -249,11 +249,17 @@ static CustomAttribute GetObsoleteAttribute (Collection<CustomAttribute> attribu
 		static string GetObsoleteComment (CustomAttribute attribute) =>
 			attribute?.ConstructorArguments.Any () == true ? (string) attribute.ConstructorArguments [0].Value : null;
 
-		static CustomAttribute GetRegisterAttribute (Collection<CustomAttribute> attributes) =>
+		static CustomAttribute GetRegisterAttribute (Collection<CustomAttribute> attributes, CodeGenerationOptions opt) =>
 			attributes.FirstOrDefault (a => {
 				var attrType    = a.AttributeType.FullNameCorrected ();
-				return attrType == "Android.Runtime.RegisterAttribute" ||
-					attrType == "Java.Interop.JniTypeSignatureAttribute";
+
+				if (attrType == "Android.Runtime.RegisterAttribute")
+					return true;
+
+				if (opt.CodeGenerationTarget == Xamarin.Android.Binder.CodeGenerationTarget.JavaInterop1 && attrType == "Java.Interop.JniTypeSignatureAttribute")
+					return true;
+
+				return false;
 			});
 
 		static bool IsDefaultInterfaceMethod (GenBase declaringType, MethodDefinition method)
diff --git a/tools/generator/Java.Interop.Tools.Generator.Transformation/JavaTypeResolutionFixups.cs b/tools/generator/Java.Interop.Tools.Generator.Transformation/JavaTypeResolutionFixups.cs
index 71b0c2b0b..c2bc4a5dd 100644
--- a/tools/generator/Java.Interop.Tools.Generator.Transformation/JavaTypeResolutionFixups.cs
+++ b/tools/generator/Java.Interop.Tools.Generator.Transformation/JavaTypeResolutionFixups.cs
@@ -4,6 +4,7 @@
 using Java.Interop.Tools.Cecil;
 using Java.Interop.Tools.Generator;
 using Java.Interop.Tools.JavaTypeSystem;
+using Xamarin.Android.Binder;
 
 namespace generator
 {
@@ -14,17 +15,21 @@ public static class JavaTypeResolutionFixups
 
 		// This fixup ensures all referenced Java types can be resolved, and
 		// removes types and members that rely on unresolvable Java types.
-		public static void Fixup (string xmlFile, string outputXmlFile, DirectoryAssemblyResolver resolver, string [] references, TypeDefinitionCache cache)
+		public static void Fixup (string xmlFile, string outputXmlFile, DirectoryAssemblyResolver resolver, string [] references, TypeDefinitionCache cache, CodeGeneratorOptions opt)
 		{
 			// Parse api.xml
 			var type_collection = JavaXmlApiImporter.Parse (xmlFile);
+			var options = new ApiImporterOptions ();
+
+			if (opt.CodeGenerationTarget == CodeGenerationTarget.JavaInterop1)
+				options.SupportedRegisterAttributes.Add ("Java.Interop.JniTypeSignatureAttribute");
 
 			// Add in reference types from assemblies
 			foreach (var reference in references.Distinct ()) {
 				Report.Verbose (0, "Resolving assembly for Java type resolution: '{0}'.", reference);
 				var assembly = resolver.Load (reference);
 
-				ManagedApiImporter.Parse (assembly, type_collection, cache);
+				ManagedApiImporter.Parse (assembly, type_collection, cache, options);
 			}
 
 			// Run the type resolution pass

From 5db0525895e55febd0c6cdb321d98aeb41bbd853 Mon Sep 17 00:00:00 2001
From: Jonathan Pobst <jonathan.pobst@microsoft.com>
Date: Tue, 15 Oct 2024 09:57:31 -1000
Subject: [PATCH 2/3] Address review feedback.

---
 .../Adapters/ApiImporterOptions.cs                              | 2 +-
 .../Adapters/ManagedApiImporter.cs                              | 2 +-
 .../JavaTypeResolutionFixups.cs                                 | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/Java.Interop.Tools.JavaTypeSystem/Adapters/ApiImporterOptions.cs b/src/Java.Interop.Tools.JavaTypeSystem/Adapters/ApiImporterOptions.cs
index 7778f3527..4c5160788 100644
--- a/src/Java.Interop.Tools.JavaTypeSystem/Adapters/ApiImporterOptions.cs
+++ b/src/Java.Interop.Tools.JavaTypeSystem/Adapters/ApiImporterOptions.cs
@@ -5,5 +5,5 @@ namespace Java.Interop.Tools.JavaTypeSystem;
 
 public class ApiImporterOptions
 {
-	public Collection<string> SupportedRegisterAttributes { get; } = ["Android.Runtime.RegisterAttribute"];
+	public Collection<string> SupportedTypeMapAttributes { get; } = ["Android.Runtime.RegisterAttribute"];
 }
diff --git a/src/Java.Interop.Tools.JavaTypeSystem/Adapters/ManagedApiImporter.cs b/src/Java.Interop.Tools.JavaTypeSystem/Adapters/ManagedApiImporter.cs
index 41e57b56a..908485d58 100644
--- a/src/Java.Interop.Tools.JavaTypeSystem/Adapters/ManagedApiImporter.cs
+++ b/src/Java.Interop.Tools.JavaTypeSystem/Adapters/ManagedApiImporter.cs
@@ -333,7 +333,7 @@ static string GetBaseTypeJni (TypeDefinition type, ApiImporterOptions options)
 			attributes.FirstOrDefault (a => {
 				var attrType    = a.AttributeType.FullNameCorrected ();
 
-				return options.SupportedRegisterAttributes.Contains (attrType);
+				return options.SupportedTypeMapAttributes.Contains (attrType);
 			});
 
 		static string? GetRegisteredJavaTypeName (TypeDefinition type, ApiImporterOptions options)
diff --git a/tools/generator/Java.Interop.Tools.Generator.Transformation/JavaTypeResolutionFixups.cs b/tools/generator/Java.Interop.Tools.Generator.Transformation/JavaTypeResolutionFixups.cs
index c2bc4a5dd..dc3ec63fb 100644
--- a/tools/generator/Java.Interop.Tools.Generator.Transformation/JavaTypeResolutionFixups.cs
+++ b/tools/generator/Java.Interop.Tools.Generator.Transformation/JavaTypeResolutionFixups.cs
@@ -22,7 +22,7 @@ public static void Fixup (string xmlFile, string outputXmlFile, DirectoryAssembl
 			var options = new ApiImporterOptions ();
 
 			if (opt.CodeGenerationTarget == CodeGenerationTarget.JavaInterop1)
-				options.SupportedRegisterAttributes.Add ("Java.Interop.JniTypeSignatureAttribute");
+				options.SupportedTypeMapAttributes.Add ("Java.Interop.JniTypeSignatureAttribute");
 
 			// Add in reference types from assemblies
 			foreach (var reference in references.Distinct ()) {

From 964543ee454047a4d93790e477cfd51610bd6cef Mon Sep 17 00:00:00 2001
From: Jonathan Pryor <jonpryor@vt.edu>
Date: Thu, 17 Oct 2024 15:45:10 -0400
Subject: [PATCH 3/3] Make the label match the contents

The dotnet/java-interop#1266 summary says:

> Only use `[JniTypeSignatureAttribute]` for JavaInterop1

*Actually* do so: for XAJavaInterop1, don't allow `[JniTypeSignatureAttribute]`.
For JavaInterop1, don't allow [Register].

Eventually we'll want XAJavaInterop1 to import
JniTypeSignatureAttribute (maybe?), but not now.
---
 .../CecilApiImporter.cs                                    | 7 ++++---
 .../JavaTypeResolutionFixups.cs                            | 4 +++-
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/tools/generator/Java.Interop.Tools.Generator.Importers/CecilApiImporter.cs b/tools/generator/Java.Interop.Tools.Generator.Importers/CecilApiImporter.cs
index 377ec97ee..ffcc4cdf9 100644
--- a/tools/generator/Java.Interop.Tools.Generator.Importers/CecilApiImporter.cs
+++ b/tools/generator/Java.Interop.Tools.Generator.Importers/CecilApiImporter.cs
@@ -253,10 +253,11 @@ static CustomAttribute GetRegisterAttribute (Collection<CustomAttribute> attribu
 			attributes.FirstOrDefault (a => {
 				var attrType    = a.AttributeType.FullNameCorrected ();
 
-				if (attrType == "Android.Runtime.RegisterAttribute")
-					return true;
+				if (opt.CodeGenerationTarget == Xamarin.Android.Binder.CodeGenerationTarget.JavaInterop1) {
+					return attrType == "Java.Interop.JniTypeSignatureAttribute";
+				}
 
-				if (opt.CodeGenerationTarget == Xamarin.Android.Binder.CodeGenerationTarget.JavaInterop1 && attrType == "Java.Interop.JniTypeSignatureAttribute")
+				if (attrType == "Android.Runtime.RegisterAttribute")
 					return true;
 
 				return false;
diff --git a/tools/generator/Java.Interop.Tools.Generator.Transformation/JavaTypeResolutionFixups.cs b/tools/generator/Java.Interop.Tools.Generator.Transformation/JavaTypeResolutionFixups.cs
index dc3ec63fb..bf8301457 100644
--- a/tools/generator/Java.Interop.Tools.Generator.Transformation/JavaTypeResolutionFixups.cs
+++ b/tools/generator/Java.Interop.Tools.Generator.Transformation/JavaTypeResolutionFixups.cs
@@ -21,8 +21,10 @@ public static void Fixup (string xmlFile, string outputXmlFile, DirectoryAssembl
 			var type_collection = JavaXmlApiImporter.Parse (xmlFile);
 			var options = new ApiImporterOptions ();
 
-			if (opt.CodeGenerationTarget == CodeGenerationTarget.JavaInterop1)
+			if (opt.CodeGenerationTarget == CodeGenerationTarget.JavaInterop1) {
+				options.SupportedTypeMapAttributes.Clear ();
 				options.SupportedTypeMapAttributes.Add ("Java.Interop.JniTypeSignatureAttribute");
+			}
 
 			// Add in reference types from assemblies
 			foreach (var reference in references.Distinct ()) {