Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[generator] Use DIM to support static interface methods (#487)
Using the new Default Interface Members support (29f9707), and `generator --lang-features=default-interface-methods`, we can now also support static interface methods/properties. This Java interface: // Java public interface StaticMethodsInterface { static int foo () { return 10; } static int getValue () { return 3; } static void setValue (int value) { } } can now be bound as: // C# Binding public partial interface IStaticMethodsInterface { static new readonly JniPeerMembers _members = new JniPeerMembers ( "java/code/StaticMethodsInterface", typeof (IStaticMethodsInterface), isInterface: true); public static unsafe int Foo () { return _members.StaticMethods.InvokeInt32Method ("foo.()I", null); } public static unsafe int Value { get { return _members.StaticMethods.InvokeInt32Method ("getValue.()I", null); } set { JniArgumentValue* __args = stackalloc JniArgumentValue [1]; __args [0] = new JniArgumentValue (value); _members.StaticMethods.InvokeVoidMethod ("setValue.(I)V", __args); } } } Which can be invoked as: [Test] public void TestStaticMethods () { Assert.AreEqual (10, IStaticMethodsInterface.Foo ()); Assert.AreEqual (3, IStaticMethodsInterface.Value); Assert.DoesNotThrow (() => IStaticMethodsInterface.Value = 5); }
- Loading branch information
Showing
8 changed files
with
319 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
101 changes: 101 additions & 0 deletions
101
...Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteStaticInterfaceMethod.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
[Register ("java/code/IMyInterface", DoNotGenerateAcw=true)] | ||
public abstract class MyInterface : Java.Lang.Object { | ||
|
||
internal MyInterface () | ||
{ | ||
} | ||
// Metadata.xml XPath method reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/method[@name='DoSomething' and count(parameter)=0]" | ||
[Register ("DoSomething", "()V", "")] | ||
public static unsafe void DoSomething () | ||
{ | ||
const string __id = "DoSomething.()V"; | ||
try { | ||
_members.StaticMethods.InvokeVoidMethod (__id, null); | ||
} finally { | ||
} | ||
} | ||
|
||
|
||
static new readonly JniPeerMembers _members = new JniPeerMembers ("java/code/IMyInterface", typeof (MyInterface)); | ||
} | ||
|
||
[Register ("java/code/IMyInterface", DoNotGenerateAcw=true)] | ||
[global::System.Obsolete ("Use the 'MyInterface' type. This type will be removed in a future release.")] | ||
public abstract class MyInterfaceConsts : MyInterface { | ||
|
||
private MyInterfaceConsts () | ||
{ | ||
} | ||
} | ||
|
||
// Metadata.xml XPath interface reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']" | ||
[Register ("java/code/IMyInterface", "", "java.code.IMyInterfaceInvoker")] | ||
public partial interface IMyInterface : IJavaObject, IJavaPeerable { | ||
static new readonly JniPeerMembers _members = new JniPeerMembers ("java/code/IMyInterface", typeof (IMyInterface), isInterface: true); | ||
|
||
// Metadata.xml XPath method reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/method[@name='DoSomething' and count(parameter)=0]" | ||
[Register ("DoSomething", "()V", "")] | ||
public static unsafe void DoSomething () | ||
{ | ||
const string __id = "DoSomething.()V"; | ||
try { | ||
_members.StaticMethods.InvokeVoidMethod (__id, null); | ||
} finally { | ||
} | ||
} | ||
|
||
} | ||
|
||
[global::Android.Runtime.Register ("java/code/IMyInterface", DoNotGenerateAcw=true)] | ||
internal partial class IMyInterfaceInvoker : global::Java.Lang.Object, IMyInterface { | ||
|
||
internal static new readonly JniPeerMembers _members = new JniPeerMembers ("java/code/IMyInterface", typeof (IMyInterfaceInvoker)); | ||
|
||
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 IMyInterface GetObject (IntPtr handle, JniHandleOwnership transfer) | ||
{ | ||
return global::Java.Lang.Object.GetObject<IMyInterface> (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), "java.code.IMyInterface")); | ||
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 IMyInterfaceInvoker (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); | ||
} | ||
|
||
} | ||
|
31 changes: 31 additions & 0 deletions
31
...sts/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteStaticInterfaceProperty.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// Metadata.xml XPath interface reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']" | ||
[Register ("java/code/IMyInterface", "", "java.code.IMyInterfaceInvoker")] | ||
public partial interface IMyInterface : IJavaObject, IJavaPeerable { | ||
static new readonly JniPeerMembers _members = new JniPeerMembers ("java/code/IMyInterface", typeof (IMyInterface), isInterface: true); | ||
|
||
static unsafe int Value { | ||
// Metadata.xml XPath method reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/method[@name='get_Value' and count(parameter)=0]" | ||
[Register ("get_Value", "()I", "Getget_ValueHandler")] | ||
get { | ||
const string __id = "get_Value.()I"; | ||
try { | ||
var __rm = _members.StaticMethods.InvokeInt32Method (__id, null); | ||
return __rm; | ||
} finally { | ||
} | ||
} | ||
// Metadata.xml XPath method reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/method[@name='set_Value' and count(parameter)=1 and parameter[1][@type='int']]" | ||
[Register ("set_Value", "(I)V", "Getset_Value_IHandler")] | ||
set { | ||
const string __id = "set_Value.(I)V"; | ||
try { | ||
JniArgumentValue* __args = stackalloc JniArgumentValue [1]; | ||
__args [0] = new JniArgumentValue (value); | ||
_members.StaticMethods.InvokeVoidMethod (__id, __args); | ||
} finally { | ||
} | ||
} | ||
} | ||
|
||
} | ||
|
101 changes: 101 additions & 0 deletions
101
...sts/Unit-Tests/CodeGeneratorExpectedResults/XAJavaInterop1/WriteStaticInterfaceMethod.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
[Register ("java/code/IMyInterface", DoNotGenerateAcw=true)] | ||
public abstract class MyInterface : Java.Lang.Object { | ||
|
||
internal MyInterface () | ||
{ | ||
} | ||
// Metadata.xml XPath method reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/method[@name='DoSomething' and count(parameter)=0]" | ||
[Register ("DoSomething", "()V", "")] | ||
public static unsafe void DoSomething () | ||
{ | ||
const string __id = "DoSomething.()V"; | ||
try { | ||
_members.StaticMethods.InvokeVoidMethod (__id, null); | ||
} finally { | ||
} | ||
} | ||
|
||
|
||
static new readonly JniPeerMembers _members = new XAPeerMembers ("java/code/IMyInterface", typeof (MyInterface)); | ||
} | ||
|
||
[Register ("java/code/IMyInterface", DoNotGenerateAcw=true)] | ||
[global::System.Obsolete ("Use the 'MyInterface' type. This type will be removed in a future release.")] | ||
public abstract class MyInterfaceConsts : MyInterface { | ||
|
||
private MyInterfaceConsts () | ||
{ | ||
} | ||
} | ||
|
||
// Metadata.xml XPath interface reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']" | ||
[Register ("java/code/IMyInterface", "", "java.code.IMyInterfaceInvoker")] | ||
public partial interface IMyInterface : IJavaObject, IJavaPeerable { | ||
static new readonly JniPeerMembers _members = new XAPeerMembers ("java/code/IMyInterface", typeof (IMyInterface), isInterface: true); | ||
|
||
// Metadata.xml XPath method reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/method[@name='DoSomething' and count(parameter)=0]" | ||
[Register ("DoSomething", "()V", "")] | ||
public static unsafe void DoSomething () | ||
{ | ||
const string __id = "DoSomething.()V"; | ||
try { | ||
_members.StaticMethods.InvokeVoidMethod (__id, null); | ||
} finally { | ||
} | ||
} | ||
|
||
} | ||
|
||
[global::Android.Runtime.Register ("java/code/IMyInterface", DoNotGenerateAcw=true)] | ||
internal partial class IMyInterfaceInvoker : global::Java.Lang.Object, IMyInterface { | ||
|
||
internal static new readonly JniPeerMembers _members = new XAPeerMembers ("java/code/IMyInterface", typeof (IMyInterfaceInvoker)); | ||
|
||
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 IMyInterface GetObject (IntPtr handle, JniHandleOwnership transfer) | ||
{ | ||
return global::Java.Lang.Object.GetObject<IMyInterface> (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), "java.code.IMyInterface")); | ||
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 IMyInterfaceInvoker (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); | ||
} | ||
|
||
} | ||
|
31 changes: 31 additions & 0 deletions
31
...s/Unit-Tests/CodeGeneratorExpectedResults/XAJavaInterop1/WriteStaticInterfaceProperty.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// Metadata.xml XPath interface reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']" | ||
[Register ("java/code/IMyInterface", "", "java.code.IMyInterfaceInvoker")] | ||
public partial interface IMyInterface : IJavaObject, IJavaPeerable { | ||
static new readonly JniPeerMembers _members = new XAPeerMembers ("java/code/IMyInterface", typeof (IMyInterface), isInterface: true); | ||
|
||
static unsafe int Value { | ||
// Metadata.xml XPath method reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/method[@name='get_Value' and count(parameter)=0]" | ||
[Register ("get_Value", "()I", "Getget_ValueHandler")] | ||
get { | ||
const string __id = "get_Value.()I"; | ||
try { | ||
var __rm = _members.StaticMethods.InvokeInt32Method (__id, null); | ||
return __rm; | ||
} finally { | ||
} | ||
} | ||
// Metadata.xml XPath method reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/method[@name='set_Value' and count(parameter)=1 and parameter[1][@type='int']]" | ||
[Register ("set_Value", "(I)V", "Getset_Value_IHandler")] | ||
set { | ||
const string __id = "set_Value.(I)V"; | ||
try { | ||
JniArgumentValue* __args = stackalloc JniArgumentValue [1]; | ||
__args [0] = new JniArgumentValue (value); | ||
_members.StaticMethods.InvokeVoidMethod (__id, __args); | ||
} finally { | ||
} | ||
} | ||
} | ||
|
||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters