Skip to content

Commit dede5ac

Browse files
committed
[generator] Add support for [ObsoletedOSPlatform].
1 parent 6d1ae4e commit dede5ac

26 files changed

+170
-27
lines changed

src/utils/XmlExtensions.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,18 @@ public static string XGetAttribute (this XPathNavigator nav, string name, string
2020
var attr = nav.GetAttribute (name, ns);
2121
return attr != null ? attr.Trim () : null;
2222
}
23+
24+
public static int? XGetAttributeAsIntOrNull (this XElement element, string name)
25+
{
26+
var attr = element.Attribute (name);
27+
28+
if (attr?.Value is null)
29+
return null;
30+
31+
if (int.TryParse (attr.Value, out var val))
32+
return val;
33+
34+
return null;
35+
}
2336
}
2437
}

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

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,76 @@ public void ObsoleteBoundMethodAbstractDeclaration ()
531531
Assert.True (writer.ToString ().Contains ("[global::System.Obsolete (@\"This is so old!\")]"), writer.ToString ());
532532
}
533533

534+
[Test]
535+
public void ObsoletedOSPlatformAttributeSupport ()
536+
{
537+
var xml = @"<api>
538+
<package name='java.lang' jni-name='java/lang'>
539+
<class abstract='false' deprecated='not deprecated' final='false' name='Object' static='false' visibility='public' jni-signature='Ljava/lang/Object;' />
540+
</package>
541+
<package name='com.xamarin.android' jni-name='com/xamarin/android'>
542+
<class abstract='false' deprecated='This is a class deprecated since 25!' 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;' deprecated-since='25'>
543+
<field deprecated='This is a field deprecated since 25!' final='true' name='ACCEPT_HANDOVER' jni-signature='Ljava/lang/String;' static='true' transient='false' type='java.lang.String' type-generic-aware='java.lang.String' value='&quot;android.permission.ACCEPT_HANDOVER&quot;' visibility='public' volatile='false' deprecated-since='25'></field>
544+
<constructor deprecated='This is a constructor deprecated since 25!' final='false' name='MyClass' jni-signature='()V' bridge='false' static='false' type='com.xamarin.android.MyClass' synthetic='false' visibility='public' deprecated-since='25'></constructor>
545+
<method abstract='true' deprecated='This is a method deprecated since 25!' final='false' name='countAffectedRows' jni-signature='()I' bridge='false' native='false' return='int' jni-return='I' static='false' synchronized='false' synthetic='false' visibility='public' deprecated-since='25'></method>
546+
</class>
547+
</package>
548+
</api>";
549+
550+
options.UseObsoletedOSPlatformAttributes = true;
551+
552+
var gens = ParseApiDefinition (xml);
553+
var iface = gens.Single (g => g.Name == "MyClass");
554+
555+
generator.Context.ContextTypes.Push (iface);
556+
generator.WriteType (iface, string.Empty, new GenerationInfo ("", "", "MyAssembly"));
557+
generator.Context.ContextTypes.Pop ();
558+
559+
// Ensure [ObsoletedOSPlatform] was written
560+
Assert.True (writer.ToString ().Contains ("[global::System.Runtime.Versioning.ObsoletedOSPlatform (\"android25.0\", @\"This is a class deprecated since 25!\")]"), writer.ToString ());
561+
Assert.True (writer.ToString ().Contains ("[global::System.Runtime.Versioning.ObsoletedOSPlatform (\"android25.0\", @\"This is a field deprecated since 25!\")]"), writer.ToString ());
562+
Assert.True (writer.ToString ().Contains ("[global::System.Runtime.Versioning.ObsoletedOSPlatform (\"android25.0\", @\"This is a constructor deprecated since 25!\")]"), writer.ToString ());
563+
Assert.True (writer.ToString ().Contains ("[global::System.Runtime.Versioning.ObsoletedOSPlatform (\"android25.0\", @\"This is a method deprecated since 25!\")]"), writer.ToString ());
564+
}
565+
566+
[Test]
567+
public void ObsoletedOSPlatformAttributeUnneededSupport ()
568+
{
569+
var xml = @"<api>
570+
<package name='java.lang' jni-name='java/lang'>
571+
<class abstract='false' deprecated='not deprecated' final='false' name='Object' static='false' visibility='public' jni-signature='Ljava/lang/Object;' />
572+
</package>
573+
<package name='com.xamarin.android' jni-name='com/xamarin/android'>
574+
<class abstract='false' deprecated='This is a class deprecated since 19!' 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;' deprecated-since='19'>
575+
<field deprecated='This is a field deprecated since 0!' final='true' name='ACCEPT_HANDOVER' jni-signature='Ljava/lang/String;' static='true' transient='false' type='java.lang.String' type-generic-aware='java.lang.String' value='&quot;android.permission.ACCEPT_HANDOVER&quot;' visibility='public' volatile='false' deprecated-since='0'></field>
576+
<constructor deprecated='This is a constructor deprecated since empty string!' final='false' name='MyClass' jni-signature='()V' bridge='false' static='false' type='com.xamarin.android.MyClass' synthetic='false' visibility='public' deprecated-since=''></constructor>
577+
<method abstract='true' deprecated='deprecated' final='false' name='countAffectedRows' jni-signature='()I' bridge='false' native='false' return='int' jni-return='I' static='false' synchronized='false' synthetic='false' visibility='public' deprecated-since='25'></method>
578+
<method abstract='true' deprecated='This method has an invalid deprecated-since!' final='false' name='countAffectedRows2' jni-signature='()I' bridge='false' native='false' return='int' jni-return='I' static='false' synchronized='false' synthetic='false' visibility='public' deprecated-since='foo'></method>
579+
</class>
580+
</package>
581+
</api>";
582+
583+
options.UseObsoletedOSPlatformAttributes = true;
584+
585+
var gens = ParseApiDefinition (xml);
586+
var iface = gens.Single (g => g.Name == "MyClass");
587+
588+
generator.Context.ContextTypes.Push (iface);
589+
generator.WriteType (iface, string.Empty, new GenerationInfo ("", "", "MyAssembly"));
590+
generator.Context.ContextTypes.Pop ();
591+
592+
// These should use [Obsolete] because they have always been obsolete in all currently supported versions (21+)
593+
Assert.True (writer.ToString ().Contains ("[global::System.Obsolete (@\"This is a class deprecated since 19!\")]"), writer.ToString ());
594+
Assert.True (writer.ToString ().Contains ("[global::System.Obsolete (@\"This is a field deprecated since 0!\")]"), writer.ToString ());
595+
Assert.True (writer.ToString ().Contains ("[global::System.Obsolete (@\"This is a constructor deprecated since empty string!\")]"), writer.ToString ());
596+
597+
// This should not have a message because the default "deprecated" message isn't useful
598+
Assert.True (writer.ToString ().Contains ("[global::System.Runtime.Versioning.ObsoletedOSPlatform (\"android25.0\")]"), writer.ToString ());
599+
600+
// This should use [Obsolete] because the 'deprecated-since' attribute could not be parsed
601+
Assert.True (writer.ToString ().Contains ("[global::System.Obsolete (@\"This method has an invalid deprecated-since!\")]"), writer.ToString ());
602+
}
603+
534604
[Test]
535605
[NonParallelizable] // We are setting a static property on Report
536606
public void WarnIfTypeNameMatchesNamespace ()

