You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[generator] Fix NRE when interfaces appear to implement classes. (#798)
Fixes: #797
In commit b0d170c we updated `generator` to only apply the
ConstSugar logic to `Mono.Android.dll`. However, there are other
libraries written by Google that use the same pattern, namely
AndroidX. I still think removing ConstSugar is the correct move for
libraries other than `Mono.Android` because it causes more problems
than it solves. (Also, `ConstSugar` is irrelevant in the
Default Interface Method world we want to move the ecosystem to.)
However, there is an issue when other libraries try to create
interfaces that inherit `Mono.Android.dll`'s
`Android.Provider.BaseColumns` type:
`Mono.Android.dll` contains:
[Register ("android.provider.BaseColumns")] public abstract class BaseColumns
[Register ("android.provider.BaseColumns")] public interface IBaseColumns
When we build our Java -> C# typemap in `generator`, we only support
a single mapping per key, and it just happens that
`abstract class BaseColumns` wins. Thus when we look for the Symbol
that matches `implements android.provider.BaseColumns` we end up with
a `class` instead of a `interface`. We then cast that as an
`InterfaceGen` which is `null`, and throw a `NullReferenceException`:
System.NullReferenceException: Object reference not set to an instance of an object
at generator.SourceWriters.BoundInterface.AddInheritedInterfaces (MonoDroid.Generation.InterfaceGen iface, MonoDroid.Generation.CodeGenerationOptions opt)
at generator.SourceWriters.BoundInterface..ctor (MonoDroid.Generation.InterfaceGen iface, MonoDroid.Generation.CodeGenerationOptions opt, MonoDroid.Generation.CodeGeneratorContext context, MonoDroid.Generation.GenerationInfo genInfo)
at generator.SourceWriters.SourceWriterExtensions.BuildManagedTypeModel (MonoDroid.Generation.GenBase gen, MonoDroid.Generation.CodeGenerationOptions opt, MonoDroid.Generation.CodeGeneratorContext context, MonoDroid.Generation.GenerationInfo genInfo)
at generator.SourceWriters.BoundClass.AddNestedTypes (MonoDroid.Generation.ClassGen klass, MonoDroid.Generation.CodeGenerationOptions opt, MonoDroid.Generation.CodeGeneratorContext context, MonoDroid.Generation.GenerationInfo genInfo)
at generator.SourceWriters.BoundClass..ctor (MonoDroid.Generation.ClassGen klass, MonoDroid.Generation.CodeGenerationOptions opt, MonoDroid.Generation.CodeGeneratorContext context, MonoDroid.Generation.GenerationInfo generationInfo)
at MonoDroid.Generation.JavaInteropCodeGenerator.WriteType (MonoDroid.Generation.GenBase gen, System.String indent, MonoDroid.Generation.GenerationInfo gen_info)
at MonoDroid.Generation.ClassGen.Generate (MonoDroid.Generation.CodeGenerationOptions opt, MonoDroid.Generation.GenerationInfo gen_info)
at Xamarin.Android.Binder.CodeGenerator.Run (Xamarin.Android.Binder.CodeGeneratorOptions options, Java.Interop.Tools.Cecil.DirectoryAssemblyResolver resolver)
at Xamarin.Android.Binder.CodeGenerator.Run (Xamarin.Android.Binder.CodeGeneratorOptions options)
at Xamarin.Android.Binder.CodeGenerator.Main (System.String[] args)
There are at least three ways to address this:
1. We could update `generator` to support more than
Java -> C# mapping.
2. *Don't* emit a `[Register]` on the `BaseColumns` class.
3. Add a `null` check to `BoundInterface.AddInheritedInterfaces()`,
avoiding the `NullReferenceException`.
While (1) and (2) may address the exception, we're not sure what the
broader ramifications will be.
For now, go with (3). The bindings will still be fine since these
interfaces are not meant to be implemented, just used to provide
access to constants.
0 commit comments