Skip to content
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// Metadata.xml XPath interface reference: path="/api/package[@name='com.xamarin.android']/interface[@name='Parent']"
[Register ("com/xamarin/android/Parent", "", "Com.Xamarin.Android.IParentInvoker")]
public partial interface IParent : IJavaObject, IJavaPeerable {

int Bar {
// Metadata.xml XPath method reference: path="/api/package[@name='com.xamarin.android']/interface[@name='Parent']/method[@name='getBar' and count(parameter)=0]"
[Register ("getBar", "()I", "GetGetBarHandler:Com.Xamarin.Android.IParentInvoker, MyAssembly")] get;
}

// Metadata.xml XPath class reference: path="/api/package[@name='com.xamarin.android']/class[@name='Parent.Child']"
[global::Android.Runtime.Register ("com/xamarin/android/Parent$Child", DoNotGenerateAcw=true)]
public partial class Child : Java.Lang.Object {

static readonly JniPeerMembers _members = new JniPeerMembers ("com/xamarin/android/Parent$Child", typeof (Child));
internal static new 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 Child (IntPtr javaReference, JniHandleOwnership transfer) : base (javaReference, transfer) {}

}

}

[global::Android.Runtime.Register ("com/xamarin/android/Parent", DoNotGenerateAcw=true)]
internal partial class IParentInvoker : global::Java.Lang.Object, IParent {

static readonly JniPeerMembers _members = new JniPeerMembers ("com/xamarin/android/Parent", typeof (IParentInvoker));

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; }
}

new IntPtr class_ref;

public static IParent GetObject (IntPtr handle, JniHandleOwnership transfer)
{
return global::Java.Lang.Object.GetObject<IParent> (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), "com.xamarin.android.Parent"));
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 IParentInvoker (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_getBar;
#pragma warning disable 0169
static Delegate GetGetBarHandler ()
{
if (cb_getBar == null)
cb_getBar = JNINativeWrapper.CreateDelegate ((Func<IntPtr, IntPtr, int>) n_GetBar);
return cb_getBar;
}

static int n_GetBar (IntPtr jnienv, IntPtr native__this)
{
Com.Xamarin.Android.IParent __this = global::Java.Lang.Object.GetObject<Com.Xamarin.Android.IParent> (jnienv, native__this, JniHandleOwnership.DoNotTransfer);
return __this.Bar;
}
#pragma warning restore 0169

IntPtr id_getBar;
public unsafe int Bar {
get {
if (id_getBar == IntPtr.Zero)
id_getBar = JNIEnv.GetMethodID (class_ref, "getBar", "()I");
return JNIEnv.CallIntMethod (((global::Java.Lang.Object) this).Handle, id_getBar);
}
}

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// Metadata.xml XPath interface reference: path="/api/package[@name='com.xamarin.android']/interface[@name='Parent']"
[Register ("com/xamarin/android/Parent", "", "Com.Xamarin.Android.IParentInvoker")]
public partial interface IParent : IJavaObject, IJavaPeerable {

int Bar {
// Metadata.xml XPath method reference: path="/api/package[@name='com.xamarin.android']/interface[@name='Parent']/method[@name='getBar' and count(parameter)=0]"
[Register ("getBar", "()I", "GetGetBarHandler:Com.Xamarin.Android.IParentInvoker, MyAssembly")] get;
}

// Metadata.xml XPath class reference: path="/api/package[@name='com.xamarin.android']/class[@name='Parent.Child']"
[global::Android.Runtime.Register ("com/xamarin/android/Parent$Child", DoNotGenerateAcw=true)]
public partial class Child : Java.Lang.Object {

static readonly JniPeerMembers _members = new XAPeerMembers ("com/xamarin/android/Parent$Child", typeof (Child));
internal static new 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 Child (IntPtr javaReference, JniHandleOwnership transfer) : base (javaReference, transfer) {}

}

}

[global::Android.Runtime.Register ("com/xamarin/android/Parent", DoNotGenerateAcw=true)]
internal partial class IParentInvoker : global::Java.Lang.Object, IParent {

static readonly JniPeerMembers _members = new XAPeerMembers ("com/xamarin/android/Parent", typeof (IParentInvoker));

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; }
}

