-
Notifications
You must be signed in to change notification settings - Fork 53
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
Expand managedOverride
for none
#981
Comments
Tangentially related is this TODO from a65d6fb:
The solution is to "reabstract" the member: public partial interface IAnnotatedType {
// Contains default interface method
virtual IAnnotatedType? AnnotatedOwnerType => null;
}
public partial interface IAnnotatedArrayType : IAnnotatedType {
// Contains *no* method body; re-abstracted
abstract IAnnotatedType? IAnnotatedType.AnnotatedOwnerType {get;}
} The question is how to "reabstract" <attr path="/api/package[@name='java.lang.reflect']/interface[@name='AnnotatedArrayType']/method[@name='getAnnotatedOwnerType' and count(parameter)=0]"
name="propertyName">IAnnotatedType.AnnotatedOwnerType</attr> This partially works: public partial interface IAnnotatedArrayType : global::Java.Lang.Reflect.IAnnotatedType {
global::Java.Lang.Reflect.IAnnotatedType? IAnnotatedType.AnnotatedOwnerType {
// Metadata.xml XPath method reference: path="/api/package[@name='java.lang.reflect']/interface[@name='AnnotatedArrayType']/method[@name='getAnnotatedOwnerType' and count(parameter)=0]"
[global::Java.Interop.JniMethodSignature ("getAnnotatedOwnerType", "()Ljava/lang/reflect/AnnotatedType;")]
get;
}
} However, it fails to compile:
Thus, a fourth <attr path="/api/package[@name='java.lang.reflect']/interface[@name='AnnotatedArrayType']/method[@name='getAnnotatedOwnerType' and count(parameter)=0]"
name="managedOverride">abstract</attr> Which, in combination with the public partial interface IAnnotatedArrayType : global::Java.Lang.Reflect.IAnnotatedType {
abstract global::Java.Lang.Reflect.IAnnotatedType? IAnnotatedType.AnnotatedOwnerType {
// Metadata.xml XPath method reference: path="/api/package[@name='java.lang.reflect']/interface[@name='AnnotatedArrayType']/method[@name='getAnnotatedOwnerType' and count(parameter)=0]"
[global::Java.Interop.JniMethodSignature ("getAnnotatedOwnerType", "()Ljava/lang/reflect/AnnotatedType;")]
get;
}
} (Another question on our call earlier today was whether or not this would be "enough". These two fixes are "enough" to get the current |
Is this not fixed by setting <attr path="/api/package[@name='java.lang.reflect']/interface[@name='AnnotatedArrayType']/method[@name='getAnnotatedOwnerType' and count(parameter)=0]"
name="abstract">true</attr> |
It's already <interface abstract="true" deprecated="not deprecated" final="false" name="AnnotatedArrayType" static="false" visibility="public" jni-signature="Ljava/lang/reflect/AnnotatedArrayType;">
<implements name="java.lang.reflect.AnnotatedType" name-generic-aware="java.lang.reflect.AnnotatedType" jni-type="Ljava/lang/reflect/AnnotatedType;" />
<method abstract="true" deprecated="not deprecated" final="false" name="getAnnotatedGenericComponentType" jni-signature="()Ljava/lang/reflect/AnnotatedType;" bridge="false" native="false" return="java.lang.reflect.AnnotatedType" jni-return="Ljava/lang/reflect/AnnotatedType;" static="false" synchronized="false" synthetic="false" visibility="public" />
<method abstract="true" deprecated="not deprecated" final="false" name="getAnnotatedOwnerType" jni-signature="()Ljava/lang/reflect/AnnotatedType;" bridge="false" native="false" return="java.lang.reflect.AnnotatedType" jni-return="Ljava/lang/reflect/AnnotatedType;" static="false" synchronized="false" synthetic="false" visibility="public" propertyName="IAnnotatedType.AnnotatedOwnerType" />
</interface> Yet |
I went with |
…1000) Fixes: #981 Context: 5a0e37e Add support for `//class/method[@managedOverride = 'none']` and `//interface/method[@managedOverride = 'reabstract']`. Setting `@managedOverride` to `none` ensures that the member is not marked with `virtual` or `override`. This is useful for `sealed` classes, to avoid a [CS0549 error][0]. Previously, given the Java: // Java public final class MyClass { public void doThing() {/* … */ } } The `class-parse` XML would specify that `MyClass.doThing()` was "virtual" -- `@abstract` is false, `@final` is false: <class name="MyClass …> <method abstract="false" final="false" name="doThing" return="void" … /> </class> This would result in the C# binding: // C# public sealed partial class MyClass { public virtual void DoThing() => … } which would error out with a CS0549: error CS0549: 'MyClass.DoThing()' is a new virtual member in sealed type 'MyClass' This can now be resolved by setting `@managedOverride` to `none`: <attr path="//class[@name='MyClass']/method[@name='doThing']" name="managedOverride">none</attr> which will result in the compilable binding: // C# public sealed partial class MyClass { public void DoThing() => … } Setting `@managedOverride` to `reabstract` is part of support for re-abstracting interface members; see also a65d6fb. Currently in `src/Java.Base`, we have Java: // Java public interface AnnotatedType { default AnnotatedType getAnnotatedOwnerType() {…} } public interface AnnotatedArrayType implements AnnotatedType { AnnotatedType getAnnotatedOwnerType(); // re-abstract interface default method } which results in the C# binding: // C# public partial interface IAnnotatedType { virtual IAnnotatedType? AnnotatedOwnerType { get => … } } public partial interface IAnnotatedArrayType : IAnnotatedType { IAnnotatedType? AnnotatedOwnerType { get; } // CS0108 } which results in a [warning CS0108][1]: warning CS0108: 'IAnnotatedArrayType.AnnotatedOwnerType' hides inherited member 'IAnnotatedType.AnnotatedOwnerType'. Use the new keyword if hiding was intended. Fixing this requires two steps. First, we can now set `//interface/method/@managedOverride` to `reabstract`: <attr path="//interface[@name='AnnotatedArrayType']/method[@name='getAnnotatedOwnerType']" name="managedOverride">reabstract</attr> What we *also* need to do is make the member *explicitly qualified*. This can be "forced" for *properties* by setting `@propertyName`: <attr path="//interface[@name='AnnotatedArrayType']/method[@name='getAnnotatedOwnerType']" name="propertyName">IAnnotatedType.AnnotatedOwnerType</attr> `@managedOverride` and `@propertyName` work together to emit: public partial interface IAnnotatedArrayType : IAnnotatedType { abstract IAnnotatedType? IAnnotatedType.AnnotatedOwnerType {get;} } The problem is that this combination probably breaks Android output, and it can't be used for *method* overrides, e.g. having `java.io.Closeable.close()` re-abstract `java.lang.AutoCloseable.close()`. TODO: complete the "interface reabstract" case, possibly via `//interface/method[@explicitInterface='ManagedInterfaceName']`: <attr path="//interface[@name='AnnotatedArrayType']/method[@name='getAnnotatedOwnerType']" name="explicitInterface">IAnnotatedType</attr> [0]: https://docs.microsoft.com/en-us/dotnet/csharp/misc/cs0549 [1]: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-messages/cs0108
Fixes: dotnet/java-interop#335 Fixes: dotnet/java-interop#954 Fixes: dotnet/java-interop#976 Fixes: dotnet/java-interop#981 Fixes: dotnet/java-interop#992 Changes: dotnet/java-interop@7716ae5...c942ab6 * dotnet/java-interop@c942ab68: [java-source-utils] Build one `$(TargetFramework)` (#1007) * dotnet/java-interop@b7caa788: [Byecode] Hide `internal` Kotlin fields marked with `@JvmField` (#1004) * dotnet/java-interop@22d5687b: [generator] Add `@managedOverride` values `none` and `reabstract`. (#1000) * dotnet/java-interop@7f1d2d7a: [generator] Fix <remove-attr/> metadata (#999) * dotnet/java-interop@265ad762: [Java.Interop.Tools.JavaSource] Fix tag parsing errors (#997) * dotnet/java-interop@99c68a86: [Java.Interop] JniTypeSignature & CultureInfo, empty strings (#1002) * dotnet/java-interop@920ea648: [Java.Interop] optimize JniTypeManager.AssertSimpleReference() (#1001) * dotnet/java-interop@4b4fedd3: [generator] Process Javadoc for nested types (#996) Ever since commit 2197a45, CI builds for the `main` branch have been incredibly flakey: 918613d through 27647d2 all failed to complete the **Mac** stage -- which *must* pass in order for most unit tests to run -- then dbadf13 built, then f149c25 failed. Nine commits in the past week have failed to adequately build. (PR builds, meanwhile, were largely fine.) Most of these failures are from `make all-tests`: _ExtractJavadocsFromJavaSourceJars: /Users/runner/android-toolchain/jdk-11/bin/java -jar /Users/runner/work/1/s/xamarin-android/bin/Release/lib/xamarin.android/xbuild/Xamarin/Android/java-source-utils.jar @/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/tmp1cf0947e.tmp JAVASOURCEUTILS : warning : Invalid or corrupt jarfile /Users/runner/work/1/s/xamarin-android/bin/Release/lib/xamarin.android/xbuild/Xamarin/Android/java-source-utils.jar [/Users/runner/work/1/s/xamarin-android/tests/CodeGen-Binding/Xamarin.Android.McwGen-Tests/Xamarin.Android.McwGen-Tests.csproj] … BINDINGSGENERATOR : warning BG8600: Invalid XML file '/Users/runner/work/1/s/xamarin-android/tests/CodeGen-Binding/Xamarin.Android.McwGen-Tests/obj/Release/javadoc-xamarin-test-sources-F6F5170BF7A8BC71.xml': Could not find file "/Users/runner/work/1/s/xamarin-android/tests/CodeGen-Binding/Xamarin.Android.McwGen-Tests/obj/Release/javadoc-xamarin-test-sources-F6F5170BF7A8BC71.xml". For details, see verbose output. [/Users/runner/work/1/s/xamarin-android/tests/CodeGen-Binding/Xamarin.Android.McwGen-Tests/Xamarin.Android.McwGen-Tests.csproj] System.IO.FileNotFoundException: Could not find file "/Users/runner/work/1/s/xamarin-android/tests/CodeGen-Binding/Xamarin.Android.McwGen-Tests/obj/Release/javadoc-xamarin-test-sources-F6F5170BF7A8BC71.xml" … "/Users/runner/work/1/s/xamarin-android/Xamarin.Android-Tests.sln" (default target) (1:2) -> "/Users/runner/work/1/s/xamarin-android/tests/CodeGen-Binding/Xamarin.Android.JcwGen-Tests/Xamarin.Android.JcwGen-Tests.csproj" (default target) (12:6) -> (CoreCompile target) -> /Users/runner/work/1/s/xamarin-android/tests/CodeGen-Binding/Xamarin.Android.JcwGen-Tests/BindingTests.cs(78,37): error CS1061: 'DataEventArgs' does not contain a definition for 'FromNode' and no accessible extension method 'FromNode' accepting a first argument of type 'DataEventArgs' could be found (are you missing a using directive or an assembly reference?) [/Users/runner/work/1/s/xamarin-android/tests/CodeGen-Binding/Xamarin.Android.JcwGen-Tests/Xamarin.Android.JcwGen-Tests.csproj] /Users/runner/work/1/s/xamarin-android/tests/CodeGen-Binding/Xamarin.Android.JcwGen-Tests/BindingTests.cs(79,40): error CS1061: 'DataEventArgs' does not contain a definition for 'FromChannel' and no accessible extension method 'FromChannel' accepting a first argument of type 'DataEventArgs' could be found (are you missing a using directive or an assembly reference?) [/Users/runner/work/1/s/xamarin-android/tests/CodeGen-Binding/Xamarin.Android.JcwGen-Tests/Xamarin.Android.JcwGen-Tests.csproj] /Users/runner/work/1/s/xamarin-android/tests/CodeGen-Binding/Xamarin.Android.JcwGen-Tests/BindingTests.cs(80,40): error CS1061: 'DataEventArgs' does not contain a definition for 'PayloadType' and no accessible extension method 'PayloadType' accepting a first argument of type 'DataEventArgs' could be found (are you missing a using directive or an assembly reference?) [/Users/runner/work/1/s/xamarin-android/tests/CodeGen-Binding/Xamarin.Android.JcwGen-Tests/Xamarin.Android.JcwGen-Tests.csproj] /Users/runner/work/1/s/xamarin-android/tests/CodeGen-Binding/Xamarin.Android.JcwGen-Tests/BindingTests.cs(81,28): error CS1061: 'DataEventArgs' does not contain a definition for 'Payload' and no accessible extension method 'Payload' accepting a first argument of type 'DataEventArgs' could be found (are you missing a using directive or an assembly reference?) [/Users/runner/work/1/s/xamarin-android/tests/CodeGen-Binding/Xamarin.Android.JcwGen-Tests/Xamarin.Android.JcwGen-Tests.csproj] /Users/runner/work/1/s/xamarin-android/tests/CodeGen-Binding/Xamarin.Android.JcwGen-Tests/BindingTests.cs(82,29): error CS1061: 'DataEventArgs' does not contain a definition for 'Payload' and no accessible extension method 'Payload' accepting a first argument of type 'DataEventArgs' could be found (are you missing a using directive or an assembly reference?) [/Users/runner/work/1/s/xamarin-android/tests/CodeGen-Binding/Xamarin.Android.JcwGen-Tests/Xamarin.Android.JcwGen-Tests.csproj] /Users/runner/work/1/s/xamarin-android/tests/CodeGen-Binding/Xamarin.Android.JcwGen-Tests/BindingTests.cs(84,51): error CS1061: 'DataEventArgs' does not contain a definition for 'Payload' and no accessible extension method 'Payload' accepting a first argument of type 'DataEventArgs' could be found (are you missing a using directive or an assembly reference?) [/Users/runner/work/1/s/xamarin-android/tests/CodeGen-Binding/Xamarin.Android.JcwGen-Tests/Xamarin.Android.JcwGen-Tests.csproj] /Users/runner/work/1/s/xamarin-android/tests/CodeGen-Binding/Xamarin.Android.JcwGen-Tests/BindingTests.cs(85,10): error CS1061: 'DataEventArgs' does not contain a definition for 'Payload' and no accessible extension method 'Payload' accepting a first argument of type 'DataEventArgs' could be found (are you missing a using directive or an assembly reference?) [/Users/runner/work/1/s/xamarin-android/tests/CodeGen-Binding/Xamarin.Android.JcwGen-Tests/Xamarin.Android.JcwGen-Tests.csproj] `java-source-utils.jar` is (apparently) corrupt, so `javadoc-xamarin-test-sources-F6F5170BF7A8BC71.xml` is never created, which means no parameter name information is present, which means the generated `DataEventArgs` type doesn't have the appropriate property names, as the property names come from parameter names, and since we don't have parameter names we instead have property names like `P0`, `P1`, `P2`, etc. Why, then, is `java-source-utils.jar` corrupt? The current guess is that it is being built *concurrently*; from a `msbuild-20220706T175333-leeroy-all.binlog` build log file from one of the offending builds, we see: 17:53:44.526 59:11>Target "_BuildJava: (TargetId:490)" in file "/Users/runner/work/1/s/xamarin-android/external/Java.Interop/tools/java-source-utils/java-source-utils.targets" from project "/Users/runner/work/1/s/xamarin-android/external/Java.Interop/tools/java-source-utils/java-source-utils.csproj" (entry point): 17:53:44.526 59:11>Building target "_BuildJava" completely. Output file "/Users/runner/work/1/s/xamarin-android/bin/Release/lib/packs/Microsoft.Android.Sdk.Darwin/33.0.0/tools/java-source-utils.jar" does not exist. … 17:54:19.564 59:12>Target "DispatchToInnerBuilds: (TargetId:1637)" in file "/Users/runner/work/1/s/xamarin-android/bin/Release/dotnet/sdk/7.0.100-preview.7.22354.2/Microsoft.Common.CrossTargeting.targets" from project "/Users/runner/work/1/s/xamarin-android/external/Java.Interop/tools/java-source-utils/java-source-utils.csproj" (target "Build" depends on it): Task "MSBuild" (TaskId:1099) Task Parameter:BuildInParallel=True (TaskId:1099) Task Parameter:Targets=Build (TaskId:1099) Task Parameter: Projects= java-source-utils.csproj AdditionalProperties=TargetFramework=net7.0 (TaskId:1099) Additional Properties for project "java-source-utils.csproj": (TaskId:1099) TargetFramework=net7.0 (TaskId:1099) … 17:54:19.592 59:12>Target "_BuildJava: (TargetId:1640)" in file "/Users/runner/work/1/s/xamarin-android/external/Java.Interop/tools/java-source-utils/java-source-utils.targets" from project "/Users/runner/work/1/s/xamarin-android/external/Java.Interop/tools/java-source-utils/java-source-utils.csproj" (entry point): Building target "_BuildJava" completely. Output file "/Users/runner/work/1/s/xamarin-android/external/Java.Interop/../../bin/Release/lib/xamarin.android/xbuild/Xamarin/Android/java-source-utils.jar" does not exist. … 17:54:41.034 59:11>Done building target "_BuildJava" in project "java-source-utils.csproj".: (TargetId:490) What appears to be happening -- and there is lots of conjecture here, as the build log is enormous and it's difficult to piece everything together -- is that `java-source-utils.csproj` is built *twice*: Once via `Xamarin.Android.sln`, and once via `apksigner.csproj`, as it appears that setting `%(PackageReference.AdditionalProperties)` triggers a *nested build*; note the `DispatchToInnerBuilds` target which invokes the `<MSBuild/>` Task with the specified `AdditionalProperties`. However, that's not the only potential source of concurrent builds; `java-source-utils.csproj` used `$(TargetFrameworks)` (plural), which can *also* result in concurrent builds between the "outer" and "inner" builds used as part of `$(TargetFrameworks)`. Fix this problem by bumping to dotnet/java-interop@c942ab68, which updates `java-source-utils.csproj` to use the singular `$(TargetFramework)` property -- avoiding "outer" and "inner" build problems -- and "for good measure" update `apksigner.csproj` to remove `%(ProjectReference.AdditionalProperties)` on `java-source-utils.csproj`. This should ensure that `java-source-utils.csproj` is only built *once*, which in turn should ensure that `java-source-utils.jar` isn't corrupted, and our CI builds become more reliable
In #701, we created the
managedOverride
metadata which allows a user to override which ofvirtual
/override
keywords are placed on a method:However, sometimes the desired fix is "none of the above". For example, there may not be a method to
override
, however the class issealed
sovirtual
is not a valid option either. Both keywords must be omitted.We should add support for a third
none
option:The text was updated successfully, but these errors were encountered: