Uh oh!
There was an error while loading. Please reload this page.
[Java.Base, generator] Bind all of package java.lang - #966
Conversation
9f7a4be to
b37ae0cComparejonpryor
commented
Mar 24, 2022
So… strings: how should we bind them? There's no backward compatibility requirement with Consider classString {
publicintcompareTo(StringanotherString);
}In Xamarin.Android, this is bound as: partialclassString{publicintCompareTo(stringanotherString);}In this PR, it is bound as: partialclassString{publicintCompareTo(Java.Lang.String?anotherString);}This PR also adds an implicit conversion from vars=newJava.Lang.String("value");s.CompareTo("another value");but this implicit conversion means extra GC Pros of binding |
jonpryor
commented
Mar 24, 2022
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
jpobst
commented
Mar 24, 2022
A downside of binding as Additionally, for return values, you are not going to see methods available on Calling, for example, |
jonpryor
commented
Mar 24, 2022
@jpobstreminded 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.
|
jonpryor
commented
Mar 24, 2022
After additional thought, that wouldn't be good, as it wouldn't be bidirectional. Consider: varlist=newJava.Util.ArrayList();list.Add(newList<int>{1,2,3,4});This can be "made to work" by updating varitems=(List<int>)list.Get(0);// boomIf varitems=(List<int>)(object)list.Get(0);// *maybe* works as expected?Thus, updating The original idea of "unifying" partialclassArrayList{publicobject?Get(intindex){conststring__id="get.(I)Ljava/lang/Object;";try{JniArgumentValue*__args=stackallocJniArgumentValue[1];__args[0]=newJniArgumentValue(index);var__rm=_members.InstanceMethods.InvokeVirtualObjectMethod(__id,this,__args);returnglobal::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: publicclassMyListener:Java.Lang.Object,IOnChangeListener{ ...}Would we be able to get around this requirement? |
jonpryor
commented
Mar 24, 2022
Yes and no. See also: https://github.com/xamarin/java.interop/issues/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
9b7edbcCompare

Context: bc5bcf4
Bind all classes and interfaces in the
java.langpackage.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>toJavaCharArrayin the future, if deemed useful.This also impacts method return types, properties, and fields.
Bind the
java.lang.modulepackage in the namespaceJava.Lang.Modules. This is to avoid a type/namespace conflictwith
java.lang.Module, bound asJava.Lang.Module.Continue updating
generatorto remove "Android-isms".Update
Java.Base.csprojto ignore warning CS0108:The problem here is that we have:
TODO: figure out how to properly fix this.
managedOverridemetadata (5a0e37e) doesn't seem useful to "re-abstract" a default
interface member.
Update
Java.Base.targetsto usegenerator --global. This is sothat
java.lang.Systemcan be bound asJava.Lang.Systemwithoutcausing 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=JavaInterop1is 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.
@jonpryorthinks the
JNIENv.ToLocalJniHandle(v)was introduced"in case"
vwould be collected by the GC "during" a JNI call.Use of
GC.KeepAlive()(1f21f38, da73d6a), would be a bettersolution, but also requires auditing
generatoroutput.Bind the rest of
java.base.jmod(bc5bcf4).