Skip to content

Commit

Permalink
Add [SupportedOSPlatform] attributes to assemblies using ApiSince.
Browse files Browse the repository at this point in the history
  • Loading branch information
jpobst committed Jan 7, 2021
1 parent 7574f16 commit 6c2e1a4
Show file tree
Hide file tree
Showing 15 changed files with 102 additions and 0 deletions.
27 changes: 27 additions & 0 deletions tests/generator-Tests/Unit-Tests/CodeGeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -215,12 +215,39 @@ public void WriteDuplicateInterfaceEventArgs ()

Assert.AreEqual (GetExpected (nameof (WriteDuplicateInterfaceEventArgs)), writer.ToString ().NormalizeLineEndings ());
}

[Test]
public void SupportedOSPlatform ()
{
// We do not write [SupportedOSPlatform] for JavaInterop, only XAJavaInterop
var klass = SupportTypeBuilder.CreateClass ("java.code.MyClass", options);
klass.ApiAvailableSince = 30;

generator.Context.ContextTypes.Push (klass);
generator.WriteType (klass, string.Empty, new GenerationInfo ("", "", "MyAssembly"));
generator.Context.ContextTypes.Pop ();

StringAssert.DoesNotContain ("[global::System.Runtime.Versioning.SupportedOSPlatformAttribute (\"android30.0\")]", builder.ToString (), "Should contain SupportedOSPlatform!");
}
}

[TestFixture]
class XAJavaInteropCodeGeneratorTests : CodeGeneratorTests
{
protected override CodeGenerationTarget Target => CodeGenerationTarget.XAJavaInterop1;

[Test]
public void SupportedOSPlatform ()
{
var klass = SupportTypeBuilder.CreateClass ("java.code.MyClass", options);
klass.ApiAvailableSince = 30;

generator.Context.ContextTypes.Push (klass);
generator.WriteType (klass, string.Empty, new GenerationInfo ("", "", "MyAssembly"));
generator.Context.ContextTypes.Pop ();

StringAssert.Contains ("[global::System.Runtime.Versioning.SupportedOSPlatformAttribute (\"android30.0\")]", builder.ToString (), "Should contain SupportedOSPlatform!");
}
}

[TestFixture]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,21 @@ public void Generate (CodeGenerationOptions opt, GenerationInfo gen_info)
// delegate bool _JniMarshal_PPL_Z (IntPtr jnienv, IntPtr klass, IntPtr a);
foreach (var jni in opt.GetJniMarshalDelegates ())
sw.WriteLine ($"delegate {FromJniType (jni[jni.Length - 1])} {jni} (IntPtr jnienv, IntPtr klass{GetDelegateParameters (jni)});");

