Commit 2244407
authored
[generator] Ensure DIM from assembly refs are correctly marked (#770)
Context: dotnet/android-libraries#235
Consider the following Java API:
// Java
public interface MyInterface {
default void doSomething() {}
}
public class MyAbstractClass implements MyInterface {
}
which is then bound in C# as:
// C#
[Register (…)]
public interface IMyInterface {
[Register(…)]
public void DoSomething() => …; // default interface method
}
[Register (…)]
public abstract class MyAbstractClass : Java.Lang.Object, IMyInterface {
// Doesn't override IMyInterface.DoSomething()
}
`generator` needs to ensure that `Method.IsInterfaceDefaultMethod()`
gets set for `IMyInterface.DoSomething()` so that the
`BoundClass.AddInterfaceAbstractMembers()` logic knows it does not
need to create an `abstract` method `MyAbstractClass.DoSomething()`.
This works correctly if the interface is in the assembly we are
binding, because it uses `XmlApiImporter`. That is, `generator`
output is valid if `MyInterface` and `MyAbstractClass` are in the
same `.jar`.
However, if the interface is in a reference assembly -- `MyInterface`
and `MyAbstractClass` are in different assemblies -- then `generator`
uses `CecilApiImporter`, and our Cecil importer only marks Java
Interface Default Methods if the method has a
`[JavaInterfaceDefaultMethodAttribute]` custom attribute, which we
don't appear to ever emit.
Consequently, when `MyInterface` and `MyAbstractClass` are in
separate libraries, then `MyAbstractClass` is bound as:
// C#
[Register (…)]
public abstract class MyAbstractClass : Java.Lang.Object, IMyInterface {
public abstract void DoSomething();
}
which causes most bindings that inherit `MyAbstractClass` to fail,
as they typically don't override the interface default method:
// C#
[Register (…)]
public class MyClass : MyAbstractClass {
}
// error CS0534: 'MyClass' does not implemented inherited abstract member 'MyAbstractClass.DoSomething()'
Update `generator` and `CecilApiImporter` to properly detect C#8
default interface methods without requiring the presence of the
(unused!) `[JavaInterfaceDefaultMethodAttribute]` custom attribute,
so that classes don't re-declare C#8 interface default methods as
"new" abstract methods. This fixes the generated `MyAbstractClass`
declaration to be:
// C*
[Register (…)]
public class MyAbstractClass : Java.Lang.Object, IMyInterface {
// No `DoSomething()` declaration
}1 parent da73d6a commit 2244407
File tree
1 file changed
+12
-1
lines changed- tools/generator/Java.Interop.Tools.Generator.Importers
1 file changed
+12
-1
lines changedLines changed: 12 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
191 | 191 | | |
192 | 192 | | |
193 | 193 | | |
194 | | - | |
| 194 | + | |
195 | 195 | | |
196 | 196 | | |
197 | 197 | | |
| |||
248 | 248 | | |
249 | 249 | | |
250 | 250 | | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
251 | 262 | | |
252 | 263 | | |
0 commit comments