diff --git a/tests/generator-Tests/Unit-Tests/CodeGeneratorTests.cs b/tests/generator-Tests/Unit-Tests/CodeGeneratorTests.cs
index 29e4205e1..961668207 100644
--- a/tests/generator-Tests/Unit-Tests/CodeGeneratorTests.cs
+++ b/tests/generator-Tests/Unit-Tests/CodeGeneratorTests.cs
@@ -1406,6 +1406,36 @@ public void SupportedOSPlatformConstFields ()
StringAssert.Contains ("[global::System.Runtime.Versioning.SupportedOSPlatformAttribute (\"android30.0\")]", builder.ToString (), "Should contain SupportedOSPlatform!");
}
+ [Test]
+ public void UnsupportedOSPlatform ()
+ {
+ var klass = SupportTypeBuilder.CreateClass ("java.code.MyClass", options);
+ klass.ApiRemovedSince = 30;
+
+ generator.Context.ContextTypes.Push (klass);
+ generator.WriteType (klass, string.Empty, new GenerationInfo ("", "", "MyAssembly"));
+ generator.Context.ContextTypes.Pop ();
+
+ StringAssert.Contains ("[global::System.Runtime.Versioning.UnsupportedOSPlatformAttribute (\"android30.0\")]", builder.ToString (), "Should contain UnsupportedOSPlatform!");
+ }
+
+ [Test]
+ public void UnsupportedOSPlatformConstFields ()
+ {
+ var klass = new TestClass ("java.lang.Object", "com.mypackage.foo");
+ var field = new TestField ("java.lang.String", "bar").SetConstant ("MY_VALUE");
+
+ field.ApiRemovedSince = 30;
+
+ klass.Fields.Add (field);
+
+ generator.Context.ContextTypes.Push (klass);
+ generator.WriteType (klass, string.Empty, new GenerationInfo ("", "", "MyAssembly"));
+ generator.Context.ContextTypes.Pop ();
+
+ StringAssert.Contains ("[global::System.Runtime.Versioning.UnsupportedOSPlatformAttribute (\"android30.0\")]", builder.ToString (), "Should contain UnsupportedOSPlatform!");
+ }
+
[Test]
public void StringPropertyOverride ([Values ("true", "false")] string final)
{
diff --git a/tests/generator-Tests/Unit-Tests/XmlApiImporterTests.cs b/tests/generator-Tests/Unit-Tests/XmlApiImporterTests.cs
index 9999d17b4..b19aa96f5 100644
--- a/tests/generator-Tests/Unit-Tests/XmlApiImporterTests.cs
+++ b/tests/generator-Tests/Unit-Tests/XmlApiImporterTests.cs
@@ -51,6 +51,15 @@ public void CreateClass_CorrectApiSinceOverridePackage ()
Assert.AreEqual (9, klass.ApiAvailableSince);
}
+ [Test]
+ public void CreateClass_CorrectApiRemoved ()
+ {
+ var xml = XDocument.Parse ("");
+ var klass = XmlApiImporter.CreateClass (xml.Root, xml.Root.Element ("class"), opt);
+
+ Assert.AreEqual (7, klass.ApiRemovedSince);
+ }
+
[Test]
public void CreateCtor_EnsureValidName ()
{
diff --git a/tools/generator/ApiVersionsSupport.cs b/tools/generator/ApiVersionsSupport.cs
index 43530de89..524c7437d 100644
--- a/tools/generator/ApiVersionsSupport.cs
+++ b/tools/generator/ApiVersionsSupport.cs
@@ -18,6 +18,7 @@ public static class ApiVersionsSupport
public interface IApiAvailability
{
int ApiAvailableSince { get; set; }
+ int ApiRemovedSince { get; set; }
}
static IEnumerable FlattenGens (IEnumerable gens)
diff --git a/tools/generator/Java.Interop.Tools.Generator.Importers/XmlApiImporter.cs b/tools/generator/Java.Interop.Tools.Generator.Importers/XmlApiImporter.cs
index 901f235e8..6c3a67767 100644
--- a/tools/generator/Java.Interop.Tools.Generator.Importers/XmlApiImporter.cs
+++ b/tools/generator/Java.Interop.Tools.Generator.Importers/XmlApiImporter.cs
@@ -159,6 +159,7 @@ public static Ctor CreateCtor (GenBase declaringType, XElement elem, CodeGenerat
var ctor = new Ctor (declaringType) {
AnnotatedVisibility = elem.XGetAttribute ("annotated-visibility"),
ApiAvailableSince = declaringType.ApiAvailableSince,
+ ApiRemovedSince = declaringType.ApiRemovedSince,
CustomAttributes = elem.XGetAttribute ("customAttributes"),
Deprecated = elem.Deprecated (),
DeprecatedSince = elem.XGetAttributeAsIntOrNull ("deprecated-since"),
@@ -211,6 +212,7 @@ public static Field CreateField (GenBase declaringType, XElement elem, CodeGener
var field = new Field {
AnnotatedVisibility = elem.XGetAttribute ("annotated-visibility"),
ApiAvailableSince = declaringType.ApiAvailableSince,
+ ApiRemovedSince = declaringType.ApiRemovedSince,
DeprecatedComment = elem.XGetAttribute ("deprecated"),
DeprecatedSince = elem.XGetAttributeAsIntOrNull ("deprecated-since"),
IsAcw = true,
@@ -369,6 +371,7 @@ public static Method CreateMethod (GenBase declaringType, XElement elem, CodeGen
var method = new Method (declaringType) {
AnnotatedVisibility = elem.XGetAttribute ("annotated-visibility"),
ApiAvailableSince = declaringType.ApiAvailableSince,
+ ApiRemovedSince = declaringType.ApiRemovedSince,
ArgsType = elem.Attribute ("argsType")?.Value,
CustomAttributes = elem.XGetAttribute ("customAttributes"),
Deprecated = elem.Deprecated (),
@@ -515,9 +518,12 @@ static XElement GetPreviousClass (XNode n, string nameValue)
// Elements need to be passed in the above order. (package, class, member)
static void FillApiSince (ApiVersionsSupport.IApiAvailability model, params XElement[] elems)
{
- foreach (var elem in elems)
+ foreach (var elem in elems) {
if (int.TryParse (elem.XGetAttribute ("api-since"), out var result))
model.ApiAvailableSince = result;
+ if (int.TryParse (elem.XGetAttribute ("removed-since"), out var removed))
+ model.ApiRemovedSince = removed;
+ }
}
static bool IsObfuscatedName (int threshold, string name)
diff --git a/tools/generator/Java.Interop.Tools.Generator.ObjectModel/Field.cs b/tools/generator/Java.Interop.Tools.Generator.ObjectModel/Field.cs
index 8477fab1d..4141993ee 100644
--- a/tools/generator/Java.Interop.Tools.Generator.ObjectModel/Field.cs
+++ b/tools/generator/Java.Interop.Tools.Generator.ObjectModel/Field.cs
@@ -9,6 +9,7 @@ public class Field : ApiVersionsSupport.IApiAvailability, ISourceLineInfo
public string AnnotatedVisibility { get; set; }
public string Annotation { get; set; }
public int ApiAvailableSince { get; set; }
+ public int ApiRemovedSince { get; set; }
public string DeprecatedComment { get; set; }
public int? DeprecatedSince { get; set; }
public bool IsAcw { get; set; }
diff --git a/tools/generator/Java.Interop.Tools.Generator.ObjectModel/GenBase.cs b/tools/generator/Java.Interop.Tools.Generator.ObjectModel/GenBase.cs
index 94cf2a022..8568a8de8 100644
--- a/tools/generator/Java.Interop.Tools.Generator.ObjectModel/GenBase.cs
+++ b/tools/generator/Java.Interop.Tools.Generator.ObjectModel/GenBase.cs
@@ -188,6 +188,8 @@ IEnumerable Ancestors ()
public int ApiAvailableSince { get; set; }
+ public int ApiRemovedSince { get; set; }
+
public virtual ClassGen BaseGen => null;
public GenBase BaseSymbol =>
diff --git a/tools/generator/Java.Interop.Tools.Generator.ObjectModel/MethodBase.cs b/tools/generator/Java.Interop.Tools.Generator.ObjectModel/MethodBase.cs
index 8eb5c71da..4f548c729 100644
--- a/tools/generator/Java.Interop.Tools.Generator.ObjectModel/MethodBase.cs
+++ b/tools/generator/Java.Interop.Tools.Generator.ObjectModel/MethodBase.cs
@@ -16,6 +16,7 @@ protected MethodBase (GenBase declaringType)
public string AnnotatedVisibility { get; set; }
public string Annotation { get; internal set; }
public int ApiAvailableSince { get; set; }
+ public int ApiRemovedSince { get; set; }
public string AssemblyName { get; set; }
public GenBase DeclaringType { get; }
public string Deprecated { get; set; }
diff --git a/tools/generator/SourceWriters/Attributes/UnsupportedOSPlatformAttr.cs b/tools/generator/SourceWriters/Attributes/UnsupportedOSPlatformAttr.cs
new file mode 100644
index 000000000..27c789c4f
--- /dev/null
+++ b/tools/generator/SourceWriters/Attributes/UnsupportedOSPlatformAttr.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xamarin.SourceWriter;
+
+namespace generator.SourceWriters
+{
+ public class UnsupportedOSPlatformAttr : AttributeWriter
+ {
+ public int Version { get; }
+
+ public UnsupportedOSPlatformAttr (int version) => Version = version;
+
+ public override void WriteAttribute (CodeWriter writer)
+ {
+ writer.WriteLine ($"[global::System.Runtime.Versioning.UnsupportedOSPlatformAttribute (\"android{Version}.0\")]");
+ }
+ }
+}
diff --git a/tools/generator/SourceWriters/Extensions/SourceWriterExtensions.cs b/tools/generator/SourceWriters/Extensions/SourceWriterExtensions.cs
index 7170f74d0..bbc1ca4f5 100644
--- a/tools/generator/SourceWriters/Extensions/SourceWriterExtensions.cs
+++ b/tools/generator/SourceWriters/Extensions/SourceWriterExtensions.cs
@@ -12,6 +12,8 @@ namespace generator.SourceWriters
{
public static class SourceWriterExtensions
{
+ const int MINIMUM_API_LEVEL = 21;
+
public static void AddField (TypeWriter tw, GenBase type, Field field, CodeGenerationOptions opt)
{
if (field.NeedsProperty)
@@ -306,16 +308,26 @@ public static void AddParameterListCallArgs (List body, ParameterList pa
}
public static void AddSupportedOSPlatform (List attributes, ApiVersionsSupport.IApiAvailability member, CodeGenerationOptions opt)
- => AddSupportedOSPlatform (attributes, member.ApiAvailableSince, opt);
+ {
+ AddSupportedOSPlatform (attributes, member.ApiAvailableSince, opt);
+ AddUnsupportedOSPlatform (attributes, member.ApiRemovedSince, opt);
+ }
public static void AddSupportedOSPlatform (List attributes, int since, CodeGenerationOptions opt)
{
// There's no sense in writing say 'android15' because we do not support older APIs,
// so those APIs will be available in all of our versions.
- if (since > 21 && opt.CodeGenerationTarget == Xamarin.Android.Binder.CodeGenerationTarget.XAJavaInterop1)
+ if (since > MINIMUM_API_LEVEL && opt.CodeGenerationTarget == Xamarin.Android.Binder.CodeGenerationTarget.XAJavaInterop1)
attributes.Add (new SupportedOSPlatformAttr (since));
}
+ public static void AddUnsupportedOSPlatform (List attributes, int since, CodeGenerationOptions opt)
+ {
+ // Here it makes sense to still write 'android15' because it will be missing in later versions like `android35`.
+ if (since > 0 && opt.CodeGenerationTarget == CodeGenerationTarget.XAJavaInterop1)
+ attributes.Add (new UnsupportedOSPlatformAttr (since));
+ }
+
public static void AddObsolete (List attributes, string message, CodeGenerationOptions opt, bool forceDeprecate = false, bool isError = false, int? deprecatedSince = null)
{
// Bail if we're not obsolete
@@ -336,7 +348,7 @@ static bool AddObsoletedOSPlatformAttribute (List attributes, s
return false;
// If it was obsoleted in a version earlier than we support (like 15), use a regular [Obsolete] instead
- if (!deprecatedSince.HasValue || deprecatedSince <= 21)
+ if (!deprecatedSince.HasValue || deprecatedSince <= MINIMUM_API_LEVEL)
return false;
// This is the default Android message, but it isn't useful so remove it