Skip to content

[generator] do not generate identical methods to previously generated ones. #153

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions tools/generator/ClassGen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
}

Expand Down Expand Up @@ -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<Method> ();

gen_info.TypeRegistrations.Add (new KeyValuePair<string, string>(RawJniName, AssemblyQualifiedName));
bool is_enum = base_symbol != null && base_symbol.FullName == "Java.Lang.Enum";
if (is_enum)
Expand Down Expand Up @@ -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 ();
}

Expand Down
1 change: 1 addition & 0 deletions tools/generator/CodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,7 @@ public class CodeGenerationOptions
public Stack<GenBase> ContextTypes {
get { return context_types; }
}
public List<Method> ContextGeneratedMethods { get; set; } = new List<Method> ();
public GenBase ContextType {
get { return context_types.Any () ? context_types.Peek () : null; }
}
Expand Down
3 changes: 3 additions & 0 deletions tools/generator/InterfaceGen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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))
Expand Down
19 changes: 19 additions & 0 deletions tools/generator/Tests/InterfaceMethodsConflict.cs
Original file line number Diff line number Diff line change
@@ -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");
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" ?>
<api>
<package name="xamarin.test">
<class abstract="false" deprecated="not deprecated" final="false" name="Object" static="false" visibility="public">
</class>
</package>
<package name="xamarin.test">
<interface abstract="true" deprecated="not deprecated" final="false" name="I1" static="false" visibility="public">
<method abstract="true" deprecated="not deprecated" final="false" name="close" native="false" return="void" static="false" synchronized="false" visibility="public">
</method>
</interface>
<interface abstract="true" deprecated="not deprecated" final="false" name="I2" static="false" visibility="public">
<method abstract="true" deprecated="not deprecated" final="false" name="close" native="false" return="void" static="false" synchronized="false" visibility="public">
</method>
</interface>
<class abstract="true" deprecated="not deprecated" extends="java.lang.Object" extends-generic-aware="java.lang.Object"
final="false" name="SomeObject" static="false" visibility="public">
<implements name="xamarin.test.I1" name-generic-aware="xamarin.test.I1" />
<implements name="xamarin.test.I2" name-generic-aware="xamarin.test.I2" />
</class>
</package>
</api>



Original file line number Diff line number Diff line change
@@ -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<string, Type>[]{
});
#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);
}
}
}
Original file line number Diff line number Diff line change
@@ -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 {

}
}
Original file line number Diff line number Diff line change
@@ -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<II1> (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<IntPtr, IntPtr>) n_Close);
return cb_close;
}

static void n_Close (IntPtr jnienv, IntPtr native__this)
{
global::Xamarin.Test.II1 __this = global::Java.Lang.Object.GetObject<global::Xamarin.Test.II1> (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);
}

}

}
Original file line number Diff line number Diff line change
@@ -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<II2> (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<IntPtr, IntPtr>) n_Close);
return cb_close;
}

static void n_Close (IntPtr jnienv, IntPtr native__this)
{
global::Xamarin.Test.II2 __this = global::Java.Lang.Object.GetObject<global::Xamarin.Test.II2> (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);
}

}

}
Loading