From a6314e6fdf30afa674ab10c905aec4bfc0c468f3 Mon Sep 17 00:00:00 2001 From: Atsushi Eno Date: Wed, 7 Jun 2017 00:19:14 +0900 Subject: [PATCH] [generator] do not generate identical methods to previously generated ones. There are classes that implement more than one interfaces that share an identical methods (which share the same name and the same JNI signature). For example, java.nio.AsynchronousFileChannel implements Closeable and AsynchronousChannel, both of which contain `close()` method. Only one `Close()` should be generated for that class. --- tools/generator/ClassGen.cs | 10 +- tools/generator/CodeGenerator.cs | 1 + tools/generator/InterfaceGen.cs | 3 + .../Tests/InterfaceMethodsConflict.cs | 19 +++ .../InterfaceMethodsConflict.xml | 25 ++++ .../Java.Interop.__TypeRegistrations.cs | 34 ++++++ .../Java.Lang.Object.cs | 13 +++ .../Xamarin.Test.II1.cs | 95 +++++++++++++++ .../Xamarin.Test.II2.cs | 95 +++++++++++++++ .../Xamarin.Test.SomeObject.cs | 61 ++++++++++ .../Xamarin.Test.SomeObject2.cs | 110 ++++++++++++++++++ .../__NamespaceMapping__.cs | 2 + tools/generator/Tests/expected.targets | 12 ++ .../InterfaceMethodsConflict.xml | 35 ++++++ .../Java.Interop.__TypeRegistrations.cs | 34 ++++++ .../Java.Lang.Object.cs | 12 ++ .../Xamarin.Test.II1.cs | 86 ++++++++++++++ .../Xamarin.Test.II2.cs | 86 ++++++++++++++ .../Xamarin.Test.SomeObject.cs | 62 ++++++++++ .../Xamarin.Test.SomeObject2.cs | 107 +++++++++++++++++ .../__NamespaceMapping__.cs | 2 + tools/generator/Tests/generator-Tests.csproj | 1 + 22 files changed, 902 insertions(+), 3 deletions(-) create mode 100644 tools/generator/Tests/InterfaceMethodsConflict.cs create mode 100644 tools/generator/Tests/expected.ji/InterfaceMethodsConflict/InterfaceMethodsConflict.xml create mode 100644 tools/generator/Tests/expected.ji/InterfaceMethodsConflict/Java.Interop.__TypeRegistrations.cs create mode 100644 tools/generator/Tests/expected.ji/InterfaceMethodsConflict/Java.Lang.Object.cs create mode 100644 tools/generator/Tests/expected.ji/InterfaceMethodsConflict/Xamarin.Test.II1.cs create mode 100644 tools/generator/Tests/expected.ji/InterfaceMethodsConflict/Xamarin.Test.II2.cs create mode 100644 tools/generator/Tests/expected.ji/InterfaceMethodsConflict/Xamarin.Test.SomeObject.cs create mode 100644 tools/generator/Tests/expected.ji/InterfaceMethodsConflict/Xamarin.Test.SomeObject2.cs create mode 100644 tools/generator/Tests/expected.ji/InterfaceMethodsConflict/__NamespaceMapping__.cs create mode 100644 tools/generator/Tests/expected/InterfaceMethodsConflict/InterfaceMethodsConflict.xml create mode 100644 tools/generator/Tests/expected/InterfaceMethodsConflict/Java.Interop.__TypeRegistrations.cs create mode 100644 tools/generator/Tests/expected/InterfaceMethodsConflict/Java.Lang.Object.cs create mode 100644 tools/generator/Tests/expected/InterfaceMethodsConflict/Xamarin.Test.II1.cs create mode 100644 tools/generator/Tests/expected/InterfaceMethodsConflict/Xamarin.Test.II2.cs create mode 100644 tools/generator/Tests/expected/InterfaceMethodsConflict/Xamarin.Test.SomeObject.cs create mode 100644 tools/generator/Tests/expected/InterfaceMethodsConflict/Xamarin.Test.SomeObject2.cs create mode 100644 tools/generator/Tests/expected/InterfaceMethodsConflict/__NamespaceMapping__.cs diff --git a/tools/generator/ClassGen.cs b/tools/generator/ClassGen.cs index 3fc23fb09..465839647 100644 --- a/tools/generator/ClassGen.cs +++ b/tools/generator/ClassGen.cs @@ -313,9 +313,7 @@ public override ClassGen BaseGen { void GenerateAbstractMembers (StreamWriter sw, string indent, CodeGenerationOptions opt) { foreach (InterfaceGen gen in GetAllDerivedInterfaces ()) - // FIXME: this is an ugly workaround for bug in generator that generates extraneous member. - if (FullName != "Android.Views.Animations.BaseInterpolator" || gen.FullName != "Android.Views.Animations.IInterpolator") - gen.GenerateAbstractMembers (this, sw, indent, opt); + gen.GenerateAbstractMembers (this, sw, indent, opt); } void GenMethods (StreamWriter sw, string indent, CodeGenerationOptions opt) @@ -339,6 +337,7 @@ void GenMethods (StreamWriter sw, string indent, CodeGenerationOptions opt) m.GenerateAbstractDeclaration (sw, indent, opt, null, this); else m.Generate (sw, indent, opt, this, true); + opt.ContextGeneratedMethods.Add (m); m.IsVirtual = virt; } @@ -371,6 +370,8 @@ void GenProperties (StreamWriter sw, string indent, CodeGenerationOptions opt) public override void Generate (StreamWriter sw, string indent, CodeGenerationOptions opt, GenerationInfo gen_info) { opt.ContextTypes.Push (this); + opt.ContextGeneratedMethods = new List (); + gen_info.TypeRegistrations.Add (new KeyValuePair(RawJniName, AssemblyQualifiedName)); bool is_enum = base_symbol != null && base_symbol.FullName == "Java.Lang.Enum"; if (is_enum) @@ -497,6 +498,9 @@ public override void Generate (StreamWriter sw, string indent, CodeGenerationOpt sw.WriteLine (); GenerateInvoker (sw, indent, opt); } + + opt.ContextGeneratedMethods.Clear (); + opt.ContextTypes.Pop (); } diff --git a/tools/generator/CodeGenerator.cs b/tools/generator/CodeGenerator.cs index 04efe9250..1207f1d61 100644 --- a/tools/generator/CodeGenerator.cs +++ b/tools/generator/CodeGenerator.cs @@ -560,6 +560,7 @@ public class CodeGenerationOptions public Stack ContextTypes { get { return context_types; } } + public List ContextGeneratedMethods { get; set; } = new List (); public GenBase ContextType { get { return context_types.Any () ? context_types.Peek () : null; } } diff --git a/tools/generator/InterfaceGen.cs b/tools/generator/InterfaceGen.cs index f17c765e5..87e5d40a6 100644 --- a/tools/generator/InterfaceGen.cs +++ b/tools/generator/InterfaceGen.cs @@ -620,6 +620,8 @@ public void GenerateAbstractMembers (ClassGen gen, StreamWriter sw, string inden foreach (Method m in Methods.Where (m => !m.IsInterfaceDefaultMethod && !m.IsStatic)) { bool mapped = false; string sig = m.GetSignature (); + if (opt.ContextGeneratedMethods.Any (_ => _.Name == m.Name && _.JniSignature == m.JniSignature)) + continue; for (var cls = gen; cls != null; cls = cls.BaseGen) if (cls.ContainsMethod (m, false) || cls != gen && gen.ExplicitlyImplementedInterfaceMethods.Contains (sig)) { mapped = true; @@ -631,6 +633,7 @@ public void GenerateAbstractMembers (ClassGen gen, StreamWriter sw, string inden m.GenerateExplicitInterfaceImplementation (sw, indent, opt, this); else m.GenerateAbstractDeclaration (sw, indent, opt, this, gen); + opt.ContextGeneratedMethods.Add (m); } foreach (Property prop in Properties) { if (gen.ContainsProperty (prop.Name, false)) diff --git a/tools/generator/Tests/InterfaceMethodsConflict.cs b/tools/generator/Tests/InterfaceMethodsConflict.cs new file mode 100644 index 000000000..36b5c9b95 --- /dev/null +++ b/tools/generator/Tests/InterfaceMethodsConflict.cs @@ -0,0 +1,19 @@ +using System; +using NUnit.Framework; + +namespace generatortests +{ + [TestFixture] + public class InterfaceMethodsConflict : BaseGeneratorTest + { + [Test] + public void GeneratedOK () + { + RunAllTargets ( + outputRelativePath: "InterfaceMethodsConflict", + apiDescriptionFile: "expected/InterfaceMethodsConflict/InterfaceMethodsConflict.xml", + expectedRelativePath: "InterfaceMethodsConflict"); + } + } +} + diff --git a/tools/generator/Tests/expected.ji/InterfaceMethodsConflict/InterfaceMethodsConflict.xml b/tools/generator/Tests/expected.ji/InterfaceMethodsConflict/InterfaceMethodsConflict.xml new file mode 100644 index 000000000..703f91b24 --- /dev/null +++ b/tools/generator/Tests/expected.ji/InterfaceMethodsConflict/InterfaceMethodsConflict.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/generator/Tests/expected.ji/InterfaceMethodsConflict/Java.Interop.__TypeRegistrations.cs b/tools/generator/Tests/expected.ji/InterfaceMethodsConflict/Java.Interop.__TypeRegistrations.cs new file mode 100644 index 000000000..6008ae6da --- /dev/null +++ b/tools/generator/Tests/expected.ji/InterfaceMethodsConflict/Java.Interop.__TypeRegistrations.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using Android.Runtime; + +namespace Java.Interop { + + partial class __TypeRegistrations { + + public static void RegisterPackages () + { +#if MONODROID_TIMING + var start = DateTime.Now; + Android.Util.Log.Info ("MonoDroid-Timing", "RegisterPackages start: " + (start - new DateTime (1970, 1, 1)).TotalMilliseconds); +#endif // def MONODROID_TIMING + Java.Interop.TypeManager.RegisterPackages ( + new string[]{ + }, + new Converter[]{ + }); +#if MONODROID_TIMING + var end = DateTime.Now; + Android.Util.Log.Info ("MonoDroid-Timing", "RegisterPackages time: " + (end - new DateTime (1970, 1, 1)).TotalMilliseconds + " [elapsed: " + (end - start).TotalMilliseconds + " ms]"); +#endif // def MONODROID_TIMING + } + + static Type Lookup (string[] mappings, string javaType) + { + string managedType = Java.Interop.TypeManager.LookupTypeMapping (mappings, javaType); + if (managedType == null) + return null; + return Type.GetType (managedType); + } + } +} diff --git a/tools/generator/Tests/expected.ji/InterfaceMethodsConflict/Java.Lang.Object.cs b/tools/generator/Tests/expected.ji/InterfaceMethodsConflict/Java.Lang.Object.cs new file mode 100644 index 000000000..af30ec490 --- /dev/null +++ b/tools/generator/Tests/expected.ji/InterfaceMethodsConflict/Java.Lang.Object.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using Android.Runtime; +using Java.Interop; + +namespace Java.Lang { + + // Metadata.xml XPath class reference: path="/api/package[@name='java.lang']/class[@name='Object']" + [global::Android.Runtime.Register ("java/lang/Object", DoNotGenerateAcw=true)] + public partial class Object { + + } +} diff --git a/tools/generator/Tests/expected.ji/InterfaceMethodsConflict/Xamarin.Test.II1.cs b/tools/generator/Tests/expected.ji/InterfaceMethodsConflict/Xamarin.Test.II1.cs new file mode 100644 index 000000000..957ad6f4d --- /dev/null +++ b/tools/generator/Tests/expected.ji/InterfaceMethodsConflict/Xamarin.Test.II1.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using Android.Runtime; +using Java.Interop; + +namespace Xamarin.Test { + + // Metadata.xml XPath interface reference: path="/api/package[@name='xamarin.test']/interface[@name='I1']" + [Register ("xamarin/test/I1", "", "Xamarin.Test.II1Invoker")] + public partial interface II1 : IJavaObject { + + // Metadata.xml XPath method reference: path="/api/package[@name='xamarin.test']/interface[@name='I1']/method[@name='close' and count(parameter)=0]" + [Register ("close", "()V", "GetCloseHandler:Xamarin.Test.II1Invoker, Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null")] + void Close (); + + } + + [global::Android.Runtime.Register ("xamarin/test/I1", DoNotGenerateAcw=true)] + internal class II1Invoker : global::Java.Lang.Object, II1 { + + internal new static readonly JniPeerMembers _members = new JniPeerMembers ("xamarin/test/I1", typeof (II1Invoker)); + + static IntPtr java_class_ref { + get { return _members.JniPeerType.PeerReference.Handle; } + } + + public override global::Java.Interop.JniPeerMembers JniPeerMembers { + get { return _members; } + } + + protected override IntPtr ThresholdClass { + get { return class_ref; } + } + + protected override global::System.Type ThresholdType { + get { return _members.ManagedPeerType; } + } + + IntPtr class_ref; + + public static II1 GetObject (IntPtr handle, JniHandleOwnership transfer) + { + return global::Java.Lang.Object.GetObject (handle, transfer); + } + + static IntPtr Validate (IntPtr handle) + { + if (!JNIEnv.IsInstanceOf (handle, java_class_ref)) + throw new InvalidCastException (string.Format ("Unable to convert instance of type '{0}' to type '{1}'.", + JNIEnv.GetClassNameFromInstance (handle), "xamarin.test.I1")); + return handle; + } + + protected override void Dispose (bool disposing) + { + if (this.class_ref != IntPtr.Zero) + JNIEnv.DeleteGlobalRef (this.class_ref); + this.class_ref = IntPtr.Zero; + base.Dispose (disposing); + } + + public II1Invoker (IntPtr handle, JniHandleOwnership transfer) : base (Validate (handle), transfer) + { + IntPtr local_ref = JNIEnv.GetObjectClass (((global::Java.Lang.Object) this).Handle); + this.class_ref = JNIEnv.NewGlobalRef (local_ref); + JNIEnv.DeleteLocalRef (local_ref); + } + + static Delegate cb_close; +#pragma warning disable 0169 + static Delegate GetCloseHandler () + { + if (cb_close == null) + cb_close = JNINativeWrapper.CreateDelegate ((Action) n_Close); + return cb_close; + } + + static void n_Close (IntPtr jnienv, IntPtr native__this) + { + global::Xamarin.Test.II1 __this = global::Java.Lang.Object.GetObject (jnienv, native__this, JniHandleOwnership.DoNotTransfer); + __this.Close (); + } +#pragma warning restore 0169 + + IntPtr id_close; + public unsafe void Close () + { + if (id_close == IntPtr.Zero) + id_close = JNIEnv.GetMethodID (class_ref, "close", "()V"); + JNIEnv.CallVoidMethod (((global::Java.Lang.Object) this).Handle, id_close); + } + + } + +} diff --git a/tools/generator/Tests/expected.ji/InterfaceMethodsConflict/Xamarin.Test.II2.cs b/tools/generator/Tests/expected.ji/InterfaceMethodsConflict/Xamarin.Test.II2.cs new file mode 100644 index 000000000..6239407f1 --- /dev/null +++ b/tools/generator/Tests/expected.ji/InterfaceMethodsConflict/Xamarin.Test.II2.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using Android.Runtime; +using Java.Interop; + +namespace Xamarin.Test { + + // Metadata.xml XPath interface reference: path="/api/package[@name='xamarin.test']/interface[@name='I2']" + [Register ("xamarin/test/I2", "", "Xamarin.Test.II2Invoker")] + public partial interface II2 : IJavaObject { + + // Metadata.xml XPath method reference: path="/api/package[@name='xamarin.test']/interface[@name='I2']/method[@name='close' and count(parameter)=0]" + [Register ("close", "()V", "GetCloseHandler:Xamarin.Test.II2Invoker, Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null")] + void Close (); + + } + + [global::Android.Runtime.Register ("xamarin/test/I2", DoNotGenerateAcw=true)] + internal class II2Invoker : global::Java.Lang.Object, II2 { + + internal new static readonly JniPeerMembers _members = new JniPeerMembers ("xamarin/test/I2", typeof (II2Invoker)); + + static IntPtr java_class_ref { + get { return _members.JniPeerType.PeerReference.Handle; } + } + + public override global::Java.Interop.JniPeerMembers JniPeerMembers { + get { return _members; } + } + + protected override IntPtr ThresholdClass { + get { return class_ref; } + } + + protected override global::System.Type ThresholdType { + get { return _members.ManagedPeerType; } + } + + IntPtr class_ref; + + public static II2 GetObject (IntPtr handle, JniHandleOwnership transfer) + { + return global::Java.Lang.Object.GetObject (handle, transfer); + } + + static IntPtr Validate (IntPtr handle) + { + if (!JNIEnv.IsInstanceOf (handle, java_class_ref)) + throw new InvalidCastException (string.Format ("Unable to convert instance of type '{0}' to type '{1}'.", + JNIEnv.GetClassNameFromInstance (handle), "xamarin.test.I2")); + return handle; + } + + protected override void Dispose (bool disposing) + { + if (this.class_ref != IntPtr.Zero) + JNIEnv.DeleteGlobalRef (this.class_ref); + this.class_ref = IntPtr.Zero; + base.Dispose (disposing); + } + + public II2Invoker (IntPtr handle, JniHandleOwnership transfer) : base (Validate (handle), transfer) + { + IntPtr local_ref = JNIEnv.GetObjectClass (((global::Java.Lang.Object) this).Handle); + this.class_ref = JNIEnv.NewGlobalRef (local_ref); + JNIEnv.DeleteLocalRef (local_ref); + } + + static Delegate cb_close; +#pragma warning disable 0169 + static Delegate GetCloseHandler () + { + if (cb_close == null) + cb_close = JNINativeWrapper.CreateDelegate ((Action) n_Close); + return cb_close; + } + + static void n_Close (IntPtr jnienv, IntPtr native__this) + { + global::Xamarin.Test.II2 __this = global::Java.Lang.Object.GetObject (jnienv, native__this, JniHandleOwnership.DoNotTransfer); + __this.Close (); + } +#pragma warning restore 0169 + + IntPtr id_close; + public unsafe void Close () + { + if (id_close == IntPtr.Zero) + id_close = JNIEnv.GetMethodID (class_ref, "close", "()V"); + JNIEnv.CallVoidMethod (((global::Java.Lang.Object) this).Handle, id_close); + } + + } + +} diff --git a/tools/generator/Tests/expected.ji/InterfaceMethodsConflict/Xamarin.Test.SomeObject.cs b/tools/generator/Tests/expected.ji/InterfaceMethodsConflict/Xamarin.Test.SomeObject.cs new file mode 100644 index 000000000..20c8bc051 --- /dev/null +++ b/tools/generator/Tests/expected.ji/InterfaceMethodsConflict/Xamarin.Test.SomeObject.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using Android.Runtime; +using Java.Interop; + +namespace Xamarin.Test { + + // Metadata.xml XPath class reference: path="/api/package[@name='xamarin.test']/class[@name='SomeObject']" + [global::Android.Runtime.Register ("xamarin/test/SomeObject", DoNotGenerateAcw=true)] + public partial class SomeObject : global::Java.Lang.Object, global::Xamarin.Test.II1, global::Xamarin.Test.II2 { + + internal static readonly JniPeerMembers _members = new JniPeerMembers ("xamarin/test/SomeObject", typeof (SomeObject)); + internal static IntPtr class_ref { + get { + return _members.JniPeerType.PeerReference.Handle; + } + } + + public override global::Java.Interop.JniPeerMembers JniPeerMembers { + get { return _members; } + } + + protected override IntPtr ThresholdClass { + get { return _members.JniPeerType.PeerReference.Handle; } + } + + protected override global::System.Type ThresholdType { + get { return _members.ManagedPeerType; } + } + + protected SomeObject (IntPtr javaReference, JniHandleOwnership transfer) : base (javaReference, transfer) {} + + static Delegate cb_close; +#pragma warning disable 0169 + static Delegate GetCloseHandler () + { + if (cb_close == null) + cb_close = JNINativeWrapper.CreateDelegate ((Action) n_Close); + return cb_close; + } + + static void n_Close (IntPtr jnienv, IntPtr native__this) + { + global::Xamarin.Test.SomeObject __this = global::Java.Lang.Object.GetObject (jnienv, native__this, JniHandleOwnership.DoNotTransfer); + __this.Close (); + } +#pragma warning restore 0169 + + // Metadata.xml XPath method reference: path="/api/package[@name='xamarin.test']/class[@name='SomeObject']/method[@name='close' and count(parameter)=0]" + [Register ("close", "()V", "GetCloseHandler")] + public virtual unsafe void Close () + { + const string __id = "close.()V"; + try { + _members.InstanceMethods.InvokeVirtualVoidMethod (__id, this, null); + } finally { + } + } + + } +} diff --git a/tools/generator/Tests/expected.ji/InterfaceMethodsConflict/Xamarin.Test.SomeObject2.cs b/tools/generator/Tests/expected.ji/InterfaceMethodsConflict/Xamarin.Test.SomeObject2.cs new file mode 100644 index 000000000..bbabe28ad --- /dev/null +++ b/tools/generator/Tests/expected.ji/InterfaceMethodsConflict/Xamarin.Test.SomeObject2.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections.Generic; +using Android.Runtime; +using Java.Interop; + +namespace Xamarin.Test { + + // Metadata.xml XPath class reference: path="/api/package[@name='xamarin.test']/class[@name='SomeObject2']" + [global::Android.Runtime.Register ("xamarin/test/SomeObject2", DoNotGenerateAcw=true)] + public abstract partial class SomeObject2 : global::Java.Lang.Object, global::Xamarin.Test.II1, global::Xamarin.Test.II2 { + + internal static readonly JniPeerMembers _members = new JniPeerMembers ("xamarin/test/SomeObject2", typeof (SomeObject2)); + internal static IntPtr class_ref { + get { + return _members.JniPeerType.PeerReference.Handle; + } + } + + public override global::Java.Interop.JniPeerMembers JniPeerMembers { + get { return _members; } + } + + protected override IntPtr ThresholdClass { + get { return _members.JniPeerType.PeerReference.Handle; } + } + + protected override global::System.Type ThresholdType { + get { return _members.ManagedPeerType; } + } + + protected SomeObject2 (IntPtr javaReference, JniHandleOwnership transfer) : base (javaReference, transfer) {} + + static Delegate cb_irrelevant; +#pragma warning disable 0169 + static Delegate GetIrrelevantHandler () + { + if (cb_irrelevant == null) + cb_irrelevant = JNINativeWrapper.CreateDelegate ((Action) n_Irrelevant); + return cb_irrelevant; + } + + static void n_Irrelevant (IntPtr jnienv, IntPtr native__this) + { + global::Xamarin.Test.SomeObject2 __this = global::Java.Lang.Object.GetObject (jnienv, native__this, JniHandleOwnership.DoNotTransfer); + __this.Irrelevant (); + } +#pragma warning restore 0169 + + // Metadata.xml XPath method reference: path="/api/package[@name='xamarin.test']/class[@name='SomeObject2']/method[@name='irrelevant' and count(parameter)=0]" + [Register ("irrelevant", "()V", "GetIrrelevantHandler")] + public virtual unsafe void Irrelevant () + { + const string __id = "irrelevant.()V"; + try { + _members.InstanceMethods.InvokeVirtualVoidMethod (__id, this, null); + } finally { + } + } + + static Delegate cb_close; +#pragma warning disable 0169 + static Delegate GetCloseHandler () + { + if (cb_close == null) + cb_close = JNINativeWrapper.CreateDelegate ((Action) n_Close); + return cb_close; + } + + static void n_Close (IntPtr jnienv, IntPtr native__this) + { + global::Xamarin.Test.SomeObject2 __this = global::Java.Lang.Object.GetObject (jnienv, native__this, JniHandleOwnership.DoNotTransfer); + __this.Close (); + } +#pragma warning restore 0169 + + // Metadata.xml XPath method reference: path="/api/package[@name='xamarin.test']/interface[@name='I1']/method[@name='close' and count(parameter)=0]" + [Register ("close", "()V", "GetCloseHandler")] + public abstract void Close (); + + } + + [global::Android.Runtime.Register ("xamarin/test/SomeObject2", DoNotGenerateAcw=true)] + internal partial class SomeObject2Invoker : SomeObject2 { + + public SomeObject2Invoker (IntPtr handle, JniHandleOwnership transfer) : base (handle, transfer) {} + + internal new static readonly JniPeerMembers _members = new JniPeerMembers ("xamarin/test/SomeObject2", typeof (SomeObject2Invoker)); + + public override global::Java.Interop.JniPeerMembers JniPeerMembers { + get { return _members; } + } + + protected override global::System.Type ThresholdType { + get { return _members.ManagedPeerType; } + } + + // Metadata.xml XPath method reference: path="/api/package[@name='xamarin.test']/interface[@name='I1']/method[@name='close' and count(parameter)=0]" + [Register ("close", "()V", "GetCloseHandler")] + public override unsafe void Close () + { + const string __id = "close.()V"; + try { + _members.InstanceMethods.InvokeAbstractVoidMethod (__id, this, null); + } finally { + } + } + + } + +} diff --git a/tools/generator/Tests/expected.ji/InterfaceMethodsConflict/__NamespaceMapping__.cs b/tools/generator/Tests/expected.ji/InterfaceMethodsConflict/__NamespaceMapping__.cs new file mode 100644 index 000000000..03f5e975a --- /dev/null +++ b/tools/generator/Tests/expected.ji/InterfaceMethodsConflict/__NamespaceMapping__.cs @@ -0,0 +1,2 @@ +[assembly:global::Android.Runtime.NamespaceMapping (Java = "java.lang", Managed="Java.Lang")] +[assembly:global::Android.Runtime.NamespaceMapping (Java = "xamarin.test", Managed="Xamarin.Test")] diff --git a/tools/generator/Tests/expected.targets b/tools/generator/Tests/expected.targets index d27d6cb5c..a4fa8d245 100644 --- a/tools/generator/Tests/expected.targets +++ b/tools/generator/Tests/expected.targets @@ -495,6 +495,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + PreserveNewest @@ -615,5 +621,11 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + diff --git a/tools/generator/Tests/expected/InterfaceMethodsConflict/InterfaceMethodsConflict.xml b/tools/generator/Tests/expected/InterfaceMethodsConflict/InterfaceMethodsConflict.xml new file mode 100644 index 000000000..e83a6e37a --- /dev/null +++ b/tools/generator/Tests/expected/InterfaceMethodsConflict/InterfaceMethodsConflict.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/generator/Tests/expected/InterfaceMethodsConflict/Java.Interop.__TypeRegistrations.cs b/tools/generator/Tests/expected/InterfaceMethodsConflict/Java.Interop.__TypeRegistrations.cs new file mode 100644 index 000000000..6008ae6da --- /dev/null +++ b/tools/generator/Tests/expected/InterfaceMethodsConflict/Java.Interop.__TypeRegistrations.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using Android.Runtime; + +namespace Java.Interop { + + partial class __TypeRegistrations { + + public static void RegisterPackages () + { +#if MONODROID_TIMING + var start = DateTime.Now; + Android.Util.Log.Info ("MonoDroid-Timing", "RegisterPackages start: " + (start - new DateTime (1970, 1, 1)).TotalMilliseconds); +#endif // def MONODROID_TIMING + Java.Interop.TypeManager.RegisterPackages ( + new string[]{ + }, + new Converter[]{ + }); +#if MONODROID_TIMING + var end = DateTime.Now; + Android.Util.Log.Info ("MonoDroid-Timing", "RegisterPackages time: " + (end - new DateTime (1970, 1, 1)).TotalMilliseconds + " [elapsed: " + (end - start).TotalMilliseconds + " ms]"); +#endif // def MONODROID_TIMING + } + + static Type Lookup (string[] mappings, string javaType) + { + string managedType = Java.Interop.TypeManager.LookupTypeMapping (mappings, javaType); + if (managedType == null) + return null; + return Type.GetType (managedType); + } + } +} diff --git a/tools/generator/Tests/expected/InterfaceMethodsConflict/Java.Lang.Object.cs b/tools/generator/Tests/expected/InterfaceMethodsConflict/Java.Lang.Object.cs new file mode 100644 index 000000000..1aa80ac6b --- /dev/null +++ b/tools/generator/Tests/expected/InterfaceMethodsConflict/Java.Lang.Object.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using Android.Runtime; + +namespace Java.Lang { + + // Metadata.xml XPath class reference: path="/api/package[@name='java.lang']/class[@name='Object']" + [global::Android.Runtime.Register ("java/lang/Object", DoNotGenerateAcw=true)] + public partial class Object { + + } +} diff --git a/tools/generator/Tests/expected/InterfaceMethodsConflict/Xamarin.Test.II1.cs b/tools/generator/Tests/expected/InterfaceMethodsConflict/Xamarin.Test.II1.cs new file mode 100644 index 000000000..1a45adfdc --- /dev/null +++ b/tools/generator/Tests/expected/InterfaceMethodsConflict/Xamarin.Test.II1.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; +using Android.Runtime; + +namespace Xamarin.Test { + + // Metadata.xml XPath interface reference: path="/api/package[@name='xamarin.test']/interface[@name='I1']" + [Register ("xamarin/test/I1", "", "Xamarin.Test.II1Invoker")] + public partial interface II1 : IJavaObject { + + // Metadata.xml XPath method reference: path="/api/package[@name='xamarin.test']/interface[@name='I1']/method[@name='close' and count(parameter)=0]" + [Register ("close", "()V", "GetCloseHandler:Xamarin.Test.II1Invoker, Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null")] + void Close (); + + } + + [global::Android.Runtime.Register ("xamarin/test/I1", DoNotGenerateAcw=true)] + internal class II1Invoker : global::Java.Lang.Object, II1 { + + static IntPtr java_class_ref = JNIEnv.FindClass ("xamarin/test/I1"); + + protected override IntPtr ThresholdClass { + get { return class_ref; } + } + + protected override global::System.Type ThresholdType { + get { return typeof (II1Invoker); } + } + + IntPtr class_ref; + + public static II1 GetObject (IntPtr handle, JniHandleOwnership transfer) + { + return global::Java.Lang.Object.GetObject (handle, transfer); + } + + static IntPtr Validate (IntPtr handle) + { + if (!JNIEnv.IsInstanceOf (handle, java_class_ref)) + throw new InvalidCastException (string.Format ("Unable to convert instance of type '{0}' to type '{1}'.", + JNIEnv.GetClassNameFromInstance (handle), "xamarin.test.I1")); + return handle; + } + + protected override void Dispose (bool disposing) + { + if (this.class_ref != IntPtr.Zero) + JNIEnv.DeleteGlobalRef (this.class_ref); + this.class_ref = IntPtr.Zero; + base.Dispose (disposing); + } + + public II1Invoker (IntPtr handle, JniHandleOwnership transfer) : base (Validate (handle), transfer) + { + IntPtr local_ref = JNIEnv.GetObjectClass (((global::Java.Lang.Object) this).Handle); + this.class_ref = JNIEnv.NewGlobalRef (local_ref); + JNIEnv.DeleteLocalRef (local_ref); + } + + static Delegate cb_close; +#pragma warning disable 0169 + static Delegate GetCloseHandler () + { + if (cb_close == null) + cb_close = JNINativeWrapper.CreateDelegate ((Action) n_Close); + return cb_close; + } + + static void n_Close (IntPtr jnienv, IntPtr native__this) + { + global::Xamarin.Test.II1 __this = global::Java.Lang.Object.GetObject (jnienv, native__this, JniHandleOwnership.DoNotTransfer); + __this.Close (); + } +#pragma warning restore 0169 + + IntPtr id_close; + public unsafe void Close () + { + if (id_close == IntPtr.Zero) + id_close = JNIEnv.GetMethodID (class_ref, "close", "()V"); + JNIEnv.CallVoidMethod (((global::Java.Lang.Object) this).Handle, id_close); + } + + } + +} diff --git a/tools/generator/Tests/expected/InterfaceMethodsConflict/Xamarin.Test.II2.cs b/tools/generator/Tests/expected/InterfaceMethodsConflict/Xamarin.Test.II2.cs new file mode 100644 index 000000000..f29d0206c --- /dev/null +++ b/tools/generator/Tests/expected/InterfaceMethodsConflict/Xamarin.Test.II2.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; +using Android.Runtime; + +namespace Xamarin.Test { + + // Metadata.xml XPath interface reference: path="/api/package[@name='xamarin.test']/interface[@name='I2']" + [Register ("xamarin/test/I2", "", "Xamarin.Test.II2Invoker")] + public partial interface II2 : IJavaObject { + + // Metadata.xml XPath method reference: path="/api/package[@name='xamarin.test']/interface[@name='I2']/method[@name='close' and count(parameter)=0]" + [Register ("close", "()V", "GetCloseHandler:Xamarin.Test.II2Invoker, Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null")] + void Close (); + + } + + [global::Android.Runtime.Register ("xamarin/test/I2", DoNotGenerateAcw=true)] + internal class II2Invoker : global::Java.Lang.Object, II2 { + + static IntPtr java_class_ref = JNIEnv.FindClass ("xamarin/test/I2"); + + protected override IntPtr ThresholdClass { + get { return class_ref; } + } + + protected override global::System.Type ThresholdType { + get { return typeof (II2Invoker); } + } + + IntPtr class_ref; + + public static II2 GetObject (IntPtr handle, JniHandleOwnership transfer) + { + return global::Java.Lang.Object.GetObject (handle, transfer); + } + + static IntPtr Validate (IntPtr handle) + { + if (!JNIEnv.IsInstanceOf (handle, java_class_ref)) + throw new InvalidCastException (string.Format ("Unable to convert instance of type '{0}' to type '{1}'.", + JNIEnv.GetClassNameFromInstance (handle), "xamarin.test.I2")); + return handle; + } + + protected override void Dispose (bool disposing) + { + if (this.class_ref != IntPtr.Zero) + JNIEnv.DeleteGlobalRef (this.class_ref); + this.class_ref = IntPtr.Zero; + base.Dispose (disposing); + } + + public II2Invoker (IntPtr handle, JniHandleOwnership transfer) : base (Validate (handle), transfer) + { + IntPtr local_ref = JNIEnv.GetObjectClass (((global::Java.Lang.Object) this).Handle); + this.class_ref = JNIEnv.NewGlobalRef (local_ref); + JNIEnv.DeleteLocalRef (local_ref); + } + + static Delegate cb_close; +#pragma warning disable 0169 + static Delegate GetCloseHandler () + { + if (cb_close == null) + cb_close = JNINativeWrapper.CreateDelegate ((Action) n_Close); + return cb_close; + } + + static void n_Close (IntPtr jnienv, IntPtr native__this) + { + global::Xamarin.Test.II2 __this = global::Java.Lang.Object.GetObject (jnienv, native__this, JniHandleOwnership.DoNotTransfer); + __this.Close (); + } +#pragma warning restore 0169 + + IntPtr id_close; + public unsafe void Close () + { + if (id_close == IntPtr.Zero) + id_close = JNIEnv.GetMethodID (class_ref, "close", "()V"); + JNIEnv.CallVoidMethod (((global::Java.Lang.Object) this).Handle, id_close); + } + + } + +} diff --git a/tools/generator/Tests/expected/InterfaceMethodsConflict/Xamarin.Test.SomeObject.cs b/tools/generator/Tests/expected/InterfaceMethodsConflict/Xamarin.Test.SomeObject.cs new file mode 100644 index 000000000..0efde4b3f --- /dev/null +++ b/tools/generator/Tests/expected/InterfaceMethodsConflict/Xamarin.Test.SomeObject.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using Android.Runtime; + +namespace Xamarin.Test { + + // Metadata.xml XPath class reference: path="/api/package[@name='xamarin.test']/class[@name='SomeObject']" + [global::Android.Runtime.Register ("xamarin/test/SomeObject", DoNotGenerateAcw=true)] + public partial class SomeObject : global::Java.Lang.Object, global::Xamarin.Test.II1, global::Xamarin.Test.II2 { + + internal static IntPtr java_class_handle; + internal static IntPtr class_ref { + get { + return JNIEnv.FindClass ("xamarin/test/SomeObject", ref java_class_handle); + } + } + + protected override IntPtr ThresholdClass { + get { return class_ref; } + } + + protected override global::System.Type ThresholdType { + get { return typeof (SomeObject); } + } + + protected SomeObject (IntPtr javaReference, JniHandleOwnership transfer) : base (javaReference, transfer) {} + + static Delegate cb_close; +#pragma warning disable 0169 + static Delegate GetCloseHandler () + { + if (cb_close == null) + cb_close = JNINativeWrapper.CreateDelegate ((Action) n_Close); + return cb_close; + } + + static void n_Close (IntPtr jnienv, IntPtr native__this) + { + global::Xamarin.Test.SomeObject __this = global::Java.Lang.Object.GetObject (jnienv, native__this, JniHandleOwnership.DoNotTransfer); + __this.Close (); + } +#pragma warning restore 0169 + + static IntPtr id_close; + // Metadata.xml XPath method reference: path="/api/package[@name='xamarin.test']/class[@name='SomeObject']/method[@name='close' and count(parameter)=0]" + [Register ("close", "()V", "GetCloseHandler")] + public virtual unsafe void Close () + { + if (id_close == IntPtr.Zero) + id_close = JNIEnv.GetMethodID (class_ref, "close", "()V"); + try { + + if (((object) this).GetType () == ThresholdType) + JNIEnv.CallVoidMethod (((global::Java.Lang.Object) this).Handle, id_close); + else + JNIEnv.CallNonvirtualVoidMethod (((global::Java.Lang.Object) this).Handle, ThresholdClass, JNIEnv.GetMethodID (ThresholdClass, "close", "()V")); + } finally { + } + } + + } +} diff --git a/tools/generator/Tests/expected/InterfaceMethodsConflict/Xamarin.Test.SomeObject2.cs b/tools/generator/Tests/expected/InterfaceMethodsConflict/Xamarin.Test.SomeObject2.cs new file mode 100644 index 000000000..bbe379f3b --- /dev/null +++ b/tools/generator/Tests/expected/InterfaceMethodsConflict/Xamarin.Test.SomeObject2.cs @@ -0,0 +1,107 @@ +using System; +using System.Collections.Generic; +using Android.Runtime; + +namespace Xamarin.Test { + + // Metadata.xml XPath class reference: path="/api/package[@name='xamarin.test']/class[@name='SomeObject2']" + [global::Android.Runtime.Register ("xamarin/test/SomeObject2", DoNotGenerateAcw=true)] + public abstract partial class SomeObject2 : global::Java.Lang.Object, global::Xamarin.Test.II1, global::Xamarin.Test.II2 { + + internal static IntPtr java_class_handle; + internal static IntPtr class_ref { + get { + return JNIEnv.FindClass ("xamarin/test/SomeObject2", ref java_class_handle); + } + } + + protected override IntPtr ThresholdClass { + get { return class_ref; } + } + + protected override global::System.Type ThresholdType { + get { return typeof (SomeObject2); } + } + + protected SomeObject2 (IntPtr javaReference, JniHandleOwnership transfer) : base (javaReference, transfer) {} + + static Delegate cb_irrelevant; +#pragma warning disable 0169 + static Delegate GetIrrelevantHandler () + { + if (cb_irrelevant == null) + cb_irrelevant = JNINativeWrapper.CreateDelegate ((Action) n_Irrelevant); + return cb_irrelevant; + } + + static void n_Irrelevant (IntPtr jnienv, IntPtr native__this) + { + global::Xamarin.Test.SomeObject2 __this = global::Java.Lang.Object.GetObject (jnienv, native__this, JniHandleOwnership.DoNotTransfer); + __this.Irrelevant (); + } +#pragma warning restore 0169 + + static IntPtr id_irrelevant; + // Metadata.xml XPath method reference: path="/api/package[@name='xamarin.test']/class[@name='SomeObject2']/method[@name='irrelevant' and count(parameter)=0]" + [Register ("irrelevant", "()V", "GetIrrelevantHandler")] + public virtual unsafe void Irrelevant () + { + if (id_irrelevant == IntPtr.Zero) + id_irrelevant = JNIEnv.GetMethodID (class_ref, "irrelevant", "()V"); + try { + + if (((object) this).GetType () == ThresholdType) + JNIEnv.CallVoidMethod (((global::Java.Lang.Object) this).Handle, id_irrelevant); + else + JNIEnv.CallNonvirtualVoidMethod (((global::Java.Lang.Object) this).Handle, ThresholdClass, JNIEnv.GetMethodID (ThresholdClass, "irrelevant", "()V")); + } finally { + } + } + + static Delegate cb_close; +#pragma warning disable 0169 + static Delegate GetCloseHandler () + { + if (cb_close == null) + cb_close = JNINativeWrapper.CreateDelegate ((Action) n_Close); + return cb_close; + } + + static void n_Close (IntPtr jnienv, IntPtr native__this) + { + global::Xamarin.Test.SomeObject2 __this = global::Java.Lang.Object.GetObject (jnienv, native__this, JniHandleOwnership.DoNotTransfer); + __this.Close (); + } +#pragma warning restore 0169 + + // Metadata.xml XPath method reference: path="/api/package[@name='xamarin.test']/interface[@name='I1']/method[@name='close' and count(parameter)=0]" + [Register ("close", "()V", "GetCloseHandler")] + public abstract void Close (); + + } + + [global::Android.Runtime.Register ("xamarin/test/SomeObject2", DoNotGenerateAcw=true)] + internal partial class SomeObject2Invoker : SomeObject2 { + + public SomeObject2Invoker (IntPtr handle, JniHandleOwnership transfer) : base (handle, transfer) {} + + protected override global::System.Type ThresholdType { + get { return typeof (SomeObject2Invoker); } + } + + static IntPtr id_close; + // Metadata.xml XPath method reference: path="/api/package[@name='xamarin.test']/interface[@name='I1']/method[@name='close' and count(parameter)=0]" + [Register ("close", "()V", "GetCloseHandler")] + public override unsafe void Close () + { + if (id_close == IntPtr.Zero) + id_close = JNIEnv.GetMethodID (class_ref, "close", "()V"); + try { + JNIEnv.CallVoidMethod (((global::Java.Lang.Object) this).Handle, id_close); + } finally { + } + } + + } + +} diff --git a/tools/generator/Tests/expected/InterfaceMethodsConflict/__NamespaceMapping__.cs b/tools/generator/Tests/expected/InterfaceMethodsConflict/__NamespaceMapping__.cs new file mode 100644 index 000000000..03f5e975a --- /dev/null +++ b/tools/generator/Tests/expected/InterfaceMethodsConflict/__NamespaceMapping__.cs @@ -0,0 +1,2 @@ +[assembly:global::Android.Runtime.NamespaceMapping (Java = "java.lang", Managed="Java.Lang")] +[assembly:global::Android.Runtime.NamespaceMapping (Java = "xamarin.test", Managed="Xamarin.Test")] diff --git a/tools/generator/Tests/generator-Tests.csproj b/tools/generator/Tests/generator-Tests.csproj index 55385a84a..403fbb55d 100644 --- a/tools/generator/Tests/generator-Tests.csproj +++ b/tools/generator/Tests/generator-Tests.csproj @@ -61,6 +61,7 @@ +