new IntPtr class_ref;

public static IParent GetObject (IntPtr handle, JniHandleOwnership transfer)
{
return global::Java.Lang.Object.GetObject<IParent> (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), "com.xamarin.android.Parent"));
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 IParentInvoker (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_getBar;
#pragma warning disable 0169
static Delegate GetGetBarHandler ()
{
if (cb_getBar == null)
cb_getBar = JNINativeWrapper.CreateDelegate ((Func<IntPtr, IntPtr, int>) n_GetBar);
return cb_getBar;
}

static int n_GetBar (IntPtr jnienv, IntPtr native__this)
{
Com.Xamarin.Android.IParent __this = global::Java.Lang.Object.GetObject<Com.Xamarin.Android.IParent> (jnienv, native__this, JniHandleOwnership.DoNotTransfer);
return __this.Bar;
}
#pragma warning restore 0169

IntPtr id_getBar;
public unsafe int Bar {
get {
if (id_getBar == IntPtr.Zero)
id_getBar = JNIEnv.GetMethodID (class_ref, "getBar", "()I");
return JNIEnv.CallIntMethod (((global::Java.Lang.Object) this).Handle, id_getBar);
}
}

}

30 changes: 30 additions & 0 deletions tests/generator-Tests/Unit-Tests/DefaultInterfaceMethodsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,18 @@ public void WriteStaticInterfaceProperty ()
</package>
</api>";

readonly string nested_class_api = @"<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/EmptyOverrideClass;' />
</package>
<package name='com.xamarin.android' jni-name='com/xamarin/android'>
<interface abstract='true' deprecated='not deprecated' final='false' name='Parent' static='false' visibility='public' jni-signature='Lcom/xamarin/android/Parent;'>
<method abstract='true' deprecated='not deprecated' final='false' name='getBar' jni-signature='()I' bridge='false' native='false' return='int' jni-return='I' static='false' synchronized='false' synthetic='false' visibility='public'></method>
</interface>
<class abstract='false' deprecated='not deprecated' extends='java.lang.Object' extends-generic-aware='java.lang.Object' jni-extends='Ljava/lang/Object;' final='false' name='Parent.Child' static='false' visibility='public' jni-signature='Lcom/xamarin/android/Parent$Child;' />
</package>
</api>";

[Test]
public void WriteUnnestedInterfaceTypes ()
{
Expand Down Expand Up @@ -273,5 +285,23 @@ public void WriteNestedInterfaceTypes ()

Assert.AreEqual (GetTargetedExpected (nameof (WriteNestedInterfaceTypes)), writer.ToString ().NormalizeLineEndings ());
}

[Test]
public void WriteNestedInterfaceClass ()
{
// Traditionally this would have created namespace.IParent and namespace.IParentChild
// With nested types this creates namespace.IParent and namespace.IParent.IChild
options.SupportNestedInterfaceTypes = true;

var gens = ParseApiDefinition (nested_class_api);

var parent_iface = gens.OfType<InterfaceGen> ().Single ();

parent_iface.Validate (options, new GenericParameterDefinitionList (), new CodeGeneratorContext ());

generator.WriteInterface (parent_iface, string.Empty, new GenerationInfo (string.Empty, string.Empty, "MyAssembly"));

Assert.AreEqual (GetTargetedExpected (nameof (WriteNestedInterfaceClass)), writer.ToString ().NormalizeLineEndings ());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,14 @@ public override void AddNestedType (GenBase gen)
var nest_name = gen.JavaName.Substring (JavaName.Length + 1);

if (nest_name.IndexOf (".") < 0) {
if (gen is InterfaceGen) {

// We don't need to mangle the name if we support nested interface types
// ex: my.namespace.IParent.IChild
if (!gen.Unnest) {
gen.FullName = FullName + "." + gen.Name;
return;
}
// We don't need to mangle the name if we support nested interface types
// ex: my.namespace.IParent.IChild
if (!gen.Unnest) {
gen.FullName = FullName + "." + gen.Name;
return;
}

if (gen is InterfaceGen) {
// ex: my.namespace.IParentChild
gen.FullName = FullName + gen.Name.Substring (1);
gen.Name = Name + gen.Name.Substring (1);
Expand Down