diff --git a/tests/generator-Tests/Unit-Tests/CodeGeneratorTests.cs b/tests/generator-Tests/Unit-Tests/CodeGeneratorTests.cs index a8393c61b..29e4205e1 100644 --- a/tests/generator-Tests/Unit-Tests/CodeGeneratorTests.cs +++ b/tests/generator-Tests/Unit-Tests/CodeGeneratorTests.cs @@ -379,6 +379,34 @@ public void SkipInterfaceInvokerMethodsMetadata () Assert.False (writer.ToString ().Contains ("InvokeAbstractInt32Method"), $"was: `{writer}`"); } + [Test] + public void SkipInterfaceMethodsMetadata () + { + var xml = @"<api> + <package name='java.lang' jni-name='java/lang'> + <class abstract='false' deprecated='not deprecated' final='false' name='Object' static='false' visibility='public' jni-signature='Ljava/lang/Object;' /> + </package> + <package name='com.xamarin.android' jni-name='com/xamarin/android'> + <interface abstract='true' deprecated='not deprecated' extends='java.lang.Object' extends-generic-aware='java.lang.Object' jni-extends='Ljava/lang/Object;' final='false' name='MyInterface' static='false' visibility='public' jni-signature='Lcom/xamarin/android/MyInterface;'> + <method abstract='true' deprecated='not deprecated' final='false' name='countAffectedRows' jni-signature='()I' bridge='false' native='false' return='int' jni-return='I' static='false' synchronized='false' synthetic='false' visibility='public'></method> + </interface> + <class abstract='true' deprecated='not deprecated' extends='java.lang.Object' extends-generic-aware='java.lang.Object' jni-extends='Ljava/lang/Object;' final='false' name='MyBaseClass' static='false' visibility='public' jni-signature='Lcom/xamarin/android/MyBaseClass;' skipInterfaceMethods='com/xamarin/android/MyInterface.countAffectedRows()I'> + <implements name='com.xamarin.android.MyInterface' name-generic-aware='com.xamarin.android.MyInterface' jni-type='Lcom/xamarin/android/MyInterface;'></implements> + </class> + </package> + </api>"; + + var gens = ParseApiDefinition (xml); + var klass = gens.Single (g => g.Name == "MyBaseClass"); + + generator.Context.ContextTypes.Push (klass); + generator.WriteType (klass, string.Empty, new GenerationInfo ("", "", "MyAssembly")); + generator.Context.ContextTypes.Pop (); + + // The abstract method should not get generated because we are suppressing it with 'skipInterfaceMethods' + Assert.False (writer.ToString ().Contains ("public abstract int CountAffectedRows ();"), $"was: `{writer}`"); + } + [Test] public void CompatVirtualMethod_Class () { diff --git a/tools/generator/Java.Interop.Tools.Generator.Importers/XmlApiImporter.cs b/tools/generator/Java.Interop.Tools.Generator.Importers/XmlApiImporter.cs index fc2b8415a..901f235e8 100644 --- a/tools/generator/Java.Interop.Tools.Generator.Importers/XmlApiImporter.cs +++ b/tools/generator/Java.Interop.Tools.Generator.Importers/XmlApiImporter.cs @@ -147,6 +147,10 @@ public static ClassGen CreateClass (XElement pkg, XElement elem, CodeGenerationO } } + if (elem.Attribute ("skipInterfaceMethods")?.Value is string skip) + foreach (var m in skip.Split (new char [] { ',', ' ', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries)) + klass.SkippedInterfaceMethods.Add (m); + return klass; } diff --git a/tools/generator/Java.Interop.Tools.Generator.ObjectModel/ClassGen.cs b/tools/generator/Java.Interop.Tools.Generator.ObjectModel/ClassGen.cs index fca4acf47..0514123bf 100644 --- a/tools/generator/Java.Interop.Tools.Generator.ObjectModel/ClassGen.cs +++ b/tools/generator/Java.Interop.Tools.Generator.ObjectModel/ClassGen.cs @@ -11,6 +11,7 @@ namespace MonoDroid.Generation public class ClassGen : GenBase { bool fill_explicit_implementation_started; + HashSet<string> skipped_interface_methods; public List<Ctor> Ctors { get; private set; } = new List<Ctor> (); @@ -355,6 +356,8 @@ public override void ResetValidation () base.ResetValidation (); } + public HashSet<string> SkippedInterfaceMethods => skipped_interface_methods ??= new HashSet<string> (); + public override string ToNative (CodeGenerationOptions opt, string varname, Dictionary<string, string> mappings = null) { if (opt.CodeGenerationTarget == CodeGenerationTarget.JavaInterop1) { diff --git a/tools/generator/SourceWriters/BoundClass.cs b/tools/generator/SourceWriters/BoundClass.cs index 669692340..752f64c56 100644 --- a/tools/generator/SourceWriters/BoundClass.cs +++ b/tools/generator/SourceWriters/BoundClass.cs @@ -221,6 +221,8 @@ void AddInterfaceAbstractMembers (ClassGen klass, InterfaceGen iface, CodeGenera if (context.ContextGeneratedMethods.Any (_ => _.Name == method.Name && _.JniSignature == method.JniSignature)) continue; + if (klass.SkippedInterfaceMethods.Contains (method.GetSkipInvokerSignature ())) + continue; for (var cls = klass; cls != null; cls = cls.BaseGen) if (cls.ContainsMethod (method, false) || cls != klass && klass.ExplicitlyImplementedInterfaceMethods.Contains (sig)) {