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 @managedOverride values none and reabstract. (#1000)
Fixes: #981
Context: 5a0e37e
Add support for `//class/method[@managedOverride = 'none']` and
`//interface/method[@managedOverride = 'reabstract']`.
Setting `@managedOverride` to `none` ensures that the member is not
marked with `virtual` or `override`. This is useful for `sealed`
classes, to avoid a [CS0549 error][0]. Previously, given the Java:
// Java
public final class MyClass {
public void doThing() {/* … */ }
}
The `class-parse` XML would specify that `MyClass.doThing()` was
"virtual" -- `@abstract` is false, `@final` is false:
<class name="MyClass …>
<method
abstract="false"
final="false"
name="doThing"
return="void"
… />
</class>
This would result in the C# binding:
// C#
public sealed partial class MyClass {
public virtual void DoThing() => …
}
which would error out with a CS0549:
error CS0549: 'MyClass.DoThing()' is a new virtual member in sealed type 'MyClass'
This can now be resolved by setting `@managedOverride` to `none`:
<attr path="//class[@name='MyClass']/method[@name='doThing']"
name="managedOverride">none</attr>
which will result in the compilable binding:
// C#
public sealed partial class MyClass {
public void DoThing() => …
}
Setting `@managedOverride` to `reabstract` is part of support for
re-abstracting interface members; see also a65d6fb. Currently in
`src/Java.Base`, we have Java:
// Java
public interface AnnotatedType {
default AnnotatedType getAnnotatedOwnerType() {…}
}
public interface AnnotatedArrayType implements AnnotatedType {
AnnotatedType getAnnotatedOwnerType(); // re-abstract interface default method
}
which results in the C# binding:
// C#
public partial interface IAnnotatedType {
virtual IAnnotatedType? AnnotatedOwnerType {
get => …
}
}
public partial interface IAnnotatedArrayType : IAnnotatedType {
IAnnotatedType? AnnotatedOwnerType { get; } // CS0108
}
which results in a [warning CS0108][1]:
warning CS0108: 'IAnnotatedArrayType.AnnotatedOwnerType' hides inherited member
'IAnnotatedType.AnnotatedOwnerType'. Use the new keyword if hiding was intended.
Fixing this requires two steps. First, we can now set
`//interface/method/@managedOverride` to `reabstract`:
<attr path="//interface[@name='AnnotatedArrayType']/method[@name='getAnnotatedOwnerType']"
name="managedOverride">reabstract</attr>
What we *also* need to do is make the member *explicitly qualified*.
This can be "forced" for *properties* by setting `@propertyName`:
<attr path="//interface[@name='AnnotatedArrayType']/method[@name='getAnnotatedOwnerType']"
name="propertyName">IAnnotatedType.AnnotatedOwnerType</attr>
`@managedOverride` and `@propertyName` work together to emit:
public partial interface IAnnotatedArrayType : IAnnotatedType {
abstract IAnnotatedType? IAnnotatedType.AnnotatedOwnerType {get;}
}
The problem is that this combination probably breaks Android output,
and it can't be used for *method* overrides, e.g. having
`java.io.Closeable.close()` re-abstract `java.lang.AutoCloseable.close()`.
TODO: complete the "interface reabstract" case, possibly via
`//interface/method[@explicitInterface='ManagedInterfaceName']`:
<attr path="//interface[@name='AnnotatedArrayType']/method[@name='getAnnotatedOwnerType']"
name="explicitInterface">IAnnotatedType</attr>
[0]: https://docs.microsoft.com/en-us/dotnet/csharp/misc/cs0549
[1]: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-messages/cs0108
0 commit comments