Skip to content

Commit ddbdfae

Browse files
committed
[generator] Use DIM to support static interface methods.
1 parent 3fee05c commit ddbdfae

File tree

8 files changed

+381
-4
lines changed

8 files changed

+381
-4
lines changed

tools/generator/Java.Interop.Tools.Generator.CodeGeneration/CodeGenerator.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,7 @@ public void WriteInterfaceDeclaration (InterfaceGen @interface, string indent)
530530
writer.WriteLine ("{0}{1} partial interface {2}{3} {{", indent, @interface.Visibility, @interface.Name,
531531
@interface.IsConstSugar ? string.Empty : @interface.Interfaces.Count == 0 || sb.Length == 0 ? " : " + GetAllInterfaceImplements () : " : " + sb.ToString ());
532532

533-
if (opt.SupportDefaultInterfaceMethods && @interface.HasDefaultMethods)
533+
if (opt.SupportDefaultInterfaceMethods && (@interface.HasDefaultMethods || @interface.HasStaticMethods))
534534
WriteClassHandle (@interface, indent + "\t", @interface.Name);
535535

536536
WriteInterfaceFields (@interface, indent + "\t");
@@ -994,16 +994,18 @@ public void WriteInterfaceMethods (InterfaceGen @interface, string indent)
994994
WriteMethodDeclaration (m, indent, @interface, @interface.AssemblyQualifiedName + "Invoker");
995995
}
996996

997-
foreach (var m in @interface.Methods.Where (m => m.IsInterfaceDefaultMethod))
998-
WriteMethod (m, indent, @interface, true);
997+
if (opt.SupportDefaultInterfaceMethods)
998+
foreach (var m in @interface.Methods.Where (m => m.IsInterfaceDefaultMethod || m.IsStatic))
999+
WriteMethod (m, indent, @interface, true);
9991000
}
10001001

10011002
public void WriteInterfaceProperties (InterfaceGen @interface, string indent)
10021003
{
10031004
foreach (var prop in @interface.Properties.Where (p => !p.Getter.IsStatic && !p.Getter.IsInterfaceDefaultMethod))
10041005
WritePropertyDeclaration (prop, indent, @interface, @interface.AssemblyQualifiedName + "Invoker");
10051006

1006-
WriteImplementedProperties (@interface.Properties.Where (p => p.Getter.IsInterfaceDefaultMethod), indent, false, @interface);
1007+
if (opt.SupportDefaultInterfaceMethods)
1008+
WriteImplementedProperties (@interface.Properties.Where (p => p.Getter.IsInterfaceDefaultMethod || p.Getter.IsStatic), indent, false, @interface);
10071009
}
10081010

10091011
public void WriteInterfacePropertyInvokers (InterfaceGen @interface, IEnumerable<Property> properties, string indent, HashSet<string> members)

tools/generator/Java.Interop.Tools.Generator.ObjectModel/InterfaceGen.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ public IEnumerable<Field> GetGeneratableFields (CodeGenerationOptions options)
143143

144144
public bool HasDefaultMethods => GetAllMethods ().Any (m => m.IsInterfaceDefaultMethod);
145145

