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 @@ +