Uh oh!
There was an error while loading. Please reload this page.
[generator] Fix xamarin-android/src/Mono.Android build - #972
Conversation
Context: dotnet/java-interop#972 Does It Build™?
| } else { | ||
| writer.WriteLine ($"{(invokeType != "Object" ? arg : "new JniObjectReference (" + arg + ")")});"); | ||
| } | ||
| writer.WriteLine (); |
jpobst
left a comment
There was a problem hiding this comment.
With a forthcoming unit test and a successful test merge to XA (dotnet/android#6939), this should be fine.
d9a087b to
5cf0473CompareContext: dotnet/java-interop#972 Does It Build™?
| public string GetCharSequenceArrayToStringArrayMethodName () | ||
| { | ||
| return CodeGenerationTarget == CodeGenerationTarget.JavaInterop1 | ||
| ? "ICharSequenceExtensions.ToStringArray" |
There was a problem hiding this comment.
Is ICharSequenceExtensions.ToStringArray used? It doesn't show up in the unit test output, whereas CharSequence.ArrayToStringArray does show up.
There was a problem hiding this comment.
Is
ICharSequenceExtensions.ToStringArrayused?
No. Not only is it not used, the entire "context" is "wrong"; compare the XAJavaInterop1-NRT binding of CharSequence[] Echo(CharSequence[]):
[Register("Echo","([Ljava/lang/CharSequence;)[Ljava/lang/CharSequence;","")]publicstaticunsafeJava.Lang.ICharSequence[]?EchoFormatted(Java.Lang.ICharSequence[]?messages)=> …
public staticstring[]? Echo (string[]? messages){varjlca_messages= CharSequence.ArrayFromStringArray (messages);Java.Lang.ICharSequence[]?__result=EchoFormatted(jlca_messages);var __rsval =CharSequence.ArrayToStringArray(__result);if(jlca_messages!=null) foreach (var s injlca_messages)s?.Dispose();return __rsval;}(Aside: notice that XAJavaInterop1 uses both CharSequence.ArrayFromStringArray() and CharSequence.ArrayToStringArray().)
Compare to the JavaInterop1 binding of CharSequence[] Echo(CharSequence[]):
publicstaticunsafeJava.Interop.JavaObjectArray<Java.Lang.ICharSequence>?Echo(Java.Lang.ICharSequence[]?messages)=> …
public staticJava.Interop.JavaObjectArray<string>?Echo(string[]?messages){varjlca_messages= ICharSequenceExtensions.ToCharSequenceArray (messages);Java.Interop.JavaObjectArray<Java.Lang.ICharSequence>?__result=Echo(jlca_messages);var __rsval =__result;if(jlca_messages!=null) foreach (var s injlca_messages)s?.Dispose();return __rsval;}It's all manner of "wrong":
XAJavaInterop1 has
EchoFormatted()andEcho(); JavaInterop1 hasEcho()overloads. Presumably the first method should beEchoFormatted()?As per a65d6fb, the
messagesargument should be aJavaObjectArray<ICharSequence>, notICharSequence[]! (See alsosrc/Java.Base-ref.csfrom 968e0f5, for which the only occurrence of[]is as part of aparamsarray.)Which implies that I'm doing something "wrong" with my
Parametercreation?Shouldn't the return type of
Echo()bestring[]?
I think the fundamental problem here is that my attempted unit test "setup" is wrong.
There was a problem hiding this comment.
"For comparison", if I update tests/generator-Tests/expected/StaticMethods/StaticMethod.xml:
diff --git a/tests/generator-Tests/expected/StaticMethods/StaticMethod.xml b/tests/generator-Tests/expected/StaticMethods/StaticMethod.xml
index 913f5e69..294ba933 100644
--- a/tests/generator-Tests/expected/StaticMethods/StaticMethod.xml+++ b/tests/generator-Tests/expected/StaticMethods/StaticMethod.xml@@ -13,6 +13,9 @@
</method>
<method abstract="false" deprecated="Deprecated please use methodAsString" final="false" name="Obsoletemethod" native="false" return="java.lang.String" static="true" synchronized="false" visibility="public">
</method>
+ <method abstract="false" deprecated="not deprecated" final="false" name="echo" native="false" return="java.lang.CharSequence[]" static="true" synchronized="false" visibility="public">+ <parameter name="m" type="java.lang.CharSequence[]" />+ </method>
</class>
</package>
</api>and then run:
mkdir _x
dotnet bin/Debug-net6.0/generator.dll --codegen-target=JavaInterop1 -o _x tests/generator-Tests/expected/StaticMethods/StaticMethod.xml
then _x/Xamarin.Test.SomeObject.cs contains:
// Metadata.xml XPath method reference: path="/api/package[@name='xamarin.test']/class[@name='SomeObject']/method[@name='echo' and count(parameter)=1 and parameter[1][@type='java.lang.CharSequence[]']]"publicstaticunsafeJava.Interop.JavaObjectArray<Java.Lang.ICharSequence>Echo(Java.Interop.JavaObjectArray<Java.Lang.ICharSequence>m){conststring__id="echo.([Ljava/lang/CharSequence;)[Ljava/lang/CharSequence;";varnative_m=global::Java.Interop.JniEnvironment.Arrays.CreateMarshalObjectArray<global::Java.Lang.ICharSequence>(m);try{JniArgumentValue*__args=stackallocJniArgumentValue[1];__args[0]=newJniArgumentValue(native_m);var__rm=_members.StaticMethods.InvokeObjectMethod(__id,__args);returnglobal::Java.Interop.JniEnvironment.Runtime.ValueManager.GetValue<global::Java.Interop.JavaObjectArray<Java.Lang.ICharSequence>>(ref__rm,JniObjectReferenceOptions.CopyAndDispose);}finally{if(native_m!=null){native_m.DisposeUnlessReferenced();}global::System.GC.KeepAlive(m);}}publicstaticJava.Interop.JavaObjectArray<string>Echo(Java.Interop.JavaObjectArray<string>m){Java.Interop.JavaObjectArray<Java.Lang.ICharSequence>__result=Echo(m);var__rsval=__result;return__rsval;}which is closer to what I expected, in that the java.lang.CharSequence[] parameter was bound as JavaObjectArray<ICharSequence> (and then the method body fumbles things by using CreateMarshalObjectArray(), for no reason?!).
However, it's still not named EchoFormatted().
There was a problem hiding this comment.
Summarizing my previoustwo comments:
I think that the WriteMethodWithCharSequenceArrays() unit test is "wrong". It's not "close enough" to what the "full" XML pipeline does, and thus the output is kinda non-sensical, particularly with JavaInterop1 output.
I don't know how to fix it, offhand.
I should probably update StaticMethod.xml for this use case, if only to have a "full integration" pass. (Which still won't use ICharSequenceExtensions.ToStringArray(), but at least the output will be saner. Not sane yet, but saner.)
There was a problem hiding this comment.
I've removed GetCharSequenceArrayToStringArrayMethodName() from the most recent update, and update WriteMethodWithCharSequenceArrays() to use ParseApiDefinition().
Context: a65d6fb Context: dotnet/android#6939dotnet/android#6939 attempted to bump to 05eddd9, which promptly broke the build of src/Mono.Android, e.g. `src/Mono.Android/obj/Debug/net6.0/android-32/mcw/Android.Widget.GridLayout.cs`: /* */ partial class GridLayout { /* */ partial class partial class LayoutParams { /* */ [Register ("rowSpec")] /* */ public Android.Widget.GridLayout.Spec? RowSpec { /* */ get { /* */ const string __id = "rowSpec.Landroid/widget/GridLayout$Spec;"; /* */ var __v = _members.InstanceFields.GetObjectValue (__id, this); /* */ return global::Java.Lang.Object.GetObject<Android.Widget.GridLayout.Spec> (__v.Handle, JniHandleOwnership.TransferLocalRef); /* */ } /* */ set { /* */ const string __id = "rowSpec.Landroid/widget/GridLayout$Spec;"; /* */ IntPtr native_value = global::Android.Runtime.JNIEnv.ToLocalJniHandle (value); /* */ try { /* L 239 */ _members.InstanceFields.SetValue (__id, this, new JniObjectReference (value)); /* */ } finally { /* L 242 */ global::Android.Runtime.JNIEnv.DeleteLocalRef (value); /* */ } /* */ } /* */ } /* */ } /* */ } due to compilation errors: src/Mono.Android/obj/Debug/net6.0/android-32/mcw/Android.Widget.GridLayout.cs(239,77): error CS1503: Argument 1: cannot convert from 'Android.Widget.GridLayout.Spec' to 'System.IntPtr' src/Mono.Android/obj/Debug/net6.0/android-32/mcw/Android.Widget.GridLayout.cs(242,54): error CS1503: Argument 1: cannot convert from 'Android.Widget.GridLayout.Spec' to 'System.IntPtr' This was caused by `BoundFieldAsProperty.cs` not appropriately setting `arg` to `native_arg`, so that the correct variable would be cleaned up in the `finally` block. There was another set of errors: src/Mono.Android/obj/Release/net6.0/android-32/mcw/Android.Widget.ArrayAdapter.cs(525,53): error CS1503: Argument 1: cannot convert from 'Java.Lang.ICharSequence[]' to 'string[]?' which was also caused by a65d6fb mis-refactoring `SourceWriterExtensions.cs`, and overlooking the entire existence of the `CharSequence.ArrayToStringArray()` method (oops). Update `generator` so that xamarin-android once again builds, and add unit tests to hit these particular code paths.
5cf0473 to
d7d317dCompare
[generator] Fix xamarin-android/src/Mono.Android build
Context: a65d6fb
Context: dotnet/android#6939
dotnet/android#6939 attempted to bump to 05eddd9, which
promptly broke the build of src/Mono.Android, e.g.
src/Mono.Android/obj/Debug/net6.0/android-32/mcw/Android.Widget.GridLayout.cs:due to compilation errors:
This was caused by
BoundFieldAsProperty.csnot appropriatelysetting
argtonative_arg, so that the correct variable would becleaned up in the
finallyblock.There was another set of errors:
which was also caused by a65d6fb mis-refactoring
SourceWriterExtensions.cs, and overlooking the entire existence ofthe
CharSequence.ArrayToStringArray()method (oops).Update
generatorso that xamarin-android once again builds, and addunit tests to hit these particular code paths.