Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Xamarin.Android.Build.Tasks] Skip AbstractMethodErrors on DIM (#3458)
Context: f96fcf9 Context: https://github.com/jpobst/dimtest Context: #1939 As of commit f96fcf9, the linker will "fix abstract methods" in order to preserve binary compatibility. For example, if a type built for e.g. `$(TargetFrameworkVersion)`=v2.3 implements a Java side interface, and the assembly containing that type is included into an app with `$(TargetFrameworkVersion)`=v10.0 and the Java-side interface added members between v2.3 and v10, then those "added"/ "missing" interface members will be *inserted* into the type, with a implementation which throws `Java.Lang.AbstractMethodError`. Unfortunately, f96fcf9 assumes that *all* interface members are "abstract" members which need to be implemented (or fixed up). This is no longer true with [C#8 Default Interface Members][0], as interface methods can now contain bodies: namespace MyNamespace { public IMyInterface { void MyAbstractMethod (); public void MyDefaultMethod () { } } } Types which implement `IMyInterface` don't need to provide an implementation for `IMyInterface.MyDefaultMethod()`, which is *fine*: // What the developer wrote class MyExample : IMyInterface { public void MyAbstractMethod() {} // Does not provide MyDefaultMethod() } Unfortunately, `FixAbstractMethodsStep` didn't know about such methods (they didn't exist in 2017), so it would insert the "missing" abstract methods: // What the linker writes: class MyExample : IMyInterface { public void MyAbstractMethod () {} public void MyDefaultMethod () => throw new Java.Lang.AbstractMethodError (); } Additionally, `FixAbstractMethodsStep` was not constrained to operate on only Java-related types and interfaces. It fixes *everything*. This breaks a "pure C#" scenario in which Java isn't involved at all: IMyInterface e = new MyExample (); e.MyDefaultMethod (); The expectation is that this will invoke the `IMyInterface.MyDefaultMethod()` method. Instead, it throws an `AbstractMethodError`! Update `FixAbstractMethodsStep` so that it only processes *`abstract`* methods, not all interface methods. This will prevent it from emitting a `MyExample.MyDefaultMethod()` override and prevent the `AbstractMethodError` from being thrown. [0]: https://github.com/dotnet/csharplang/blob/f7952cdddf85316a4beec493a0ecc14fcb3241c8/proposals/csharp-8.0/default-interface-methods.md
- Loading branch information