// [SupportedOSPlatform] only exists in .NET 5.0+, so we need to generate a
// dummy one so earlier frameworks can compile.
if (opt.CodeGenerationTarget == Xamarin.Android.Binder.CodeGenerationTarget.XAJavaInterop1) {
sw.WriteLine ("#if !NET5_0_OR_GREATER");
sw.WriteLine ("namespace System.Runtime.Versioning {");
sw.WriteLine (" [System.Diagnostics.Conditional(\"NEVER\")]");
sw.WriteLine (" [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Event | AttributeTargets.Method | AttributeTargets.Module | AttributeTargets.Property | AttributeTargets.Struct, AllowMultiple = true, Inherited = false)]");
sw.WriteLine (" internal sealed class SupportedOSPlatformAttribute : Attribute {");
sw.WriteLine (" public SupportedOSPlatformAttribute (string platformName) { }");
sw.WriteLine (" }");
sw.WriteLine ("}");
sw.WriteLine ("#endif");
sw.WriteLine ("");
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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 SupportedOSPlatformAttr : AttributeWriter
{
public int Version { get; }

public SupportedOSPlatformAttr (int version) => Version = version;

public override void WriteAttribute (CodeWriter writer)
{
writer.WriteLine ($"[global::System.Runtime.Versioning.SupportedOSPlatformAttribute (\"android{Version}.0\")]");
}
}
}
4 changes: 4 additions & 0 deletions tools/generator/SourceWriters/BoundAbstractProperty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ public BoundAbstractProperty (GenBase gen, Property property, CodeGenerationOpti
if (property.Getter.IsReturnEnumified)
GetterAttributes.Add (new GeneratedEnumAttr (true));

SourceWriterExtensions.AddSupportedOSPlatform (GetterAttributes, property.Getter, opt);

GetterAttributes.Add (new RegisterAttr (property.Getter.JavaName, property.Getter.JniSignature, property.Getter.GetConnectorNameFull (opt), additionalProperties: property.Getter.AdditionalAttributeString ()));

SourceWriterExtensions.AddMethodCustomAttributes (GetterAttributes, property.Getter);
Expand All @@ -51,6 +53,8 @@ public BoundAbstractProperty (GenBase gen, Property property, CodeGenerationOpti
if (gen.IsGeneratable)
SetterComments.Add ($"// Metadata.xml XPath method reference: path=\"{gen.MetadataXPathReference}/method[@name='{property.Setter.JavaName}'{property.Setter.Parameters.GetMethodXPathPredicate ()}]\"");

SourceWriterExtensions.AddSupportedOSPlatform (SetterAttributes, property.Setter, opt);

SourceWriterExtensions.AddMethodCustomAttributes (SetterAttributes, property.Setter);
SetterAttributes.Add (new RegisterAttr (property.Setter.JavaName, property.Setter.JniSignature, property.Setter.GetConnectorNameFull (opt), additionalProperties: property.Setter.AdditionalAttributeString ()));
}
Expand Down
2 changes: 2 additions & 0 deletions tools/generator/SourceWriters/BoundClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ public BoundClass (ClassGen klass, CodeGenerationOptions opt, CodeGeneratorConte
if (klass.IsDeprecated)
Attributes.Add (new ObsoleteAttr (klass.DeprecatedComment) { WriteAttributeSuffix = true });

SourceWriterExtensions.AddSupportedOSPlatform (Attributes, klass, opt);

Attributes.Add (new RegisterAttr (klass.RawJniName, null, null, true, klass.AdditionalAttributeString ()) { UseGlobal = true, UseShortForm = true });

if (klass.TypeParameters != null && klass.TypeParameters.Any ())
Expand Down
2 changes: 2 additions & 0 deletions tools/generator/SourceWriters/BoundConstructor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public BoundConstructor (ClassGen klass, Ctor constructor, bool useBase, CodeGen
constructor.JavadocInfo?.AddJavadocs (Comments);
Comments.Add (string.Format ("// Metadata.xml XPath constructor reference: path=\"{0}/constructor[@name='{1}'{2}]\"", klass.MetadataXPathReference, klass.JavaSimpleName, constructor.Parameters.GetMethodXPathPredicate ()));

SourceWriterExtensions.AddSupportedOSPlatform (Attributes, constructor, opt);

Attributes.Add (new RegisterAttr (".ctor", constructor.JniSignature, string.Empty, additionalProperties: constructor.AdditionalAttributeString ()));

if (constructor.Deprecated != null)
Expand Down
2 changes: 2 additions & 0 deletions tools/generator/SourceWriters/BoundFieldAsProperty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public BoundFieldAsProperty (GenBase type, Field field, CodeGenerationOptions op
if (field.IsEnumified)
Attributes.Add (new GeneratedEnumAttr ());

SourceWriterExtensions.AddSupportedOSPlatform (Attributes, field, opt);

Attributes.Add (new RegisterAttr (field.JavaName, additionalProperties: field.AdditionalAttributeString ()));

if (field.IsDeprecated)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public BoundInterfaceMethodDeclaration (Method method, string adapter, CodeGener
if (method.IsInterfaceDefaultMethod)
Attributes.Add (new CustomAttr ("[global::Java.Interop.JavaInterfaceDefaultMethod]"));

SourceWriterExtensions.AddSupportedOSPlatform (Attributes, method, opt);

Attributes.Add (new RegisterAttr (method.JavaName, method.JniSignature, method.ConnectorName + ":" + method.GetAdapterName (opt, adapter), additionalProperties: method.AdditionalAttributeString ()));

method.JavadocInfo?.AddJavadocs (Comments);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ public BoundInterfacePropertyDeclaration (GenBase gen, Property property, string
if (property.Getter.GenericArguments?.Any () == true)
GetterAttributes.Add (new CustomAttr (property.Getter.GenericArguments.ToGeneratedAttributeString ()));

SourceWriterExtensions.AddSupportedOSPlatform (GetterAttributes, property.Getter, opt);

GetterAttributes.Add (new RegisterAttr (property.Getter.JavaName, property.Getter.JniSignature, property.Getter.ConnectorName + ":" + property.Getter.GetAdapterName (opt, adapter), additionalProperties: property.Getter.AdditionalAttributeString ()));
}

Expand All @@ -36,6 +38,8 @@ public BoundInterfacePropertyDeclaration (GenBase gen, Property property, string
if (property.Setter.GenericArguments?.Any () == true)
SetterAttributes.Add (new CustomAttr (property.Setter.GenericArguments.ToGeneratedAttributeString ()));

SourceWriterExtensions.AddSupportedOSPlatform (SetterAttributes, property.Setter, opt);

SetterAttributes.Add (new RegisterAttr (property.Setter.JavaName, property.Setter.JniSignature, property.Setter.ConnectorName + ":" + property.Setter.GetAdapterName (opt, adapter), additionalProperties: property.Setter.AdditionalAttributeString ()));
}
}
Expand Down
2 changes: 2 additions & 0 deletions tools/generator/SourceWriters/BoundMethod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ public BoundMethod (GenBase type, Method method, CodeGenerationOptions opt, bool
if (method.IsReturnEnumified)
Attributes.Add (new GeneratedEnumAttr (true));

SourceWriterExtensions.AddSupportedOSPlatform (Attributes, method, opt);

Attributes.Add (new RegisterAttr (method.JavaName, method.JniSignature, method.IsVirtual ? method.GetConnectorNameFull (opt) : string.Empty, additionalProperties: method.AdditionalAttributeString ()));

SourceWriterExtensions.AddMethodCustomAttributes (Attributes, method);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ public BoundMethodAbstractDeclaration (GenBase gen, Method method, CodeGeneratio
if (method.DeclaringType.IsGeneratable)
Comments.Add ($"// Metadata.xml XPath method reference: path=\"{method.GetMetadataXPathReference (method.DeclaringType)}\"");

SourceWriterExtensions.AddSupportedOSPlatform (Attributes, method, opt);

Attributes.Add (new RegisterAttr (method.JavaName, method.JniSignature, method.ConnectorName, additionalProperties: method.AdditionalAttributeString ()));

SourceWriterExtensions.AddMethodCustomAttributes (Attributes, method);
Expand Down
4 changes: 4 additions & 0 deletions tools/generator/SourceWriters/BoundProperty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ public BoundProperty (GenBase gen, Property property, CodeGenerationOptions opt,
if (gen.IsGeneratable)
GetterComments.Add ($"// Metadata.xml XPath method reference: path=\"{gen.MetadataXPathReference}/method[@name='{property.Getter.JavaName}'{property.Getter.Parameters.GetMethodXPathPredicate ()}]\"");

SourceWriterExtensions.AddSupportedOSPlatform (GetterAttributes, property.Getter, opt);

GetterAttributes.Add (new RegisterAttr (property.Getter.JavaName, property.Getter.JniSignature, property.Getter.IsVirtual ? property.Getter.GetConnectorNameFull (opt) : string.Empty, additionalProperties: property.Getter.AdditionalAttributeString ()));

SourceWriterExtensions.AddMethodBody (GetBody, property.Getter, opt);
Expand All @@ -84,6 +86,8 @@ public BoundProperty (GenBase gen, Property property, CodeGenerationOptions opt,
if (gen.IsGeneratable)
SetterComments.Add ($"// Metadata.xml XPath method reference: path=\"{gen.MetadataXPathReference}/method[@name='{property.Setter.JavaName}'{property.Setter.Parameters.GetMethodXPathPredicate ()}]\"");

SourceWriterExtensions.AddSupportedOSPlatform (SetterAttributes, property.Setter, opt);

SourceWriterExtensions.AddMethodCustomAttributes (SetterAttributes, property.Setter);
SetterAttributes.Add (new RegisterAttr (property.Setter.JavaName, property.Setter.JniSignature, property.Setter.IsVirtual ? property.Setter.GetConnectorNameFull (opt) : string.Empty, additionalProperties: property.Setter.AdditionalAttributeString ()));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,15 @@ public static void AddParameterListCallArgs (List<string> body, ParameterList pa
}
}

public static void AddSupportedOSPlatform (List<AttributeWriter> attributes, ApiVersionsSupport.IApiAvailability member, 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 (member.ApiAvailableSince > 21 && opt.CodeGenerationTarget == Xamarin.Android.Binder.CodeGenerationTarget.XAJavaInterop1)
attributes.Add (new SupportedOSPlatformAttr (member.ApiAvailableSince));

}

public static void WriteMethodInvokerBody (CodeWriter writer, Method method, CodeGenerationOptions opt, string contextThis)
{
writer.WriteLine ($"if ({method.EscapedIdName} == IntPtr.Zero)");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public GenericExplicitInterfaceImplementationProperty (Property property, Generi
if (property.Getter.GenericArguments != null && property.Getter.GenericArguments.Any ())
GetterAttributes.Add (new CustomAttr (property.Getter.GenericArguments.ToGeneratedAttributeString ()));

SourceWriterExtensions.AddSupportedOSPlatform (GetterAttributes, property.Getter, opt);

GetterAttributes.Add (new RegisterAttr (property.Getter.JavaName, property.Getter.JniSignature, property.Getter.ConnectorName + ":" + property.Getter.GetAdapterName (opt, adapter), additionalProperties: property.Getter.AdditionalAttributeString ()));

GetBody.Add ($"return {property.Name};");
Expand All @@ -40,6 +42,8 @@ public GenericExplicitInterfaceImplementationProperty (Property property, Generi
if (property.Setter.GenericArguments != null && property.Setter.GenericArguments.Any ())
SetterAttributes.Add (new CustomAttr (property.Setter.GenericArguments.ToGeneratedAttributeString ()));

SourceWriterExtensions.AddSupportedOSPlatform (SetterAttributes, property.Setter, opt);

SetterAttributes.Add (new RegisterAttr (property.Setter.JavaName, property.Setter.JniSignature, property.Setter.ConnectorName + ":" + property.Setter.GetAdapterName (opt, adapter), additionalProperties: property.Setter.AdditionalAttributeString ()));

// Temporarily rename the parameter to "value"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ public InterfaceMemberAlternativeClass (InterfaceGen iface, CodeGenerationOption

UsePriorityOrder = true;

SourceWriterExtensions.AddSupportedOSPlatform (Attributes, iface, opt);

Attributes.Add (new RegisterAttr (iface.RawJniName, noAcw: true, additionalProperties: iface.AdditionalAttributeString ()) { AcwLast = true });

if (should_obsolete)
Expand Down

0 comments on commit 6c2e1a4

Please sign in to comment.