-
Notifications
You must be signed in to change notification settings - Fork 54
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.Base, generator] Bind all of package java.lang #966
Conversation
9f7a4be
to
b37ae0c
Compare
So… strings: how should we bind them? There's no backward compatibility requirement with Consider class String {
public int compareTo(String anotherString);
} In Xamarin.Android, this is bound as: partial class String {
public int CompareTo (string anotherString);
} In this PR, it is bound as: partial class String {
public int CompareTo (Java.Lang.String? anotherString);
} This PR also adds an implicit conversion from var s = new Java.Lang.String("value");
s.CompareTo("another value"); but this implicit conversion means extra GC Pros of binding
|
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
A downside of binding as Additionally, for return values, you are not going to see methods available on Calling, for example, |
@jpobst reminded me that I'm not personally very good with how things look like with IDE-colored glasses. Those are two separate scenarios -- parameters vs. return types -- but the underlying issue is the same: how the IDE presents options is not necessarily ideal.
|
After additional thought, that wouldn't be good, as it wouldn't be bidirectional. Consider: var list = new Java.Util.ArrayList ();
list.Add (new List<int> { 1, 2, 3, 4}); This can be "made to work" by updating var items = (List<int>) list.Get (0); // boom If var items = (List<int>) (object) list.Get (0); // *maybe* works as expected? Thus, updating The original idea of "unifying" partial class ArrayList {
public object? Get (int index)
{
const string __id = "get.(I)Ljava/lang/Object;";
try {
JniArgumentValue* __args = stackalloc JniArgumentValue [1];
__args [0] = new JniArgumentValue (index);
var __rm = _members.InstanceMethods.InvokeVirtualObjectMethod (__id, this, __args);
return global::Java.Interop.JniEnvironment.Runtime.ValueManager.GetValue<object> (ref __rm, JniObjectReferenceOptions.CopyAndDispose);;
} finally {
}
}
} …because Which taken together suggests two things to me:
|
I think one of the biggest sticking points for users is the need to inherit JLO to implement a bound Java interface, a la: public class MyListener : Java.Lang.Object, IOnChangeListener { ... } Would we be able to get around this requirement? |
Yes and no. See also: #17 (which is closed for some reason?!) The "problem" is that all interfaces now implement That said, it should be possible to (eventually) make "Unifying" |
Context: bc5bcf4 Bind all classes and interfaces in the `java.lang` package. Alter Java array binding, so that instead of `IList<T>`, we get "direct" Java arrays, e.g. namespace Java.Lang { partial class Character { // Previous/Xamarin.Android-like public static int CodePointAt (IList<char>? a, int index); // New/Desktop public static int CodePointAt (JavaCharArray? a, int index); } } Rationale: it *allows* for more efficient JVM :: .NET array copying, by making copies explicit (to the dev), not implicit. We can add an implicit conversion from e.g. `IEnumerable<char>` to `JavaCharArray` in the future, if deemed useful. This also impacts method return types, properties, and fields. Bind the `java.lang.module` package in the namespace `Java.Lang.Modules`. This is to avoid a type/namespace conflict with `java.lang.Module`, bound as `Java.Lang.Module`. Continue updating `generator` to remove "Android-isms". Update `Java.Base.csproj` to ignore [warning CS0108][0]: Java.Lang.Reflect.IAnnotatedArrayType.cs(15,45): warning CS0108: 'IAnnotatedArrayType.AnnotatedOwnerType' hides inherited member 'IAnnotatedType.AnnotatedOwnerType'. Use the new keyword if hiding was intended. The problem here is that we have: public partial interface IAnnotatedType { // Contains default interface method virtual unsafe IAnnotatedType? AnnotatedOwnerType => …; } public partial interface IAnnotatedArrayType : IAnnotatedType { // Contains *no* method body; re-abstracted IAnnotatedType? AnnotatedOwnerType {get;} } TODO: figure out how to properly fix this. `managedOverride` metadata (5a0e37e) doesn't seem useful to "re-abstract" a default interface member. Update `Java.Base.targets` to use `generator --global`. This is so that `java.lang.System` can be bound as `Java.Lang.System` without causing various C# compilation errors due to type lookup. (Compare to Xamarin.Android's `Java.Lang.JavaSystem`, which got a `Java*` prefix to avoid these compilation errors.) Update `JavaInteropCodeGeneratorTests.CreateOptions()` so that C# features such as default interface methods and nested interface types are enabled within the unit tests. TODO: * When `generator --codegen-target=JavaInterop1` is used, all the language features should also be enabled by default. * Certain Java Annotation-related types aren't bound in JavaInterop1, vs. XAJavaInterop1. Revisit this. * "Revisit" use of `JNIEnv.ToLocalJniHandle()` in Xamarin.Android bindings, and it's outright removal in JavaInterop1 bindings. @jonpryor *thinks* the `JNIENv.ToLocalJniHandle(v)` was introduced "in case" `v` would be collected by the GC "during" a JNI call. Use of `GC.KeepAlive()` (1f21f38, da73d6a), would be a better solution, but also requires auditing `generator` output. * Bind the rest of `java.base.jmod` (bc5bcf4). [0]: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-messages/cs0108
b37ae0c
to
9b7edbc
Compare
Context: bc5bcf4
Bind all classes and interfaces in the
java.lang
package.Alter Java array binding, so that instead of
IList<T>
, we get"direct" Java arrays, e.g.
Rationale: it allows for more efficient JVM :: .NET array copying,
by making copies explicit (to the dev), not implicit. We can
add an implicit conversion from e.g.
IEnumerable<char>
toJavaCharArray
in the future, if deemed useful.This also impacts method return types, properties, and fields.
Bind the
java.lang.module
package in the namespaceJava.Lang.Modules
. This is to avoid a type/namespace conflictwith
java.lang.Module
, bound asJava.Lang.Module
.Continue updating
generator
to remove "Android-isms".Update
Java.Base.csproj
to ignore warning CS0108:The problem here is that we have:
TODO: figure out how to properly fix this.
managedOverride
metadata (5a0e37e) doesn't seem useful to "re-abstract" a default
interface member.
Update
Java.Base.targets
to usegenerator --global
. This is sothat
java.lang.System
can be bound asJava.Lang.System
withoutcausing various C# compilation errors due to type lookup.
(Compare to Xamarin.Android's
Java.Lang.JavaSystem
, which got aJava*
prefix to avoid these compilation errors.)Update
JavaInteropCodeGeneratorTests.CreateOptions()
so that C#features such as default interface methods and nested interface types
are enabled within the unit tests.
TODO:
When
generator --codegen-target=JavaInterop1
is used, all thelanguage features should also be enabled by default.
Certain Java Annotation-related types aren't bound in
JavaInterop1, vs. XAJavaInterop1. Revisit this.
"Revisit" use of
JNIEnv.ToLocalJniHandle()
in Xamarin.Androidbindings, and it's outright removal in JavaInterop1 bindings.
@jonpryor thinks the
JNIENv.ToLocalJniHandle(v)
was introduced"in case"
v
would be collected by the GC "during" a JNI call.Use of
GC.KeepAlive()
(1f21f38, da73d6a), would be a bettersolution, but also requires auditing
generator
output.Bind the rest of
java.base.jmod
(bc5bcf4).