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] Add support for @explicitInterface metadata (#1006)
Fixes: #1005
Context: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-8.0/default-interface-methods#reabstraction
Sometimes Java interfaces will "re-declare" methods from implemented
interfaces:
// Java
interface /* java.lang. */ AutoCloseable {
void close();
}
interface /* java.io. */ Closeable {
void close();
}
Historically, this has been bound in C# by "ignoring" that the method
was re-declared:
// C#
partial interface /* Java.Lang. */ IAutoCloseable {
void Close();
}
partial interface /* Java.IO. */ ICloseable : IAutoCloseable {
void Close();
}
This would result in a [CS0108 warning][0]:
warning CS0108: 'ICloseable.Close()' hides inherited member 'IAutoCloseable.Close()'.
Use the new keyword if hiding was intended.
*Note*: in .NET for Android, this *particular* scenario doesn't
happen, as [`metadata` is used to remove `AutoCloseable`][1].
This scenario happens for other methods, e.g.:
warning CS0108: 'IChannel.Close()' hides inherited member 'ICloseable.Close()'.
Consequently, the .NET for Android build ignores CS0108 warnings.
This in turn means that e.g. `IChannel.Close()` is implicitly
declared as `new`.
With the introduction of [Default Interface Members in C# 8][2], it
is possible to ["re-abstract"][3] a method declared in an implemented
interface. However, in order to re-abstract a member, the member
must be explicitly qualified:
partial interface ICloseable : IAutoCloseable {
abstract void IAutoCloseable.Close ();
}
The declaring type isn't something we have enough information to
figure out automatically.
Add support for `explicitInterface` metadata which allows the
declaring interface to be explicitly specified.
<attr
path="/api/package[@name='java.io']/interface[@name='Closeable']/method[@name='close']"
name="explicitInterface">IAutoCloseable</attr>
Note this is not really a concept that `generator` "understands" it
will simply output whatever is specified in this attribute. Thus the
value is the *C#* interface name, not the *Java* interface name.
For properties, placing `explicitInterface` on either the `getFoo` or
`setFoo` methods will work. The getter value takes precedence if
both are specified.
This is implemented for both `interface` and `class` members, should
there be other use-cases that can benefit from it.
[0]: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-messages/cs0108
[1]: https://github.com/xamarin/xamarin-android/blob/59352f833846c563768f18dd72133be101b0ddc6/src/Mono.Android/metadata#L1393
[2]: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-8.0/default-interface-methods
[3]: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-8.0/default-interface-methods#reabstraction
0 commit comments