Skip to content

Commit

Permalink
[generator][dotnet] Add support for [Uns|S]upportedOSPlatformAttribute
Browse files Browse the repository at this point in the history
This moves our current/legacy attributes to the ones added in dotnet 5 [1].

Short Forms (only in bindings)

| Old                                   | New                                 |
|---------------------------------------|-------------------------------------|
| [iOS (7,0)]                           | [SupportedOSPlatform ("ios7.0")]    |
| [NoIOS]                               | [UnsupportedOSPlatform ("ios")]     |

Long Forms

| Old                                   | New                                 |
|---------------------------------------|-------------------------------------|
| [Introduced (PlatformName.iOS, 7,0)]  | [SupportedOSPlatform ("ios7.0")]    |
| [Obsoleted (PlatformName.iOS, 12,1)]  | [Obsolete (...)]                    |
| [Deprecated (PlatformName.iOS, 14,3)] | [UnsupportedOSPlatform ("ios14.3")] |
| [Unavailable (PlatformName.iOS)]      | [UnsupportedOSPlatform ("ios")]     |

Other changes

* `[SupportedOSPlatform]` and `[UnsupportedOSPlatform]` are not allowed on `interface` [2] which means they cannot be used for protocols. This is currently handled by inlining the existing attributes on all members.
* `[ObsoletedInOSPlatform]` was removed in net5 RC. This PR is now mapping the existing attributes to `[Obsolote]`, however multiple ones cannot be added so they need to be platform specific.

Still Missing

* [ ] Generator deduplication of type/members attributes for interfaces (due to [2])
* [ ] Manual bindings
* [ ] Introspection tests updates

References

* [1] xamarin#10170
* [2] dotnet/runtime#47599
* [3] dotnet/runtime#47601
  • Loading branch information
spouliot committed Feb 4, 2021
1 parent 43a294f commit 4a510e7
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 0 deletions.
71 changes: 71 additions & 0 deletions src/ObjCRuntime/PlatformAvailability2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,76 @@ internal AvailabilityBaseAttribute (
public override string ToString ()
{
var builder = new StringBuilder ();
#if NET
switch (AvailabilityKind) {
case AvailabilityKind.Introduced:
builder.Append ("[SupportedOSPlatform (\"");
break;
case AvailabilityKind.Obsoleted:
switch (Platform) {
case PlatformName.iOS:
builder.AppendLine ("#if __IOS__");
break;
case PlatformName.TvOS:
builder.AppendLine ("#if __TVOS__");
break;
case PlatformName.WatchOS:
builder.AppendLine ("#if __WATCHOS__");
break;
case PlatformName.MacOSX:
builder.AppendLine ("#if __MACOS__");
break;
case PlatformName.MacCatalyst:
builder.AppendLine ("#if __MACCATALYST__");
break;
}
builder.Append ("[Obsolete (\"Starting with ");
break;
case AvailabilityKind.Deprecated:
case AvailabilityKind.Unavailable:
builder.Append ("[UnsupportedOSPlatform (\"");
break;
}

switch (Platform) {
case PlatformName.iOS:
builder.Append ("ios");
break;
case PlatformName.TvOS:
builder.Append ("tvos");
break;
case PlatformName.WatchOS:
builder.Append ("watchos");
break;
case PlatformName.MacOSX:
builder.Append ("macos"); // no 'x'
break;
case PlatformName.MacCatalyst:
builder.Append ("maccatalyst");
break;
}

if (Version != null) {
builder.Append (Version.Major).Append ('.').Append (Version.Minor);
if (Version.Build >= 0)
builder.Append ('.').Append (Version.Build);
}

switch (AvailabilityKind) {
case AvailabilityKind.Obsoleted:
if (!String.IsNullOrEmpty (Message))
builder.Append (' ').Append (Message);
// TODO add a URL (wiki?) and DiagnosticId (one per platform?) for documentation
builder.AppendLine ("\", DiagnosticId = \"BI1234\", UrlFormat = \"https://github.com/xamarin/xamarin-macios/wiki/Obsolete\")]");
builder.Append ("#endif");
break;
case AvailabilityKind.Introduced:
case AvailabilityKind.Deprecated:
case AvailabilityKind.Unavailable:
builder.Append ("\")]");
break;
}
#else
builder.AppendFormat ("[{0} ({1}.{2}", AvailabilityKind, nameof (PlatformName), Platform);

if (Version != null) {
Expand All @@ -107,6 +177,7 @@ public override string ToString ()
builder.AppendFormat (", message: \"{0}\"", Message.Replace ("\"", "\"\""));

builder.Append (")]");
#endif
return builder.ToString ();
}
}
Expand Down
13 changes: 13 additions & 0 deletions src/generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,9 @@ public NamespaceManager (BindingTouch binding_touch, string customObjCRuntimeNS,
ImplicitNamespaces.Add ("System.Diagnostics");
ImplicitNamespaces.Add ("System.Diagnostics.CodeAnalysis");
ImplicitNamespaces.Add ("System.ComponentModel");
#if NET
ImplicitNamespaces.Add ("System.Runtime.Versioning");
#endif
ImplicitNamespaces.Add ("System.Threading.Tasks");
ImplicitNamespaces.Add ("CoreFoundation");
ImplicitNamespaces.Add ("Foundation");
Expand Down Expand Up @@ -5682,7 +5685,13 @@ void GenerateProtocolTypes (Type type, string class_visibility, string TypeName,
var optionalInstanceProperties = allProtocolProperties.Where ((v) => !IsRequired (v) && !AttributeManager.HasAttribute<StaticAttribute> (v));
var requiredInstanceAsyncMethods = requiredInstanceMethods.Where (m => AttributeManager.HasAttribute<AsyncAttribute> (m)).ToList ();

#if NET
// [SupportedOSPlatform] cannot be used on interface - https://github.com/dotnet/runtime/issues/47599
// instead we'll generate them on the members
PrintAttributes (type, platform:false, preserve:true, advice:true);
#else
PrintAttributes (type, platform:true, preserve:true, advice:true);
#endif
print ("[Protocol (Name = \"{1}\", WrapperType = typeof ({0}Wrapper){2}{3})]",
TypeName,
protocol_name,
Expand Down Expand Up @@ -5822,6 +5831,10 @@ void GenerateProtocolTypes (Type type, string class_visibility, string TypeName,
var mod = string.Empty;

PrintMethodAttributes (minfo);
#if NET
// TODO - generate them only if they do not exists on the member
PrintPlatformAttributes (type);
#endif
PrintPlatformAttributes (mi);
print_generated_code ();
PrintDelegateProxy (minfo);
Expand Down

0 comments on commit 4a510e7

Please sign in to comment.