Skip to content

Commit d0231c5

Browse files
authored
[generator] Override methods should match base deprecated info (#1130)
There are several warnings when building `Mono.Android.dll` related to `[Obsolete]` methods, e.g.: warning CS0672: Member 'MediaRouteActionProvider.OnCreateActionView()' overrides obsolete member 'ActionProvider.OnCreateActionView()'. Add the Obsolete attribute to 'MediaRouteActionProvider.OnCreateActionView()' Technically, `MediaRouteActionProvider.onCreateActionView()` is only marked as `deprecated` in the [docs][0], but not in `android.jar`: public class MediaRouteActionProvider extends ActionProvider { public View onCreateActionView() { throw new RuntimeException("Stub!"); } } Regardless, any method that overrides a deprecated method should itself be marked as deprecated. Another case specific to `Mono.Android.dll` is [`ContextWrapper.setWallpaper()`][1]. This method is marked as `deprecated-since`=23, but the base method is marked as `deprecated-since`=16. This causes us to generate: public class Context { [Obsolete] public virtual void SetWallpaper () { ... } } public class ContextWrapper : Context { [ObsoletedOSPlatform ("android23.0")] public override void SetWallpaper () { ... } } This causes the same CS0672 warning. Fix the CS0672 warnings by setting the `override` method's `deprecated-since` to match the base method's `deprecated-since`. [0]: https://developer.android.com/reference/android/app/MediaRouteActionProvider?hl=en#onCreateActionView() [1]: https://developer.android.com/reference/android/content/ContextWrapper?hl=en#setWallpaper(android.graphics.Bitmap)
1 parent e1121ea commit d0231c5

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

tests/generator-Tests/Unit-Tests/CodeGeneratorTests.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,6 +1120,50 @@ public void AvoidNREOnInvalidBaseMethod ()
11201120
Assert.AreEqual (true, base_class.Methods [0].IsValid);
11211121
}
11221122

1123+
[Test]
1124+
public void FixupDeprecatedBaseMethods ()
1125+
{
1126+
var xml = @"<api>
1127+
<package name='java.lang' jni-name='java/lang'>
1128+
<class abstract='false' deprecated='not deprecated' final='false' name='Object' static='false' visibility='public' jni-signature='Ljava/lang/Object;'>
1129+
<method abstract='false' deprecated='deprecated' final='false' name='DoStuff' jni-signature='()I' bridge='false' native='false' return='int' jni-return='I' static='false' synchronized='false' synthetic='false' visibility='public'></method>
1130+
</class>
1131+
</package>
1132+
<package name='com.xamarin.android' jni-name='com/xamarin/android'>
1133+
<class abstract='false' deprecated='not deprecated' extends='java.lang.Object' extends-generic-aware='java.lang.Object' jni-extends='Ljava/lang/Object;' final='false' name='MyClass' static='false' visibility='public' jni-signature='Lcom/xamarin/android/MyClass;'>
1134+
<method abstract='false' deprecated='not deprecated' final='false' name='DoStuff' jni-signature='()I' bridge='false' native='false' return='int' jni-return='I' static='false' synchronized='false' synthetic='false' visibility='public'></method>
1135+
</class>
1136+
</package>
1137+
</api>";
1138+
1139+
var gens = ParseApiDefinition (xml);
1140+
1141+
// Override method should be marked deprecated because base method is
1142+
Assert.AreEqual ("deprecated", gens.Single (g => g.Name == "MyClass").Methods.Single (m => m.Name == "DoStuff").Deprecated);
1143+
}
1144+
1145+
[Test]
1146+
public void FixupDeprecatedSinceBaseMethods ()
1147+
{
1148+
var xml = @"<api>
1149+
<package name='java.lang' jni-name='java/lang'>
1150+
<class abstract='false' deprecated='not deprecated' final='false' name='Object' static='false' visibility='public' jni-signature='Ljava/lang/Object;'>
1151+
<method abstract='false' deprecated='deprecated' final='false' name='DoStuff' jni-signature='()I' bridge='false' native='false' return='int' jni-return='I' static='false' synchronized='false' synthetic='false' visibility='public' deprecated-since='11'></method>
1152+
</class>
1153+
</package>
1154+
<package name='com.xamarin.android' jni-name='com/xamarin/android'>
1155+
<class abstract='false' deprecated='not deprecated' extends='java.lang.Object' extends-generic-aware='java.lang.Object' jni-extends='Ljava/lang/Object;' final='false' name='MyClass' static='false' visibility='public' jni-signature='Lcom/xamarin/android/MyClass;'>
1156+
<method abstract='false' deprecated='not deprecated' final='false' name='DoStuff' jni-signature='()I' bridge='false' native='false' return='int' jni-return='I' static='false' synchronized='false' synthetic='false' visibility='public' deprecated-since='21'></method>
1157+
</class>
1158+
</package>
1159+
</api>";
1160+
1161+
var gens = ParseApiDefinition (xml);
1162+
1163+
// Override method should match base method's 'deprecated-since'
1164+
Assert.AreEqual (11, gens.Single (g => g.Name == "MyClass").Methods.Single (m => m.Name == "DoStuff").DeprecatedSince);
1165+
}
1166+
11231167
static string StripRegisterAttributes (string str)
11241168
{
11251169
// It is hard to test if the [Obsolete] is on the setter/etc due to the [Register], so remove all [Register]s

tools/generator/Java.Interop.Tools.Generator.ObjectModel/GenBase.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,15 @@ public void FixupMethodOverrides (CodeGenerationOptions opt)
310310
var bm = bt.Methods.FirstOrDefault (mm => mm.Name == m.Name && mm.Visibility == m.Visibility && ParameterList.Equals (mm.Parameters, m.Parameters));
311311
if (bm != null && bm.RetVal.FullName == m.RetVal.FullName) { // if return type is different, it could be still "new", not "override".
312312
m.IsOverride = true;
313+
314+
// If method overrides a deprecated method, it also needs to be marked as deprecated
315+
if (bm.Deprecated.HasValue () && !m.Deprecated.HasValue ())
316+
m.Deprecated = bm.Deprecated;
317+
318+
// Fix issue when base method was deprecated before the overriding method, set both both to base method value
319+
if (bm.DeprecatedSince.GetValueOrDefault (0) < m.DeprecatedSince.GetValueOrDefault (0))
320+
m.DeprecatedSince = bm.DeprecatedSince;
321+
313322
break;
314323
}
315324
}

0 commit comments

Comments
 (0)