Skip to content
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

[Java.Interop] Add JniTypeSignatureAttribute.InvokerType #1284

Merged
merged 2 commits into from
Dec 9, 2024
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
294 changes: 147 additions & 147 deletions src/Java.Base-ref.cs

Large diffs are not rendered by default.

27 changes: 8 additions & 19 deletions src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -386,18 +386,9 @@ static Type GetPeerType ([DynamicallyAccessedMembers (Constructors)] Type type)
[return: DynamicallyAccessedMembers (Constructors)]
static Type? GetInvokerType (Type type)
{
const string suffix = "Invoker";

// https://github.com/xamarin/xamarin-android/blob/5472eec991cc075e4b0c09cd98a2331fb93aa0f3/src/Microsoft.Android.Sdk.ILLink/MarkJavaObjects.cs#L176-L186
const string assemblyGetTypeMessage = "'Invoker' types are preserved by the MarkJavaObjects trimmer step.";
const string makeGenericTypeMessage = "Generic 'Invoker' types are preserved by the MarkJavaObjects trimmer step.";

[UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = assemblyGetTypeMessage)]
[UnconditionalSuppressMessage ("Trimming", "IL2073", Justification = assemblyGetTypeMessage)]
[return: DynamicallyAccessedMembers (Constructors)]
static Type? AssemblyGetType (Assembly assembly, string typeName) =>
assembly.GetType (typeName);
Comment on lines -395 to -399
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's good to remove this, it's probably not called on Android anyway, and this is used instead:


[UnconditionalSuppressMessage ("Trimming", "IL2055", Justification = makeGenericTypeMessage)]
[return: DynamicallyAccessedMembers (Constructors)]
static Type MakeGenericType (
Expand All @@ -409,18 +400,16 @@ static Type MakeGenericType (
type.MakeGenericType (arguments);
#pragma warning restore IL3050

var signature = type.GetCustomAttribute<JniTypeSignatureAttribute> ();
if (signature == null || signature.InvokerType == null) {
return null;
}

Type[] arguments = type.GetGenericArguments ();
if (arguments.Length == 0)
return AssemblyGetType (type.Assembly, type + suffix);
Type definition = type.GetGenericTypeDefinition ();
int bt = definition.FullName!.IndexOf ("`", StringComparison.Ordinal);
if (bt == -1)
throw new NotSupportedException ("Generic type doesn't follow generic type naming convention! " + type.FullName);
Type? suffixDefinition = AssemblyGetType (definition.Assembly,
definition.FullName.Substring (0, bt) + suffix + definition.FullName.Substring (bt));
if (suffixDefinition == null)
return null;
return MakeGenericType (suffixDefinition, arguments);
return signature.InvokerType;

return MakeGenericType (signature.InvokerType, arguments);
}

public object? CreateValue (
Expand Down
4 changes: 4 additions & 0 deletions src/Java.Interop/Java.Interop/JniTypeSignatureAttribute.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#nullable enable

using System;
using System.Diagnostics.CodeAnalysis;

namespace Java.Interop
{
Expand Down Expand Up @@ -31,6 +32,9 @@ public int ArrayRank {
}

public bool GenerateJavaPeer {get; set;}

[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
public Type? InvokerType {get; set;}
Comment on lines +36 to +37
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The trimmer warnings might not require this, but should this also preserve interfaces? Just thinking generally, if it needs to.

In theory, that would make every interface preserve its interface implementations?

  • Trimmer decides IFoo is used, and wants to keep the type
  • InvokerType=typeof(FooInvoker) preserves the invoker
  • InvokerType=typeof(FooInvoker) then could also preserve all interface implementations of IFoo?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the TL;DR is that "as-is", the NativeAOT linker cannot be made to do what we want it to do, and I'm not sure if it'll "ever" be supported in some "reasonable" timeframe.

Related:

I would also consider not using All unless we absolutely have to. All is kind of weird in that it will keep really everything about the type, so for example if the type implements an interface it will force all the methods on that interface to be kept (for everybody) and so on.

Part of the issue is that this InvokerType property is used for both abstract classes and interfaces.

The semantic we "need" is "preserve all method overrides/interface implementations." We can't express that semantic right now (afaik).

Trying to "fake" the above semantic with "okay, just preserve everything on the type" means that we'll preserve everything on the type. This is "fine" for interfaces (but see below), but is not fine for abstract classes. Consider LauncherActivity: as it's an Context+Activity subclass, it contains dozens of members through the inheritance chain. We almost certainly do not need most of that infrastructure; we only need the infrastructure used by the method override!

Since, afaik, we can't actually get our desired semantic right now, and "preserve everything" looks like it would have terrible implications on app size when applied to abstract classes, I see only two solutions here:

  • InterfaceInvokerType vs. AbstractClassInvokerType properties! Which is possible, but ugh.
  • Go with the least restrictive yet useful constraint (preserve constructors), and rely on "stuff elsewhere" to ensure things work and we get closer to our ideal semantic.

Additionally, "preserve everything" isn't even a useful constraint on interfaces! It's mostly correct, for non-default instance methods. Pull in a default method, or static members, and we certainly should be able to trim those away!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I was just suggesting interfaces, not All, but yeah that doesn't make sense for abstract classes.

}
}

2 changes: 2 additions & 0 deletions src/Java.Interop/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ static Java.Interop.JniEnvironment.BeginMarshalMethod(nint jnienv, out Java.Inte
static Java.Interop.JniEnvironment.EndMarshalMethod(ref Java.Interop.JniTransition transition) -> void
virtual Java.Interop.JniRuntime.OnEnterMarshalMethod() -> void
virtual Java.Interop.JniRuntime.OnUserUnhandledException(ref Java.Interop.JniTransition transition, System.Exception! e) -> void
Java.Interop.JniTypeSignatureAttribute.InvokerType.get -> System.Type?
Java.Interop.JniTypeSignatureAttribute.InvokerType.set -> void
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public unsafe MyJavaInterfaceImpl ()
}
}

[JniTypeSignature (JniTypeName, GenerateJavaPeer=false)]
[JniTypeSignature (JniTypeName, GenerateJavaPeer=false, InvokerType=typeof(IJavaInterfaceInvoker))]
interface IJavaInterface : IJavaPeerable {
internal const string JniTypeName = "net/dot/jni/test/JavaInterface";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Metadata.xml XPath interface reference: path="/api/package[@name='java.code']/interface[@name='AnimatorListener']"
[global::Java.Interop.JniTypeSignature ("java/code/AnimatorListener", GenerateJavaPeer=false)]
[global::Java.Interop.JniTypeSignature ("java/code/AnimatorListener", GenerateJavaPeer=false, InvokerType=typeof (java.code.AnimatorListenerInvoker))]
public partial interface AnimatorListener : IJavaPeerable {
// Metadata.xml XPath method reference: path="/api/package[@name='java.code']/interface[@name='AnimatorListener']/method[@name='OnAnimationEnd' and count(parameter)=1 and parameter[1][@type='int']]"
[global::Java.Interop.JniMethodSignature ("OnAnimationEnd", "(I)Z")]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Metadata.xml XPath interface reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']"
[global::Java.Interop.JniTypeSignature ("java/code/IMyInterface", GenerateJavaPeer=false)]
[global::Java.Interop.JniTypeSignature ("java/code/IMyInterface", GenerateJavaPeer=false, InvokerType=typeof (java.code.IMyInterfaceInvoker))]
public partial interface IMyInterface : IJavaPeerable {
private static readonly JniPeerMembers _members = new JniPeerMembers ("java/code/IMyInterface", typeof (IMyInterface), isInterface: true);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Xamarin.Test {

// Metadata.xml XPath interface reference: path="/api/package[@name='xamarin.test']/interface[@name='ExtendedInterface']"
[global::Java.Interop.JniTypeSignature ("xamarin/test/ExtendedInterface", GenerateJavaPeer=false)]
[global::Java.Interop.JniTypeSignature ("xamarin/test/ExtendedInterface", GenerateJavaPeer=false, InvokerType=typeof (Xamarin.Test.IExtendedInterfaceInvoker))]
public partial interface IExtendedInterface : IJavaPeerable {
// Metadata.xml XPath method reference: path="/api/package[@name='xamarin.test']/interface[@name='ExtendedInterface']/method[@name='extendedMethod' and count(parameter)=0]"
[global::Java.Interop.JniMethodSignature ("extendedMethod", "()V")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace Xamarin.Test {
[global::Java.Interop.JniTypeSignature ("xamarin/test/PublicClass", GenerateJavaPeer=false)]
public partial class PublicClass : global::Java.Lang.Object {
// Metadata.xml XPath interface reference: path="/api/package[@name='xamarin.test']/interface[@name='PublicClass.ProtectedInterface']"
[global::Java.Interop.JniTypeSignature ("xamarin/test/PublicClass$ProtectedInterface", GenerateJavaPeer=false)]
[global::Java.Interop.JniTypeSignature ("xamarin/test/PublicClass$ProtectedInterface", GenerateJavaPeer=false, InvokerType=typeof (Xamarin.Test.PublicClass.IProtectedInterfaceInvoker))]
protected internal partial interface IProtectedInterface : IJavaPeerable {
// Metadata.xml XPath method reference: path="/api/package[@name='xamarin.test']/interface[@name='PublicClass.ProtectedInterface']/method[@name='foo' and count(parameter)=0]"
[global::Java.Interop.JniMethodSignature ("foo", "()V")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
namespace Xamarin.Test {

// Metadata.xml XPath class reference: path="/api/package[@name='xamarin.test']/class[@name='AbsSpinner']"
[global::Java.Interop.JniTypeSignature ("xamarin/test/AbsSpinner", GenerateJavaPeer=false)]
[global::Java.Interop.JniTypeSignature ("xamarin/test/AbsSpinner", GenerateJavaPeer=false, InvokerType=typeof (AbsSpinnerInvoker))]
public abstract partial class AbsSpinner : Xamarin.Test.AdapterView<Xamarin.Test.ISpinnerAdapter> {
static readonly JniPeerMembers _members = new JniPeerMembers ("xamarin/test/AbsSpinner", typeof (AbsSpinner));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
namespace Xamarin.Test {

// Metadata.xml XPath class reference: path="/api/package[@name='xamarin.test']/class[@name='AdapterView']"
[global::Java.Interop.JniTypeSignature ("xamarin/test/AdapterView", GenerateJavaPeer=false)]
[global::Java.Interop.JniTypeSignature ("xamarin/test/AdapterView", GenerateJavaPeer=false, InvokerType=typeof (AdapterViewInvoker))]
[global::Java.Interop.JavaTypeParameters (new string [] {"T extends xamarin.test.Adapter"})]
public abstract partial class AdapterView : global::Java.Lang.Object {
static readonly JniPeerMembers _members = new JniPeerMembers ("xamarin/test/AdapterView", typeof (AdapterView));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Xamarin.Test {

// Metadata.xml XPath interface reference: path="/api/package[@name='xamarin.test']/interface[@name='Adapter']"
[global::Java.Interop.JniTypeSignature ("xamarin/test/Adapter", GenerateJavaPeer=false)]
[global::Java.Interop.JniTypeSignature ("xamarin/test/Adapter", GenerateJavaPeer=false, InvokerType=typeof (Xamarin.Test.IAdapterInvoker))]
public partial interface IAdapter : IJavaPeerable {
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Xamarin.Test {

// Metadata.xml XPath interface reference: path="/api/package[@name='xamarin.test']/interface[@name='SpinnerAdapter']"
[global::Java.Interop.JniTypeSignature ("xamarin/test/SpinnerAdapter", GenerateJavaPeer=false)]
[global::Java.Interop.JniTypeSignature ("xamarin/test/SpinnerAdapter", GenerateJavaPeer=false, InvokerType=typeof (Xamarin.Test.ISpinnerAdapterInvoker))]
public partial interface ISpinnerAdapter : global::Xamarin.Test.IAdapter {
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
namespace Xamarin.Test {

// Metadata.xml XPath class reference: path="/api/package[@name='xamarin.test']/class[@name='SomeObject']"
[global::Java.Interop.JniTypeSignature ("xamarin/test/SomeObject", GenerateJavaPeer=false)]
[global::Java.Interop.JniTypeSignature ("xamarin/test/SomeObject", GenerateJavaPeer=false, InvokerType=typeof (SomeObjectInvoker))]
public abstract partial class SomeObject : global::Java.Lang.Object {
static readonly JniPeerMembers _members = new JniPeerMembers ("xamarin/test/SomeObject", typeof (SomeObject));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Xamarin.Test {

// Metadata.xml XPath interface reference: path="/api/package[@name='xamarin.test']/interface[@name='I1']"
[global::Java.Interop.JniTypeSignature ("xamarin/test/I1", GenerateJavaPeer=false)]
[global::Java.Interop.JniTypeSignature ("xamarin/test/I1", GenerateJavaPeer=false, InvokerType=typeof (Xamarin.Test.II1Invoker))]
public partial interface II1 : IJavaPeerable {
// Metadata.xml XPath method reference: path="/api/package[@name='xamarin.test']/interface[@name='I1']/method[@name='close' and count(parameter)=0]"
[global::Java.Interop.JniMethodSignature ("close", "()V")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Xamarin.Test {

// Metadata.xml XPath interface reference: path="/api/package[@name='xamarin.test']/interface[@name='I2']"
[global::Java.Interop.JniTypeSignature ("xamarin/test/I2", GenerateJavaPeer=false)]
[global::Java.Interop.JniTypeSignature ("xamarin/test/I2", GenerateJavaPeer=false, InvokerType=typeof (Xamarin.Test.II2Invoker))]
public partial interface II2 : IJavaPeerable {
// Metadata.xml XPath method reference: path="/api/package[@name='xamarin.test']/interface[@name='I2']/method[@name='close' and count(parameter)=0]"
[global::Java.Interop.JniMethodSignature ("close", "()V")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
namespace Xamarin.Test {

// Metadata.xml XPath class reference: path="/api/package[@name='xamarin.test']/class[@name='SomeObject2']"
[global::Java.Interop.JniTypeSignature ("xamarin/test/SomeObject2", GenerateJavaPeer=false)]
[global::Java.Interop.JniTypeSignature ("xamarin/test/SomeObject2", GenerateJavaPeer=false, InvokerType=typeof (SomeObject2Invoker))]
public abstract partial class SomeObject2 : global::Java.Lang.Object, global::Xamarin.Test.II1, global::Xamarin.Test.II2 {
static readonly JniPeerMembers _members = new JniPeerMembers ("xamarin/test/SomeObject2", typeof (SomeObject2));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ namespace Xamarin.Test {
[global::Java.Interop.JniTypeSignature ("xamarin/test/NotificationCompatBase", GenerateJavaPeer=false)]
public partial class NotificationCompatBase : global::Java.Lang.Object {
// Metadata.xml XPath class reference: path="/api/package[@name='xamarin.test']/class[@name='NotificationCompatBase.Action']"
[global::Java.Interop.JniTypeSignature ("xamarin/test/NotificationCompatBase$Action", GenerateJavaPeer=false)]
[global::Java.Interop.JniTypeSignature ("xamarin/test/NotificationCompatBase$Action", GenerateJavaPeer=false, InvokerType=typeof (ActionInvoker))]
public abstract partial class Action : global::Java.Lang.Object {
// Metadata.xml XPath interface reference: path="/api/package[@name='xamarin.test']/interface[@name='NotificationCompatBase.Action.Factory']"
[global::Java.Interop.JniTypeSignature ("xamarin/test/NotificationCompatBase$Action$Factory", GenerateJavaPeer=false)]
[global::Java.Interop.JniTypeSignature ("xamarin/test/NotificationCompatBase$Action$Factory", GenerateJavaPeer=false, InvokerType=typeof (Xamarin.Test.NotificationCompatBase.Action.IFactoryInvoker))]
public partial interface IFactory : IJavaPeerable {
// Metadata.xml XPath method reference: path="/api/package[@name='xamarin.test']/interface[@name='NotificationCompatBase.Action.Factory']/method[@name='build' and count(parameter)=1 and parameter[1][@type='int']]"
[global::Java.Interop.JniMethodSignature ("build", "(I)Lxamarin/test/NotificationCompatBase$Action;")]
Expand Down Expand Up @@ -88,7 +88,7 @@ public ActionInvoker (ref JniObjectReference reference, JniObjectReferenceOption
}

// Metadata.xml XPath class reference: path="/api/package[@name='xamarin.test']/class[@name='NotificationCompatBase.InstanceInner']"
[global::Java.Interop.JniTypeSignature ("xamarin/test/NotificationCompatBase$InstanceInner", GenerateJavaPeer=false)]
[global::Java.Interop.JniTypeSignature ("xamarin/test/NotificationCompatBase$InstanceInner", GenerateJavaPeer=false, InvokerType=typeof (InstanceInnerInvoker))]
public abstract partial class InstanceInner : global::Java.Lang.Object {
static readonly JniPeerMembers _members = new JniPeerMembers ("xamarin/test/NotificationCompatBase$InstanceInner", typeof (InstanceInner));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
namespace Xamarin.Test {

// Metadata.xml XPath class reference: path="/api/package[@name='xamarin.test']/class[@name='SomeObject']"
[global::Java.Interop.JniTypeSignature ("xamarin/test/SomeObject", GenerateJavaPeer=false)]
[global::Java.Interop.JniTypeSignature ("xamarin/test/SomeObject", GenerateJavaPeer=false, InvokerType=typeof (SomeObjectInvoker))]
public abstract partial class SomeObject : global::Java.Lang.Object {
static readonly JniPeerMembers _members = new JniPeerMembers ("xamarin/test/SomeObject", typeof (SomeObject));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Java.Util {

// Metadata.xml XPath interface reference: path="/api/package[@name='java.util']/interface[@name='List']"
[global::Java.Interop.JniTypeSignature ("java/util/List", GenerateJavaPeer=false)]
[global::Java.Interop.JniTypeSignature ("java/util/List", GenerateJavaPeer=false, InvokerType=typeof (Java.Util.IListInvoker))]
[global::Java.Interop.JavaTypeParameters (new string [] {"E"})]
public partial interface IList : IJavaPeerable {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
namespace Java.IO {

// Metadata.xml XPath class reference: path="/api/package[@name='java.io']/class[@name='IOException']"
[global::Java.Interop.JniTypeSignature ("java/io/IOException", GenerateJavaPeer=false)]
[global::Java.Interop.JniTypeSignature ("java/io/IOException", GenerateJavaPeer=false, InvokerType=typeof (IOExceptionInvoker))]
public abstract partial class IOException : global::Java.Lang.Throwable {
static readonly JniPeerMembers _members = new JniPeerMembers ("java/io/IOException", typeof (IOException));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
namespace Java.IO {

// Metadata.xml XPath class reference: path="/api/package[@name='java.io']/class[@name='InputStream']"
[global::Java.Interop.JniTypeSignature ("java/io/InputStream", GenerateJavaPeer=false)]
[global::Java.Interop.JniTypeSignature ("java/io/InputStream", GenerateJavaPeer=false, InvokerType=typeof (InputStreamInvoker))]
public abstract partial class InputStream : global::Java.Lang.Object {
static readonly JniPeerMembers _members = new JniPeerMembers ("java/io/InputStream", typeof (InputStream));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
namespace Java.IO {

// Metadata.xml XPath class reference: path="/api/package[@name='java.io']/class[@name='OutputStream']"
[global::Java.Interop.JniTypeSignature ("java/io/OutputStream", GenerateJavaPeer=false)]
[global::Java.Interop.JniTypeSignature ("java/io/OutputStream", GenerateJavaPeer=false, InvokerType=typeof (OutputStreamInvoker))]
public abstract partial class OutputStream : global::Java.Lang.Object {
static readonly JniPeerMembers _members = new JniPeerMembers ("java/io/OutputStream", typeof (OutputStream));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
using Java.Interop;

// Metadata.xml XPath class reference: path="/api/package[@name='']/class[@name='ClassWithoutNamespace']"
[global::Java.Interop.JniTypeSignature ("ClassWithoutNamespace", GenerateJavaPeer=false)]
[global::Java.Interop.JniTypeSignature ("ClassWithoutNamespace", GenerateJavaPeer=false, InvokerType=typeof (ClassWithoutNamespaceInvoker))]
public abstract partial class ClassWithoutNamespace : global::Java.Lang.Object, IInterfaceWithoutNamespace {
static readonly JniPeerMembers _members = new JniPeerMembers ("ClassWithoutNamespace", typeof (ClassWithoutNamespace));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using Java.Interop;

// Metadata.xml XPath interface reference: path="/api/package[@name='']/interface[@name='InterfaceWithoutNamespace']"
[global::Java.Interop.JniTypeSignature ("InterfaceWithoutNamespace", GenerateJavaPeer=false)]
[global::Java.Interop.JniTypeSignature ("InterfaceWithoutNamespace", GenerateJavaPeer=false, InvokerType=typeof (IInterfaceWithoutNamespaceInvoker))]
public partial interface IInterfaceWithoutNamespace : IJavaPeerable {
// Metadata.xml XPath method reference: path="/api/package[@name='']/interface[@name='InterfaceWithoutNamespace']/method[@name='Foo' and count(parameter)=0]"
[global::Java.Interop.JniMethodSignature ("Foo", "()V")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Java.Util {

// Metadata.xml XPath interface reference: path="/api/package[@name='java.util']/interface[@name='Collection']"
[global::Java.Interop.JniTypeSignature ("java/util/Collection", GenerateJavaPeer=false)]
[global::Java.Interop.JniTypeSignature ("java/util/Collection", GenerateJavaPeer=false, InvokerType=typeof (Java.Util.ICollectionInvoker))]
[global::Java.Interop.JavaTypeParameters (new string [] {"E"})]
public partial interface ICollection : IJavaPeerable {
// Metadata.xml XPath method reference: path="/api/package[@name='java.util']/interface[@name='Collection']/method[@name='add' and count(parameter)=1 and parameter[1][@type='E']]"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Java.Util {

// Metadata.xml XPath interface reference: path="/api/package[@name='java.util']/interface[@name='Deque']"
[global::Java.Interop.JniTypeSignature ("java/util/Deque", GenerateJavaPeer=false)]
[global::Java.Interop.JniTypeSignature ("java/util/Deque", GenerateJavaPeer=false, InvokerType=typeof (Java.Util.IDequeInvoker))]
[global::Java.Interop.JavaTypeParameters (new string [] {"E"})]
public partial interface IDeque : global::Java.Util.IQueue {
// Metadata.xml XPath method reference: path="/api/package[@name='java.util']/interface[@name='Deque']/method[@name='add' and count(parameter)=1 and parameter[1][@type='E']]"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Java.Util {

// Metadata.xml XPath interface reference: path="/api/package[@name='java.util']/interface[@name='Queue']"
[global::Java.Interop.JniTypeSignature ("java/util/Queue", GenerateJavaPeer=false)]
[global::Java.Interop.JniTypeSignature ("java/util/Queue", GenerateJavaPeer=false, InvokerType=typeof (Java.Util.IQueueInvoker))]
[global::Java.Interop.JavaTypeParameters (new string [] {"E"})]
public partial interface IQueue : global::Java.Util.ICollection {
// Metadata.xml XPath method reference: path="/api/package[@name='java.util']/interface[@name='Queue']/method[@name='add' and count(parameter)=1 and parameter[1][@type='E']]"
Expand Down
Loading