146+
public bool HasStaticMethods => GetAllMethods ().Any (m => m.IsStatic);
147+
146148
public bool IsConstSugar {
147149
get {
148150
if (Methods.Count > 0 || Properties.Count > 0)
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
[Register ("java/code/IMyInterface", DoNotGenerateAcw=true)]
2+
public abstract class MyInterface : Java.Lang.Object {
3+
4+
internal MyInterface ()
5+
{
6+
}
7+
// Metadata.xml XPath method reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/method[@name='DoSomething' and count(parameter)=0]"
8+
[Register ("DoSomething", "()V", "")]
9+
public static unsafe void DoSomething ()
10+
{
11+
const string __id = "DoSomething.()V";
12+
try {
13+
_members.StaticMethods.InvokeVoidMethod (__id, null);
14+
} finally {
15+
}
16+
}
17+
18+
19+
static new readonly JniPeerMembers _members = new JniPeerMembers ("java/code/IMyInterface", typeof (MyInterface));
20+
}
21+
22+
[Register ("java/code/IMyInterface", DoNotGenerateAcw=true)]
23+
[global::System.Obsolete ("Use the 'MyInterface' type. This type will be removed in a future release.")]
24+
public abstract class MyInterfaceConsts : MyInterface {
25+
26+
private MyInterfaceConsts ()
27+
{
28+
}
29+
}
30+
31+
// Metadata.xml XPath interface reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']"
32+
[Register ("java/code/IMyInterface", "", "java.code.IMyInterfaceInvoker")]
33+
public partial interface IMyInterface : IJavaObject, IJavaPeerable {
34+
static new readonly JniPeerMembers _members = new JniPeerMembers ("java/code/IMyInterface", typeof (IMyInterface), isInterface: true);
35+
36+
// Metadata.xml XPath method reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/method[@name='DoSomething' and count(parameter)=0]"
37+
[Register ("DoSomething", "()V", "")]
38+
public static unsafe void DoSomething ()
39+
{
40+
const string __id = "DoSomething.()V";
41+
try {
42+
_members.StaticMethods.InvokeVoidMethod (__id, null);
43+
} finally {
44+
}
45+
}
46+
47+
}
48+
49+
[global::Android.Runtime.Register ("java/code/IMyInterface", DoNotGenerateAcw=true)]
50+
internal partial class IMyInterfaceInvoker : global::Java.Lang.Object, IMyInterface {
51+
52+
internal static new readonly JniPeerMembers _members = new JniPeerMembers ("java/code/IMyInterface", typeof (IMyInterfaceInvoker));
53+
54+
static IntPtr java_class_ref {
55+
get { return _members.JniPeerType.PeerReference.Handle; }
56+
}
57+
58+
public override global::Java.Interop.JniPeerMembers JniPeerMembers {
59+
get { return _members; }
60+
}
61+
62+
protected override IntPtr ThresholdClass {
63+
get { return class_ref; }
64+
}
65+
66+
protected override global::System.Type ThresholdType {
67+
get { return _members.ManagedPeerType; }
68+
}
69+
70+
IntPtr class_ref;
71+
72+
public static IMyInterface GetObject (IntPtr handle, JniHandleOwnership transfer)
73+
{
74+
return global::Java.Lang.Object.GetObject<IMyInterface> (handle, transfer);
75+
}
76+
77+
static IntPtr Validate (IntPtr handle)
78+
{
79+
if (!JNIEnv.IsInstanceOf (handle, java_class_ref))
80+
throw new InvalidCastException (string.Format ("Unable to convert instance of type '{0}' to type '{1}'.",
81+
JNIEnv.GetClassNameFromInstance (handle), "java.code.IMyInterface"));
82+
return handle;
83+
}
84+
85+
protected override void Dispose (bool disposing)
86+
{
87+
if (this.class_ref != IntPtr.Zero)
88+
JNIEnv.DeleteGlobalRef (this.class_ref);
89+
this.class_ref = IntPtr.Zero;
90+
base.Dispose (disposing);
91+
}
92+
93+
public IMyInterfaceInvoker (IntPtr handle, JniHandleOwnership transfer) : base (Validate (handle), transfer)
94+
{
95+
IntPtr local_ref = JNIEnv.GetObjectClass (((global::Java.Lang.Object) this).Handle);
96+
this.class_ref = JNIEnv.NewGlobalRef (local_ref);
97+
JNIEnv.DeleteLocalRef (local_ref);
98+
}
99+
100+
}
101+
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Metadata.xml XPath interface reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']"
2+
[Register ("java/code/IMyInterface", "", "java.code.IMyInterfaceInvoker")]
3+
public partial interface IMyInterface : IJavaObject, IJavaPeerable {
4+
static new readonly JniPeerMembers _members = new JniPeerMembers ("java/code/IMyInterface", typeof (IMyInterface), isInterface: true);
5+
6+
static Delegate cb_get_Value;
7+
#pragma warning disable 0169
8+
static Delegate Getget_ValueHandler ()
9+
{
10+
if (cb_get_Value == null)
11+
cb_get_Value = JNINativeWrapper.CreateDelegate ((Func<IntPtr, IntPtr, int>) n_get_Value);
12+
return cb_get_Value;
13+
}
14+
15+
static int n_get_Value (IntPtr jnienv, IntPtr native__this)
16+
{
17+
java.code.IMyInterface __this = global::Java.Lang.Object.GetObject<java.code.IMyInterface> (jnienv, native__this, JniHandleOwnership.DoNotTransfer);
18+
return __this.Value;
19+
}
20+
#pragma warning restore 0169
21+
22+
static Delegate cb_set_Value_I;
23+
#pragma warning disable 0169
24+
static Delegate Getset_Value_IHandler ()
25+
{
26+
if (cb_set_Value_I == null)
27+
cb_set_Value_I = JNINativeWrapper.CreateDelegate ((Action<IntPtr, IntPtr, int>) n_set_Value_I);
28+
return cb_set_Value_I;
29+
}
30+
31+
static void n_set_Value_I (IntPtr jnienv, IntPtr native__this, int value)
32+
{
33+
java.code.IMyInterface __this = global::Java.Lang.Object.GetObject<java.code.IMyInterface> (jnienv, native__this, JniHandleOwnership.DoNotTransfer);
34+
__this.Value = value;
35+
}
36+
#pragma warning restore 0169
37+
38+
static unsafe int Value {
39+
// Metadata.xml XPath method reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/method[@name='get_Value' and count(parameter)=0]"
40+
[Register ("get_Value", "()I", "Getget_ValueHandler")]
41+
get {
42+
const string __id = "get_Value.()I";
43+
try {
44+
var __rm = _members.StaticMethods.InvokeInt32Method (__id, null);
45+
return __rm;
46+
} finally {
47+
}
48+
}
49+
// 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']]"
50+
[Register ("set_Value", "(I)V", "Getset_Value_IHandler")]
51+
set {
52+
const string __id = "set_Value.(I)V";
53+
try {
54+
JniArgumentValue* __args = stackalloc JniArgumentValue [1];
55+
__args [0] = new JniArgumentValue (value);
56+
_members.StaticMethods.InvokeVoidMethod (__id, __args);
57+
} finally {
58+
}
59+
}
60+
}
61+
62+
}
63+
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
[Register ("java/code/IMyInterface", DoNotGenerateAcw=true)]
2+
public abstract class MyInterface : Java.Lang.Object {
3+
4+
internal MyInterface ()
5+
{
6+
}
7+
// Metadata.xml XPath method reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/method[@name='DoSomething' and count(parameter)=0]"
8+
[Register ("DoSomething", "()V", "")]
9+
public static unsafe void DoSomething ()
10+
{
11+
const string __id = "DoSomething.()V";
12+
try {
13+
_members.StaticMethods.InvokeVoidMethod (__id, null);
14+
} finally {
15+
}
16+
}
17+
18+
19+
static new readonly JniPeerMembers _members = new XAPeerMembers ("java/code/IMyInterface", typeof (MyInterface));
20+
}
21+
22+
[Register ("java/code/IMyInterface", DoNotGenerateAcw=true)]
23+
[global::System.Obsolete ("Use the 'MyInterface' type. This type will be removed in a future release.")]
24+
public abstract class MyInterfaceConsts : MyInterface {
25+
26+
private MyInterfaceConsts ()
27+
{
28+
}
29+
}
30+
31+
// Metadata.xml XPath interface reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']"
32+
[Register ("java/code/IMyInterface", "", "java.code.IMyInterfaceInvoker")]
33+
public partial interface IMyInterface : IJavaObject, IJavaPeerable {
34+
static new readonly JniPeerMembers _members = new XAPeerMembers ("java/code/IMyInterface", typeof (IMyInterface), isInterface: true);
35+
36+
// Metadata.xml XPath method reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/method[@name='DoSomething' and count(parameter)=0]"
37+
[Register ("DoSomething", "()V", "")]
38+
public static unsafe void DoSomething ()
39+
{
40+
const string __id = "DoSomething.()V";
41+
try {
42+
_members.StaticMethods.InvokeVoidMethod (__id, null);
43+
} finally {
44+
}
45+
}
46+
47+
}
48+
49+
[global::Android.Runtime.Register ("java/code/IMyInterface", DoNotGenerateAcw=true)]
50+
internal partial class IMyInterfaceInvoker : global::Java.Lang.Object, IMyInterface {
51+
52+
internal static new readonly JniPeerMembers _members = new XAPeerMembers ("java/code/IMyInterface", typeof (IMyInterfaceInvoker));
53+
54+
static IntPtr java_class_ref {
55+
get { return _members.JniPeerType.PeerReference.Handle; }
56+
}
57+
58+
public override global::Java.Interop.JniPeerMembers JniPeerMembers {
59+
get { return _members; }
60+
}
61+
62+
protected override IntPtr ThresholdClass {
63+
get { return class_ref; }
64+
}
65+
66+
protected override global::System.Type ThresholdType {
67+
get { return _members.ManagedPeerType; }
68+
}
69+
70+
IntPtr class_ref;
71+
72+
public static IMyInterface GetObject (IntPtr handle, JniHandleOwnership transfer)
73+
{
74+
return global::Java.Lang.Object.GetObject<IMyInterface> (handle, transfer);
75+
}
76+
77+
static IntPtr Validate (IntPtr handle)
78+
{
79+
if (!JNIEnv.IsInstanceOf (handle, java_class_ref))
80+
throw new InvalidCastException (string.Format ("Unable to convert instance of type '{0}' to type '{1}'.",
81+
JNIEnv.GetClassNameFromInstance (handle), "java.code.IMyInterface"));
82+
return handle;
83+
}
84+
85+
protected override void Dispose (bool disposing)
86+
{
87+
if (this.class_ref != IntPtr.Zero)
88+
JNIEnv.DeleteGlobalRef (this.class_ref);
89+
this.class_ref = IntPtr.Zero;
90+
base.Dispose (disposing);
91+
}
92+
93+
public IMyInterfaceInvoker (IntPtr handle, JniHandleOwnership transfer) : base (Validate (handle), transfer)
94+
{
95+
IntPtr local_ref = JNIEnv.GetObjectClass (((global::Java.Lang.Object) this).Handle);
96+
this.class_ref = JNIEnv.NewGlobalRef (local_ref);
97+
JNIEnv.DeleteLocalRef (local_ref);
98+
}
99+
100+
}
101+
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Metadata.xml XPath interface reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']"
2+
[Register ("java/code/IMyInterface", "", "java.code.IMyInterfaceInvoker")]
3+
public partial interface IMyInterface : IJavaObject, IJavaPeerable {
4+
static new readonly JniPeerMembers _members = new XAPeerMembers ("java/code/IMyInterface", typeof (IMyInterface), isInterface: true);
5+
6+
static Delegate cb_get_Value;
7+
#pragma warning disable 0169
8+
static Delegate Getget_ValueHandler ()
9+
{
10+
if (cb_get_Value == null)
11+
cb_get_Value = JNINativeWrapper.CreateDelegate ((Func<IntPtr, IntPtr, int>) n_get_Value);
12+
return cb_get_Value;
13+
}
14+
15+
static int n_get_Value (IntPtr jnienv, IntPtr native__this)
16+
{
17+
java.code.IMyInterface __this = global::Java.Lang.Object.GetObject<java.code.IMyInterface> (jnienv, native__this, JniHandleOwnership.DoNotTransfer);
18+
return __this.Value;
19+
}
20+
#pragma warning restore 0169
21+
22+
static Delegate cb_set_Value_I;
23+
#pragma warning disable 0169
24+
static Delegate Getset_Value_IHandler ()
25+
{
26+
if (cb_set_Value_I == null)
27+
cb_set_Value_I = JNINativeWrapper.CreateDelegate ((Action<IntPtr, IntPtr, int>) n_set_Value_I);
28+
return cb_set_Value_I;
29+
}
30+
31+
static void n_set_Value_I (IntPtr jnienv, IntPtr native__this, int value)
32+
{
33+
java.code.IMyInterface __this = global::Java.Lang.Object.GetObject<java.code.IMyInterface> (jnienv, native__this, JniHandleOwnership.DoNotTransfer);
34+
__this.Value = value;
35+
}
36+
#pragma warning restore 0169
37+
38+
static unsafe int Value {
39+
// Metadata.xml XPath method reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/method[@name='get_Value' and count(parameter)=0]"
40+
[Register ("get_Value", "()I", "Getget_ValueHandler")]
41+
get {
42+
const string __id = "get_Value.()I";
43+
try {
44+
var __rm = _members.StaticMethods.InvokeInt32Method (__id, null);
45+
return __rm;
46+
} finally {
47+
}
48+
}
49+
// 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']]"
50+
[Register ("set_Value", "(I)V", "Getset_Value_IHandler")]
51+
set {
52+
const string __id = "set_Value.(I)V";
53+
try {
54+
JniArgumentValue* __args = stackalloc JniArgumentValue [1];
55+
__args [0] = new JniArgumentValue (value);
56+
_members.StaticMethods.InvokeVoidMethod (__id, __args);
57+
} finally {
58+
}
59+
}
60+
}
61+
62+
}
63+

0 commit comments

Comments
 (0)