tools/generator/CodeGenerationOptions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ public SymbolTable SymbolTable {
6666
public bool SupportNestedInterfaceTypes { get; set; }
6767
public bool SupportNullableReferenceTypes { get; set; }
6868
public bool UseShallowReferencedTypes { get; set; }
69+
public bool UseObsoletedOSPlatformAttributes { get; set; }
6970
public bool RemoveConstSugar => BuildingCoreAssembly;
7071

7172
bool? buildingCoreAssembly;

tools/generator/CodeGenerator.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ static void Run (CodeGeneratorOptions options, DirectoryAssemblyResolver resolve
8383
SupportDefaultInterfaceMethods = options.SupportDefaultInterfaceMethods,
8484
SupportNestedInterfaceTypes = options.SupportNestedInterfaceTypes,
8585
SupportNullableReferenceTypes = options.SupportNullableReferenceTypes,
86+
UseObsoletedOSPlatformAttributes = options.UseObsoletedOSPlatformAttributes,
8687
};
8788
var resolverCache = new TypeDefinitionCache ();
8889

tools/generator/CodeGeneratorOptions.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ public CodeGeneratorOptions ()
5353
public bool SupportNestedInterfaceTypes { get; set; }
5454
public bool SupportNullableReferenceTypes { get; set; }
5555
public bool UseLegacyJavaResolver { get; set; }
56+
public bool UseObsoletedOSPlatformAttributes { get; set; }
5657

5758
public XmldocStyle XmldocStyle { get; set; } = XmldocStyle.IntelliSense;
5859

@@ -102,12 +103,13 @@ public static CodeGeneratorOptions Parse (string[] args)
102103
"SDK Platform {VERSION}/API level.",
103104
v => opts.ApiLevel = v },
104105
{ "lang-features=",
105-
"For internal use. (Flags: interface-constants,default-interface-methods,nullable-reference-types)",
106+
"For internal use. (Flags: interface-constants,default-interface-methods,nested-interface-types,nullable-reference-types,obsoleted-platform-attributes)",
106107
v => {
107108
opts.SupportInterfaceConstants = v?.Contains ("interface-constants") == true;
108109
opts.SupportDefaultInterfaceMethods = v?.Contains ("default-interface-methods") == true;
109110
opts.SupportNestedInterfaceTypes = v?.Contains ("nested-interface-types") == true;
110111
opts.SupportNullableReferenceTypes = v?.Contains ("nullable-reference-types") == true;
112+
opts.UseObsoletedOSPlatformAttributes = v?.Contains ("obsoleted-platform-attributes") == true;
111113
}},
112114
{ "preserve-enums",
113115
"For internal use.",

tools/generator/Java.Interop.Tools.Generator.Importers/XmlApiImporter.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ public static Ctor CreateCtor (GenBase declaringType, XElement elem, CodeGenerat
155155
ApiAvailableSince = declaringType.ApiAvailableSince,
156156
CustomAttributes = elem.XGetAttribute ("customAttributes"),
157157
Deprecated = elem.Deprecated (),
158+
DeprecatedSince = elem.XGetAttributeAsIntOrNull ("deprecated-since"),
158159
GenericArguments = elem.GenericArguments (),
159160
Name = elem.XGetAttribute ("name"),
160161
Visibility = elem.Visibility ()
@@ -200,6 +201,7 @@ public static Field CreateField (GenBase declaringType, XElement elem, CodeGener
200201
var field = new Field {
201202
ApiAvailableSince = declaringType.ApiAvailableSince,
202203
DeprecatedComment = elem.XGetAttribute ("deprecated"),
204+
DeprecatedSince = elem.XGetAttributeAsIntOrNull ("deprecated-since"),
203205
IsAcw = true,
204206
IsDeprecated = elem.XGetAttribute ("deprecated") != "not deprecated",
205207
IsDeprecatedError = elem.XGetAttribute ("deprecated-error") == "true",
@@ -237,6 +239,7 @@ public static Field CreateField (GenBase declaringType, XElement elem, CodeGener
237239
public static GenBaseSupport CreateGenBaseSupport (XElement pkg, XElement elem, CodeGenerationOptions opt, bool isInterface)
238240
{
239241
var support = new GenBaseSupport {
242+
DeprecatedSince = elem.XGetAttributeAsIntOrNull ("deprecated-since"),
240243
IsAcw = true,
241244
IsDeprecated = elem.XGetAttribute ("deprecated") != "not deprecated",
242245
IsGeneratable = true,
@@ -348,6 +351,7 @@ public static Method CreateMethod (GenBase declaringType, XElement elem, CodeGen
348351
ArgsType = elem.Attribute ("argsType")?.Value,
349352
CustomAttributes = elem.XGetAttribute ("customAttributes"),
350353
Deprecated = elem.Deprecated (),
354+
DeprecatedSince = elem.XGetAttributeAsIntOrNull ("deprecated-since"),
351355
ExplicitInterface = elem.XGetAttribute ("explicitInterface"),
352356
EventName = elem.Attribute ("eventName")?.Value,
353357
GenerateAsyncWrapper = elem.Attribute ("generateAsyncWrapper") != null,

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ public class Field : ApiVersionsSupport.IApiAvailability, ISourceLineInfo
99
public string Annotation { get; set; }
1010
public int ApiAvailableSince { get; set; }
1111
public string DeprecatedComment { get; set; }
12+
public int? DeprecatedSince { get; set; }
1213
public bool IsAcw { get; set; }
1314
public bool IsDeprecated { get; set; }
1415
public bool IsDeprecatedError { get; set; }

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,8 @@ public bool ContainsProperty (string name, bool check_ifaces, bool check_base_if
251251

252252
public string DeprecatedComment => support.DeprecatedComment;
253253

254+
public int? DeprecatedSince => support.DeprecatedSince;
255+
254256
IEnumerable<GenBase> Descendants (IList<GenBase> gens)
255257
{
256258
foreach (var directDescendants in gens.Where (x => x.BaseGen == this)) {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ public class GenBaseSupport
77
public bool IsAcw { get; set; }
88
public bool IsDeprecated { get; set; }
99
public string DeprecatedComment { get; set; }
10+
public int? DeprecatedSince { get; set; }
1011
public bool IsGeneratable { get; set; }
1112
public bool IsGeneric { get; set; }
1213
public bool IsObfuscated { get; set; }

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ protected MethodBase (GenBase declaringType)
1818
public string AssemblyName { get; set; }
1919
public GenBase DeclaringType { get; }
2020
public string Deprecated { get; set; }
21+
public int? DeprecatedSince { get; set; }
2122
public GenericParameterDefinitionList GenericArguments { get; set; }
2223
public bool IsAcw { get; set; }
2324
public bool IsValid { get; private set; }

0 commit comments

Comments
 (0)