Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[generator] Don't generate unexpected NRT types like
void?
(#856)
Context: #850 (comment) When a user binds a Java library that contains a Java interface which implements another Java interface: // Java; android.jar public interface /* android.view. */ Menu {…} // Java; androidx.core.core.jar public interface /* androidx.core.internal.view. */ SupportMenu implements android.view.Menu {…} then when we create the binding for the "leaf" interface: // C# binding for androidx.core.core namespace AndroidX.Core.Internal.View { public interface ISupportMenu : Android.Views.IMenu {…} internal partial class ISupportMenuInvoker : Java.Lang.Object, ISupportMenu { // … } } The generated `*Invoker` type implements all methods for all implemented interfaces, e.g. methods from both `IMenu` and `ISupportMenu`. When: 1. The base interface (e.g. `IMenu`) comes from a referenced assembly, *and* 2. `$(Nullable)`=Enable when binding the derived interface then we interpret the return types on imported interface methods as *always* being of a nullable type, even for types such as `void`: // C# binding for androidx.core.core with $(Nullable)=Enable partial class ISupportMenuInvoker : Java.Lang.Object, ISupportMenu { public unsafe void? Clear () {…} } This results in errors from the C# compiler: Error CS1519: Invalid token '?' in class, record, struct, or interface member declaration Error CS1520: Method must have a return type Error CS0535: 'ISupportMenuInvoker' does not implement interface member 'IMenu.Clear()' The culprit is twofold: - In `CecilApiImporter`, we set `Method.ManagedReturn` to `System.Void` instead of `void`. - In `CodeGenerationOptions`, we only check for `void` to omit the null operator, not `System.Void`. Note this also happens for all primitive types like `System.Int32`/`int`. This commit fixes both aspects: - Change `Method.ManagedReturn` to contain primitive types instead of fully qualified types. - Update `CodeGenerationOptions.GetNullable()` to correctly handle fully qualified types if one slips through. With this change, all of AndroidX/GooglePlayServices/FaceBook/MLKit can be successfully compiled with `<Nullable>enable</Nullable>`.
- Loading branch information