Repository navigation
Support C# generics in base types #11928
Copy link
Copy link
Closed
Labels
Area: BindingsIssues in Java Library Binding projects.Issues in Java Library Binding projects.java-interopIssues migrated from dotnet/java-interop / relates to the Java.Interop subtreeIssues migrated from dotnet/java-interop / relates to the Java.Interop subtreeneeds-triageIssues that need to be assigned.Issues that need to be assigned.possibly-staleIssues that are potentially no longer relevant.Issues that are potentially no longer relevant.
Description
Consider the BouncyCastle-provided bcprov-ext-jdk15on-161.jar. This Java library contains a type equivalent to:
/* partial */ interface X509AttributeCertificate extends java.security.cert.X509Extension {
}Which looks fine enough, except that it implements the IX509Extension interface, which has two properties which are generic types:
partial interface IX509Extension {
ICollection<string> CriticalExtensionOIDs {get;}
ICollection<string> NonCriticalExtensionOIDs {get;}
}Unfortunately, generator's support for C# generic methods results in the resulting binding...not being valid C# code:
internal partial class internal class IX509AttributeCertificateInvoker : global::Java.Lang.Object, IX509AttributeCertificate {
IntPtr id_getCriticalExtensionOIDs;
public unsafe global::System.Collections.Generic.ICollection`1<global::System.String> CriticalExtensionOIDs {
get {
if (id_getCriticalExtensionOIDs == IntPtr.Zero)
id_getCriticalExtensionOIDs = JNIEnv.GetMethodID (class_ref, "getCriticalExtensionOIDs", "()Ljava/util/Set;");
return global::Android.Runtime.JavaSet.FromJniHandle (JNIEnv.CallObjectMethod (((global::Java.Lang.Object) this).Handle, id_getCriticalExtensionOIDs), JniHandleOwnership.TransferLocalRef);
}
}
}The string global::System.Collections.Generic.ICollection`1<global::System.String> is not a valid C# type -- the ICollection`1<global::System.String> needs to be ICollection<global::System.String> -- which prevents the binding from compiling. (Along with a host of other issues, all of which should be addressed as well.)
generator needs to be fixed so that this can be properly supported.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
Area: BindingsIssues in Java Library Binding projects.Issues in Java Library Binding projects.java-interopIssues migrated from dotnet/java-interop / relates to the Java.Interop subtreeIssues migrated from dotnet/java-interop / relates to the Java.Interop subtreeneeds-triageIssues that need to be assigned.Issues that need to be assigned.possibly-staleIssues that are potentially no longer relevant.Issues that are potentially no longer relevant.
Activity
jpobst commentedon Jul 16, 2019
I tried naively removing the arity from the return type, which at least generates valid C# code, but it still doesn't compile due to:
ToLocalJniHandleexpects anICollectionwhile CriticalExtensionOIDs is anICollection<string>.A similar error occurs here:
because
JavaSet.FromJniHandle (...)returns anICollectionand we need the property to return anICollection<string>.I'm not sure if that means my change is incorrect, or if that is an additional separate issue that needs to be addressed.
jonpryor commentedon Jul 17, 2019
This should use
JavaSet<string>.ToLocalJniHandle (__this.CriticalExtensionOIDs).See also: https://github.com/xamarin/xamarin-android/blob/a3267e34d35a457f11ec1bb4565c350002f8c332/src/Mono.Android/Android.Runtime/JavaSet.cs#L173-L286
jpobst commentedon Jul 17, 2019
Is this something we would expect
generatorto figure out, and if so, how?Or is this something where we would expect
metadatato be written to change the base class fromJavaSettoJavaSet<T>?[generator] Strip arity from Cecil imported types. (#450)
jonpryor commentedon Jul 19, 2019
Yes.
Good question. :-)
Have a more concrete example in mind? There are only ("only") 25 instances of
JavaSet.ToLocalJniHandlein API-28:None of the existing declarations seem quite that useful for this discussion, as they all deal with non-generic types, so more "demo code" might be helpful.
That said, within the context of the
CriticalExtensionOIDsproperty declaration,generatorcan "know" that the return type isICollection<T>-- it has to, otherwise it wouldn't have emitted that in the first place, right? -- so it seems reasonable for that "generic-ness" information to be obtainable, so thatgeneratorcould in turn emitJavaSet<T>.ToLocalJniHandle(...).However, this might also be interpreted as a limitation in our current binding infrastructure. Consider the
IX509Extensiondeclaration we currently emit:Reflection-wise, the only way anything can "know" that
getCriticalExtensionOIDs()returns aSet<string>is by "reading between the lines" between the specified JNI signature (()Ljava/util/Set;) and the managed type (ICollection<string>).We may want to consider adding additional attributes to remove the need for this inference, e.g. by using a
JniGenericTypeArgumentscustom attribute, a'la:generatorcould then put[Register]+[JniGenericTypeArguments]"together" to deduce that the Java-side return type isjava/util/Set<java/lang/String>, i.e.java.util.Set<java.lang.String>i.e.Set<String>, and carry on without needing to "interrogate" and parse the managed return types.[generator] Ensure studly-case doesn't produce invalid C# field name (#…
Bump to xamarin/Java.Interop/master@be581591 (#3404)
mrrozenbergs commentedon Aug 27, 2019
Is it possible to fix this with metadata.xml?
[generator] Add string cast to prevent CS1503 (#970)
dotnet-policy-service commentedon Jul 1, 2026
We suspect this issue is stale and no longer relevant. It will be closed if no further activity occurs within 14 more days. Any new comment (by anyone, not necessarily the author) will undo this process.
dotnet-policy-service commentedon Jul 15, 2026
This issue will now be closed since it had been marked "possibly-stale" but received no further activity in the past 14 days. It is still possible to reopen or comment on the issue, but please note that the issue will be locked if it remains inactive for another 30 days.