Merge remote-tracking branch 'origin/main' into bump-main-in-net8.0-2023-03-14
This commit is contained in:
Коммит
226a5f198f
|
@ -2,5 +2,14 @@
|
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<!-- app.sandbox is required by the App Store. See https://developer.apple.com/documentation/security/app_sandbox-->
|
||||
<!-- <key>com.apple.security.app-sandbox</key>
|
||||
<true/>
|
||||
-->
|
||||
|
||||
<!-- When sandbox is enabled, this value is required if app was created with Blazor.-->
|
||||
<!--<key>com.apple.security.network.client</key>
|
||||
<true/>
|
||||
-->
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -10,6 +10,15 @@
|
|||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<!-- The App store requires that ITSAppUsesNonExemptEncryption to be set -->
|
||||
<!-- Please consult https://developer.apple.com/documentation/bundleresources/information_property_list/itsappusesnonexemptencryption -->
|
||||
<!-- <key>ITSAppUsesNonExemptEncryption</key> -->
|
||||
<!-- Please indicate <true/> or <false/> here. -->
|
||||
|
||||
<!-- Specify the category for your app here. -->
|
||||
<!-- Please consult https://developer.apple.com/documentation/bundleresources/information_property_list/lsapplicationcategorytype -->
|
||||
<!-- <key>LSApplicationCategoryType</key> -->
|
||||
<!-- <string>public.app-category.YOUR-CATEGORY-HERE</string> -->
|
||||
<key>UIDeviceFamily</key>
|
||||
<array>
|
||||
<integer>2</integer>
|
||||
|
|
|
@ -1,11 +1,53 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0-maccatalyst</TargetFramework>
|
||||
<RuntimeIdentifier>maccatalyst-x64</RuntimeIdentifier>
|
||||
<RootNamespace Condition="'$(name)' != '$(name{-VALUE-FORMS-}safe_namespace)'">MacCatalystApp1</RootNamespace>
|
||||
<!-- The default runtime is maccatalyst-x64, except in Release config, in which case the default is maccatalyst-x64;maccatalyst-arm64.
|
||||
When specifying both architectures, use the plural <RuntimeIdentifiers> instead of the singular <RuntimeIdentifer>.
|
||||
The App Store will NOT accept apps with ONLY maccatalyst-arm64 indicated;
|
||||
either BOTH runtimes must be indicated or ONLY macatalyst-x64. -->
|
||||
<!-- ex. <RuntimeIdentifiers>maccatalyst-x64;maccatalyst-arm64</RuntimeIdentifiers> -->
|
||||
<OutputType>Exe</OutputType>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>true</ImplicitUsings>
|
||||
<RootNamespace Condition="'$(name)' != '$(name{-VALUE-FORMS-}safe_namespace)'">MacCatalystApp1</RootNamespace>
|
||||
<SupportedOSPlatformVersion>minOSVersion</SupportedOSPlatformVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Notes about the values set below:
|
||||
1. For macOS it's possible to sign both the app bundle (EnableCodesigning=true) and the package (*.pkg) (EnablePackageSigning=true),
|
||||
and these are signed separately and with different certificates.
|
||||
CodesignKey: this is the signing key used for the app bundle
|
||||
PackageSigningKey: this is the signing key used for the package
|
||||
2. Publishing to the App Store requires signing both the app bundle and the package.
|
||||
Must be 'Apple Distribution: ...' for the app bundle. Note that apps signed like this will not execute locally.
|
||||
They have to be published to the App Store and then downloaded (Apple will resign the app with a different signing identity that allows for local execution).
|
||||
Must be '3rd Party Mac Developer Installer: ...' for the pkg
|
||||
3. Publishing outside of the App Store (i.e. only notarizing) requires:
|
||||
Must be 'Developer ID Application: ...' for the app bundle
|
||||
Must be 'Developer ID Installer: ...' for the pkg
|
||||
4. During development, use the 'Apple Development: ...' signing key (typically to verify that the app works when is signed and entitlements are enforced).
|
||||
5. Depending on the entitlements the app needs, a specific provisioning profile (CodesignProvision) might be needed.
|
||||
6. UseHardenedRuntime must be set to true when app sandbox is enabled in Info.plist.
|
||||
-->
|
||||
<!--
|
||||
For Debug: (Note: Replace placeholder information before building)
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
|
||||
<CodesignKey>Apple Development: YOURNAME (*******)</CodesignKey>
|
||||
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
|
||||
<CodesignProvision>YOUR PROFILE NAME</CodesignProvision>
|
||||
</PropertyGroup>
|
||||
-->
|
||||
<!--
|
||||
For Release: (Note: Replace placeholder information before building)
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||
<EnableCodeSigning>True</EnableCodeSigning>
|
||||
<ProvisionType>Manual</ProvisionType>
|
||||
<CreatePackage>true</CreatePackage>
|
||||
<EnablePackageSigning>true</EnablePackageSigning>
|
||||
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
|
||||
<CodesignKey>Apple Development: YOURNAME (*******)</CodesignKey>
|
||||
<CodesignProvision>YOUR PROFILE NAME</CodesignProvision>
|
||||
<PackageSigningKey>3rd Party Mac Developer Installer: YOURNAME (*******)</PackageSigningKey>
|
||||
<UseHardenedRuntime>true</UseHardenedRuntime>
|
||||
</PropertyGroup>-->
|
||||
</Project>
|
||||
|
|
|
@ -50,6 +50,8 @@
|
|||
* https://github.com/dotnet/sdk/blob/c5a58bc6c3eb2b236b314e6d17a89a537459890c/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets#L102
|
||||
-->
|
||||
<_IsTrimmingEnabled>true</_IsTrimmingEnabled>
|
||||
<!-- The GRCF property is contingent upon the HasRuntimeOutput property, which is only defined for executable projects. So, explicitly define GRCF for extension projects to avoid warnings at build time. -->
|
||||
<GenerateRuntimeConfigurationFiles Condition="'$(IsAppExtension)' == 'true'">true</GenerateRuntimeConfigurationFiles>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Set the default RuntimeIdentifier if not already specified. -->
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 564433f35c8ab6b7bb0709f83e1b81a89c406956
|
||||
Subproject commit b85fb26cc07f5103a24ce41dc0819d15e6a5dbe6
|
|
@ -23,74 +23,12 @@ public static class AttributeConversionManager {
|
|||
|
||||
Func<string> unknownFormatError = () => $"Unknown format for old style availability attribute {attribute.GetAttributeType ().FullName} {attribute.ConstructorArguments.Count} {createErrorMessage ()}";
|
||||
|
||||
object? [] ctorValues;
|
||||
Type [] ctorTypes;
|
||||
|
||||
switch (attribute.ConstructorArguments.Count) {
|
||||
case 2:
|
||||
if (constructorArguments [0] is byte &&
|
||||
constructorArguments [1] is byte) {
|
||||
#if NET
|
||||
ctorValues = new object? [] { (byte) platform, (int) (byte) constructorArguments [0], (int) (byte) constructorArguments [1], null };
|
||||
ctorTypes = new [] { AttributeFactory.PlatformEnum, typeof (int), typeof (int), typeof (string) };
|
||||
#else
|
||||
ctorValues = new object? [] { (byte) platform, (int) (byte) constructorArguments [0], (int) (byte) constructorArguments [1], (byte) 0xff, null };
|
||||
ctorTypes = new [] { AttributeFactory.PlatformEnum, typeof (int), typeof (int), AttributeFactory.PlatformArch, typeof (string) };
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
throw new NotImplementedException (unknownFormatError ());
|
||||
case 3:
|
||||
if (constructorArguments [0] is byte &&
|
||||
constructorArguments [1] is byte &&
|
||||
constructorArguments [2] is byte) {
|
||||
#if NET
|
||||
ctorValues = new object? [] { (byte) platform, (int) (byte) constructorArguments [0], (int) (byte) constructorArguments [1], (int) (byte) constructorArguments [2], null };
|
||||
ctorTypes = new [] { AttributeFactory.PlatformEnum, typeof (int), typeof (int), typeof (int), typeof (string) };
|
||||
#else
|
||||
ctorValues = new object? [] { (byte) platform, (int) (byte) constructorArguments [0], (int) (byte) constructorArguments [1], (int) (byte) constructorArguments [2], (byte) 0xff, null };
|
||||
ctorTypes = new [] { AttributeFactory.PlatformEnum, typeof (int), typeof (int), typeof (int), AttributeFactory.PlatformArch, typeof (string) };
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
#if !NET
|
||||
if (constructorArguments [0] is byte &&
|
||||
constructorArguments [1] is byte &&
|
||||
constructorArguments [2] is bool) {
|
||||
byte arch = (bool) constructorArguments [2] ? (byte) 2 : (byte) 0xff;
|
||||
ctorValues = new object? [] { (byte) platform, (int) (byte) constructorArguments [0], (int) (byte) constructorArguments [1], arch, null };
|
||||
ctorTypes = new [] { AttributeFactory.PlatformEnum, typeof (int), typeof (int), AttributeFactory.PlatformArch, typeof (string) };
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
throw new NotImplementedException (unknownFormatError ());
|
||||
#if !NET
|
||||
case 4:
|
||||
if (constructorArguments [0] is byte &&
|
||||
constructorArguments [1] is byte &&
|
||||
constructorArguments [2] is byte &&
|
||||
constructorArguments [3] is bool) {
|
||||
byte arch = (bool) constructorArguments [3] ? (byte) 2 : (byte) 0xff;
|
||||
ctorValues = new object? [] { (byte) platform, (int) (byte) constructorArguments [0], (int) (byte) constructorArguments [1], (int) (byte) constructorArguments [2], arch, null };
|
||||
ctorTypes = new [] { AttributeFactory.PlatformEnum, typeof (int), typeof (int), typeof (int), AttributeFactory.PlatformArch, typeof (string) };
|
||||
break;
|
||||
}
|
||||
if (constructorArguments [0] is byte &&
|
||||
constructorArguments [1] is byte &&
|
||||
constructorArguments [2] is byte &&
|
||||
constructorArguments [3] is byte /* ObjCRuntime.PlatformArchitecture */) {
|
||||
ctorValues = new object? [] { (byte) platform, (int) (byte) constructorArguments [0], (int) (byte) constructorArguments [1], (int) (byte) constructorArguments [2], constructorArguments [3], null };
|
||||
ctorTypes = new [] { AttributeFactory.PlatformEnum, typeof (int), typeof (int), typeof (int), AttributeFactory.PlatformArch, typeof (string) };
|
||||
break;
|
||||
}
|
||||
|
||||
throw new NotImplementedException (unknownFormatError ());
|
||||
#endif
|
||||
default:
|
||||
throw new NotImplementedException ($"Unknown count {attribute.ConstructorArguments.Count} {createErrorMessage ()}");
|
||||
if (AttributeFactory.ConstructorArguments.TryGetCtorArguments (
|
||||
constructorArguments, platform, out var ctorValues, out var ctorTypes)) {
|
||||
return AttributeFactory.CreateNewAttribute<IntroducedAttribute> (ctorTypes!, ctorValues!);
|
||||
}
|
||||
|
||||
return AttributeFactory.CreateNewAttribute (AttributeFactory.IntroducedAttributeType, ctorTypes, ctorValues);
|
||||
throw new NotImplementedException (unknownFormatError ());
|
||||
}
|
||||
|
||||
struct ParsedAvailabilityInfo {
|
||||
|
@ -176,22 +114,22 @@ public static class AttributeConversionManager {
|
|||
switch (arg.MemberName) {
|
||||
case "Introduced": {
|
||||
ParsedAvailabilityInfo availInfo = DetermineOldAvailabilityVersion (arg);
|
||||
yield return AttributeFactory.CreateNewIntroducedAttribute (availInfo.Platform, availInfo.Major, availInfo.Minor, message: message);
|
||||
yield return AttributeFactory.CreateNewAttribute<IntroducedAttribute> (availInfo.Platform, availInfo.Major, availInfo.Minor, message: message);
|
||||
continue;
|
||||
}
|
||||
case "Deprecated": {
|
||||
ParsedAvailabilityInfo availInfo = DetermineOldAvailabilityVersion (arg);
|
||||
yield return AttributeFactory.CreateDeprecatedAttribute (availInfo.Platform, availInfo.Major, availInfo.Minor, message: message);
|
||||
yield return AttributeFactory.CreateNewAttribute<DeprecatedAttribute> (availInfo.Platform, availInfo.Major, availInfo.Minor, message: message);
|
||||
continue;
|
||||
}
|
||||
case "Obsoleted": {
|
||||
ParsedAvailabilityInfo availInfo = DetermineOldAvailabilityVersion (arg);
|
||||
yield return AttributeFactory.CreateObsoletedAttribute (availInfo.Platform, availInfo.Major, availInfo.Minor, message: message);
|
||||
yield return AttributeFactory.CreateNewAttribute<ObsoletedAttribute> (availInfo.Platform, availInfo.Major, availInfo.Minor, message: message);
|
||||
continue;
|
||||
}
|
||||
case "Unavailable": {
|
||||
ParsedAvailabilityInfo availInfo = DetermineOldAvailabilityVersion (arg);
|
||||
yield return AttributeFactory.CreateUnavailableAttribute (availInfo.Platform, message: message);
|
||||
yield return AttributeFactory.CreateNewAttribute<UnavailableAttribute> (availInfo.Platform, message: message);
|
||||
continue;
|
||||
}
|
||||
case "Message":
|
||||
|
|
|
@ -0,0 +1,179 @@
|
|||
using System;
|
||||
using ObjCRuntime;
|
||||
|
||||
#nullable enable
|
||||
|
||||
public static partial class AttributeFactory {
|
||||
public static readonly Type PlatformEnum = typeof (PlatformName);
|
||||
#if !NET
|
||||
public static readonly Type PlatformArch = typeof (PlatformArchitecture);
|
||||
#endif
|
||||
|
||||
public readonly struct ConstructorArguments {
|
||||
readonly PlatformName platform;
|
||||
readonly int? major;
|
||||
readonly int? minor;
|
||||
readonly int? build;
|
||||
readonly string? message;
|
||||
|
||||
public ConstructorArguments (PlatformName platformIn, int majorIn, int minorIn, int buildIn, string? messageIn)
|
||||
{
|
||||
platform = platformIn;
|
||||
major = majorIn;
|
||||
minor = minorIn;
|
||||
build = buildIn;
|
||||
message = messageIn;
|
||||
}
|
||||
|
||||
public ConstructorArguments (PlatformName platformIn, int majorIn, int minorIn, string? messageIn)
|
||||
{
|
||||
platform = platformIn;
|
||||
major = majorIn;
|
||||
minor = minorIn;
|
||||
build = null;
|
||||
message = messageIn;
|
||||
}
|
||||
|
||||
public ConstructorArguments (PlatformName platformIn, string? messageIn)
|
||||
{
|
||||
platform = platformIn;
|
||||
major = null;
|
||||
minor = null;
|
||||
build = null;
|
||||
message = messageIn;
|
||||
}
|
||||
|
||||
#if NET
|
||||
public object? [] GetCtorValues ()
|
||||
{
|
||||
if (major is null || minor is null) {
|
||||
return new object? [] { (byte) platform, message };
|
||||
}
|
||||
|
||||
if (build is null)
|
||||
return new object? [] { (byte) platform, major, minor, message };
|
||||
return new object? [] { (byte) platform, major, minor, build, message };
|
||||
}
|
||||
|
||||
public Type [] GetCtorTypes ()
|
||||
{
|
||||
if (major is null || minor is null) {
|
||||
return new [] { PlatformEnum, typeof (string) };
|
||||
}
|
||||
|
||||
if (build is null)
|
||||
return new [] { PlatformEnum, typeof (int), typeof (int), typeof (string) };
|
||||
return new [] { PlatformEnum, typeof (int), typeof (int), typeof (int), typeof (string) };
|
||||
}
|
||||
|
||||
public static bool TryGetCtorArguments (object [] constructorArguments, PlatformName platform, out object? []? ctorValues, out Type []? ctorTypes)
|
||||
{
|
||||
ctorValues = null;
|
||||
ctorTypes = null;
|
||||
|
||||
switch (constructorArguments.Length) {
|
||||
case 2:
|
||||
if (constructorArguments [0] is byte &&
|
||||
constructorArguments [1] is byte) {
|
||||
ctorValues = new object? [] { (byte) platform, (int) (byte) constructorArguments [0], (int) (byte) constructorArguments [1], null };
|
||||
ctorTypes = new [] { PlatformEnum, typeof (int), typeof (int), typeof (string) };
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
case 3:
|
||||
if (constructorArguments [0] is byte &&
|
||||
constructorArguments [1] is byte &&
|
||||
constructorArguments [2] is byte) {
|
||||
ctorValues = new object? [] { (byte) platform, (int) (byte) constructorArguments [0], (int) (byte) constructorArguments [1], (int) (byte) constructorArguments [2], null };
|
||||
ctorTypes = new [] { PlatformEnum, typeof (int), typeof (int), typeof (int), typeof (string) };
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#else
|
||||
public object? [] GetCtorValues ()
|
||||
{
|
||||
if (major is null || minor is null) {
|
||||
return new object? [] { (byte) platform, (byte) 0xff, message };
|
||||
}
|
||||
|
||||
if (build is null)
|
||||
return new object? [] { (byte) platform, major, minor, (byte) 0xff, message };
|
||||
return new object? [] { (byte) platform, major, minor, build, (byte) 0xff, message };
|
||||
}
|
||||
|
||||
public Type [] GetCtorTypes ()
|
||||
{
|
||||
if (major is null || minor is null) {
|
||||
return new [] { PlatformEnum, PlatformArch, typeof (string) };
|
||||
}
|
||||
|
||||
if (build is null)
|
||||
return new [] { PlatformEnum, typeof (int), typeof (int), PlatformArch, typeof (string) };
|
||||
return new [] { PlatformEnum, typeof (int), typeof (int), typeof (int), PlatformArch, typeof (string) };
|
||||
}
|
||||
|
||||
public static bool TryGetCtorArguments (object [] constructorArguments, PlatformName platform, out object? []? ctorValues, out Type []? ctorTypes)
|
||||
{
|
||||
ctorValues = null;
|
||||
ctorTypes = null;
|
||||
|
||||
switch (constructorArguments.Length) {
|
||||
case 2:
|
||||
if (constructorArguments [0] is byte &&
|
||||
constructorArguments [1] is byte) {
|
||||
ctorValues = new object? [] { (byte) platform, (int) (byte) constructorArguments [0], (int) (byte) constructorArguments [1], (byte) 0xff, null };
|
||||
ctorTypes = new [] { PlatformEnum, typeof (int), typeof (int), PlatformArch, typeof (string) };
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
case 3:
|
||||
if (constructorArguments [0] is byte &&
|
||||
constructorArguments [1] is byte &&
|
||||
constructorArguments [2] is byte) {
|
||||
ctorValues = new object? [] { (byte) platform, (int) (byte) constructorArguments [0], (int) (byte) constructorArguments [1], (int) (byte) constructorArguments [2], (byte) 0xff, null };
|
||||
ctorTypes = new [] { PlatformEnum, typeof (int), typeof (int), typeof (int), PlatformArch, typeof (string) };
|
||||
return true;
|
||||
}
|
||||
|
||||
if (constructorArguments [0] is byte &&
|
||||
constructorArguments [1] is byte &&
|
||||
constructorArguments [2] is bool) {
|
||||
byte arch = (bool) constructorArguments [2] ? (byte) 2 : (byte) 0xff;
|
||||
ctorValues = new object? [] { (byte) platform, (int) (byte) constructorArguments [0], (int) (byte) constructorArguments [1], arch, null };
|
||||
ctorTypes = new [] { PlatformEnum, typeof (int), typeof (int), PlatformArch, typeof (string) };
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case 4:
|
||||
if (constructorArguments [0] is byte &&
|
||||
constructorArguments [1] is byte &&
|
||||
constructorArguments [2] is byte &&
|
||||
constructorArguments [3] is bool) {
|
||||
byte arch = (bool) constructorArguments [3] ? (byte) 2 : (byte) 0xff;
|
||||
ctorValues = new object? [] { (byte) platform, (int) (byte) constructorArguments [0], (int) (byte) constructorArguments [1], (int) (byte) constructorArguments [2], arch, null };
|
||||
ctorTypes = new [] { PlatformEnum, typeof (int), typeof (int), typeof (int), PlatformArch, typeof (string) };
|
||||
return true;
|
||||
}
|
||||
if (constructorArguments [0] is byte &&
|
||||
constructorArguments [1] is byte &&
|
||||
constructorArguments [2] is byte &&
|
||||
constructorArguments [3] is byte /* ObjCRuntime.PlatformArchitecture */) {
|
||||
ctorValues = new object? [] { (byte) platform, (int) (byte) constructorArguments [0], (int) (byte) constructorArguments [1], (int) (byte) constructorArguments [2], constructorArguments [3], null };
|
||||
ctorTypes = new [] { PlatformEnum, typeof (int), typeof (int), typeof (int), PlatformArch, typeof (string) };
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -1,81 +1,172 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ObjCRuntime;
|
||||
|
||||
#nullable enable
|
||||
|
||||
public static class AttributeFactory {
|
||||
public static readonly Type PlatformEnum = typeof (PlatformName);
|
||||
#if !NET
|
||||
public static readonly Type PlatformArch = typeof (PlatformArchitecture);
|
||||
#endif
|
||||
public static partial class AttributeFactory {
|
||||
|
||||
public static readonly Type IntroducedAttributeType = typeof (IntroducedAttribute);
|
||||
public static readonly Type UnavailableAttributeType = typeof (UnavailableAttribute);
|
||||
public static readonly Type ObsoletedAttributeType = typeof (ObsoletedAttribute);
|
||||
public static readonly Type DeprecatedAttributeType = typeof (DeprecatedAttribute);
|
||||
|
||||
public static Attribute CreateNewAttribute (Type attribType, Type [] ctorTypes, object? [] ctorValues)
|
||||
public static T CreateNewAttribute<T> (Type [] ctorTypes, object? [] ctorValues)
|
||||
where T : Attribute
|
||||
{
|
||||
var attribType = typeof (T);
|
||||
var ctor = attribType.GetConstructor (ctorTypes);
|
||||
if (ctor is null)
|
||||
throw ErrorHelper.CreateError (1058, attribType.FullName);
|
||||
|
||||
return (Attribute) ctor.Invoke (ctorValues);
|
||||
return (T) ctor.Invoke (ctorValues);
|
||||
}
|
||||
|
||||
static Attribute CreateMajorMinorAttribute (Type type, PlatformName platform, int major, int minor, string? message)
|
||||
public static T CreateNewAttribute<T> (PlatformName platform, int major, int minor, string? message = null)
|
||||
where T : Attribute
|
||||
{
|
||||
#if NET
|
||||
var ctorValues = new object? [] { (byte) platform, major, minor, message };
|
||||
var ctorTypes = new [] { PlatformEnum, typeof (int), typeof (int), typeof (string) };
|
||||
#else
|
||||
var ctorValues = new object? [] { (byte) platform, major, minor, (byte) 0xff, message };
|
||||
var ctorTypes = new [] { PlatformEnum, typeof (int), typeof (int), PlatformArch, typeof (string) };
|
||||
#endif
|
||||
return CreateNewAttribute (type, ctorTypes, ctorValues);
|
||||
var args = new ConstructorArguments (platform, major, minor, message);
|
||||
return CreateNewAttribute<T> (args.GetCtorTypes (), args.GetCtorValues ());
|
||||
}
|
||||
|
||||
static Attribute CreateUnspecifiedAttribute (Type type, PlatformName platform, string? message)
|
||||
public static T CreateNewAttribute<T> (PlatformName platform, int major, int minor, int build, string? message = null)
|
||||
where T : Attribute
|
||||
{
|
||||
#if NET
|
||||
var ctorValues = new object? [] { (byte) platform, message };
|
||||
var ctorTypes = new [] { PlatformEnum, typeof (string) };
|
||||
#else
|
||||
var ctorValues = new object? [] { (byte) platform, (byte) 0xff, message };
|
||||
var ctorTypes = new [] { PlatformEnum, PlatformArch, typeof (string) };
|
||||
#endif
|
||||
return CreateNewAttribute (type, ctorTypes, ctorValues);
|
||||
var args = new ConstructorArguments (platform, major, minor, build, message);
|
||||
return CreateNewAttribute<T> (args.GetCtorTypes (), args.GetCtorValues ());
|
||||
}
|
||||
|
||||
public static Attribute CreateNewIntroducedAttribute (PlatformName platform, int major, int minor, string? message = null)
|
||||
public static T CreateNewAttribute<T> (PlatformName platform, string? message = null) where T : Attribute
|
||||
{
|
||||
return CreateMajorMinorAttribute (IntroducedAttributeType, platform, major, minor, message);
|
||||
var args = new ConstructorArguments (platform, message);
|
||||
return CreateNewAttribute<T> (args.GetCtorTypes (), args.GetCtorValues ());
|
||||
}
|
||||
|
||||
public static Attribute CreateNewUnspecifiedIntroducedAttribute (PlatformName platform, string? message = null)
|
||||
public static IntroducedAttribute CreateNoVersionSupportedAttribute (PlatformName platform)
|
||||
{
|
||||
return CreateUnspecifiedAttribute (IntroducedAttributeType, platform, message);
|
||||
switch (platform) {
|
||||
case PlatformName.iOS:
|
||||
case PlatformName.TvOS:
|
||||
case PlatformName.MacOSX:
|
||||
case PlatformName.MacCatalyst:
|
||||
return new (platform);
|
||||
case PlatformName.WatchOS:
|
||||
throw new InvalidOperationException ("CreateNoVersionSupportedAttribute for WatchOS never makes sense");
|
||||
default:
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
}
|
||||
|
||||
public static Attribute CreateObsoletedAttribute (PlatformName platform, int major, int minor, string? message = null)
|
||||
public static UnavailableAttribute CreateUnsupportedAttribute (PlatformName platform)
|
||||
{
|
||||
return CreateMajorMinorAttribute (ObsoletedAttributeType, platform, major, minor, message);
|
||||
switch (platform) {
|
||||
case PlatformName.iOS:
|
||||
case PlatformName.MacCatalyst:
|
||||
case PlatformName.MacOSX:
|
||||
case PlatformName.TvOS:
|
||||
return new (platform);
|
||||
case PlatformName.WatchOS:
|
||||
throw new InvalidOperationException ("CreateUnsupportedAttribute for WatchOS never makes sense");
|
||||
default:
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
}
|
||||
|
||||
public static Attribute CreateDeprecatedAttribute (PlatformName platform, int major, int minor, string? message = null)
|
||||
public static AvailabilityBaseAttribute CloneFromOtherPlatform (AvailabilityBaseAttribute attr, PlatformName platform)
|
||||
{
|
||||
return CreateMajorMinorAttribute (DeprecatedAttributeType, platform, major, minor, message);
|
||||
if (attr.Version is null) {
|
||||
switch (attr.AvailabilityKind) {
|
||||
case AvailabilityKind.Introduced:
|
||||
return new IntroducedAttribute (platform, message: attr.Message);
|
||||
case AvailabilityKind.Deprecated:
|
||||
return new DeprecatedAttribute (platform, message: attr.Message);
|
||||
case AvailabilityKind.Obsoleted:
|
||||
return new ObsoletedAttribute (platform, message: attr.Message);
|
||||
case AvailabilityKind.Unavailable:
|
||||
return new UnavailableAttribute (platform, message: attr.Message);
|
||||
default:
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
}
|
||||
|
||||
// Due to the absurd API of Version, you can not pass a -1 to the build constructor
|
||||
// nor can you coerse to 0, as that will fail with "16.0.0 <= 16.0" => false in the registrar
|
||||
// So determine if the build is -1, and use the 2 or 3 param ctor...
|
||||
var version = attr.Version;
|
||||
var minimum = Xamarin.SdkVersions.GetMinVersion (platform.AsApplePlatform ());
|
||||
if (version < minimum)
|
||||
version = minimum;
|
||||
|
||||
if (version.Build == -1) {
|
||||
switch (attr.AvailabilityKind) {
|
||||
case AvailabilityKind.Introduced:
|
||||
return new IntroducedAttribute (platform, version.Major, version.Minor, message: attr.Message);
|
||||
case AvailabilityKind.Deprecated:
|
||||
return new DeprecatedAttribute (platform, version.Major, version.Minor, message: attr.Message);
|
||||
case AvailabilityKind.Obsoleted:
|
||||
return new ObsoletedAttribute (platform, version.Major, version.Minor, message: attr.Message);
|
||||
case AvailabilityKind.Unavailable:
|
||||
return new UnavailableAttribute (platform, message: attr.Message);
|
||||
default:
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
}
|
||||
|
||||
switch (attr.AvailabilityKind) {
|
||||
case AvailabilityKind.Introduced:
|
||||
return new IntroducedAttribute (platform, version.Major, version.Minor, version.Build, message: attr.Message);
|
||||
case AvailabilityKind.Deprecated:
|
||||
return new DeprecatedAttribute (platform, version.Major, version.Minor, version.Build, message: attr.Message);
|
||||
case AvailabilityKind.Obsoleted:
|
||||
return new ObsoletedAttribute (platform, version.Major, version.Minor, version.Build, message: attr.Message);
|
||||
case AvailabilityKind.Unavailable:
|
||||
return new UnavailableAttribute (platform, message: attr.Message);
|
||||
default:
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
}
|
||||
|
||||
public static Attribute CreateUnavailableAttribute (PlatformName platformName, string? message = null)
|
||||
// Find the introduced attribute with the highest version between the target list and the additions.
|
||||
// If the destination list has an introduced attribute, replace it if it's not the one with the highest version
|
||||
// If the destination list does not have an introduced attribute, then add one if there's one in the additions and there's not already an unavailable attribute.
|
||||
public static void FindHighestIntroducedAttributes (List<AvailabilityBaseAttribute> dest, IEnumerable<AvailabilityBaseAttribute> additions)
|
||||
{
|
||||
#if NET
|
||||
var ctorValues = new object? [] { (byte) platformName, message };
|
||||
var ctorTypes = new [] { PlatformEnum, typeof (string) };
|
||||
#else
|
||||
var ctorValues = new object [] { (byte) platformName, (byte) 0xff, message };
|
||||
var ctorTypes = new [] { PlatformEnum, PlatformArch, typeof (string) };
|
||||
#endif
|
||||
return CreateNewAttribute (UnavailableAttributeType, ctorTypes, ctorValues);
|
||||
if (!additions.Any ())
|
||||
return;
|
||||
|
||||
foreach (var platform in BindingTouch.AllPlatformNames) {
|
||||
// find the availability attribute with the highest version we're trying to add
|
||||
var latestAddition = additions
|
||||
.Where (v => v.AvailabilityKind == AvailabilityKind.Introduced && v.Platform == platform)
|
||||
.OrderBy (v => v.Version)
|
||||
.LastOrDefault ();
|
||||
if (latestAddition is null)
|
||||
continue;
|
||||
|
||||
var added = CloneFromOtherPlatform (latestAddition, latestAddition.Platform);
|
||||
var idx = dest.FindIndex (v => v.Platform == platform && v.AvailabilityKind == AvailabilityKind.Introduced);
|
||||
if (idx == -1) {
|
||||
// no existing introduced attribute: add it unless there's already an unavailable attribute
|
||||
if (!dest.Any (v => v.Platform == platform && v.AvailabilityKind == AvailabilityKind.Unavailable))
|
||||
dest.Add (added);
|
||||
} else if (added.Version > dest [idx].Version) {
|
||||
// replace any existing introduced attribute if the existing version is lower than the added one
|
||||
dest [idx] = added;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsValidToCopyTo (List<AvailabilityBaseAttribute> dest, AvailabilityBaseAttribute addition, bool allowIntroducedOnUnavailable = false)
|
||||
{
|
||||
// If we are duplicating an existing attribute
|
||||
if (dest.Any (d => d.Platform == addition.Platform && d.AvailabilityKind == addition.AvailabilityKind))
|
||||
return false;
|
||||
// If we are introduced and there is already an Unavailable
|
||||
return allowIntroducedOnUnavailable
|
||||
|| (addition is not IntroducedAttribute
|
||||
|| !dest.Any (d => d.Platform == addition.Platform && d.AvailabilityKind == AvailabilityKind.Unavailable));
|
||||
}
|
||||
|
||||
public static void CopyValidAttributes (List<AvailabilityBaseAttribute> dest, IEnumerable<AvailabilityBaseAttribute> additions)
|
||||
{
|
||||
foreach (var addition in additions.Where (a => IsValidToCopyTo (dest, a))) {
|
||||
dest.Add (CloneFromOtherPlatform (addition, addition.Platform));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -305,21 +305,21 @@ public class AttributeManager {
|
|||
case "MacCatalystAttribute":
|
||||
return AttributeConversionManager.ConvertPlatformAttribute (attribute, PlatformName.MacCatalyst).Yield ();
|
||||
case "LionAttribute":
|
||||
return AttributeFactory.CreateNewIntroducedAttribute (PlatformName.MacOSX, 10, 7).Yield ();
|
||||
return AttributeFactory.CreateNewAttribute<IntroducedAttribute> (PlatformName.MacOSX, 10, 7).Yield ();
|
||||
case "MountainLionAttribute":
|
||||
return AttributeFactory.CreateNewIntroducedAttribute (PlatformName.MacOSX, 10, 8).Yield ();
|
||||
return AttributeFactory.CreateNewAttribute<IntroducedAttribute> (PlatformName.MacOSX, 10, 8).Yield ();
|
||||
case "MavericksAttribute":
|
||||
return AttributeFactory.CreateNewIntroducedAttribute (PlatformName.MacOSX, 10, 9).Yield ();
|
||||
return AttributeFactory.CreateNewAttribute<IntroducedAttribute> (PlatformName.MacOSX, 10, 9).Yield ();
|
||||
case "NoMacAttribute":
|
||||
return AttributeFactory.CreateUnavailableAttribute (PlatformName.MacOSX).Yield ();
|
||||
return AttributeFactory.CreateNewAttribute<UnavailableAttribute> (PlatformName.MacOSX).Yield ();
|
||||
case "NoiOSAttribute":
|
||||
return AttributeFactory.CreateUnavailableAttribute (PlatformName.iOS).Yield ();
|
||||
return AttributeFactory.CreateNewAttribute<UnavailableAttribute> (PlatformName.iOS).Yield ();
|
||||
case "NoWatchAttribute":
|
||||
return AttributeFactory.CreateUnavailableAttribute (PlatformName.WatchOS).Yield ();
|
||||
return AttributeFactory.CreateNewAttribute<UnavailableAttribute> (PlatformName.WatchOS).Yield ();
|
||||
case "NoTVAttribute":
|
||||
return AttributeFactory.CreateUnavailableAttribute (PlatformName.TvOS).Yield ();
|
||||
return AttributeFactory.CreateNewAttribute<UnavailableAttribute> (PlatformName.TvOS).Yield ();
|
||||
case "NoMacCatalystAttribute":
|
||||
return AttributeFactory.CreateUnavailableAttribute (PlatformName.MacCatalyst).Yield ();
|
||||
return AttributeFactory.CreateNewAttribute<UnavailableAttribute> (PlatformName.MacCatalyst).Yield ();
|
||||
case "AvailabilityAttribute":
|
||||
return AttributeConversionManager.ConvertAvailability (attribute);
|
||||
#if NET
|
||||
|
@ -327,15 +327,15 @@ public class AttributeManager {
|
|||
var sarg = attribute.ConstructorArguments [0].Value as string;
|
||||
(var sp, var sv) = ParseOSPlatformAttribute (sarg);
|
||||
if (sv is null)
|
||||
return AttributeFactory.CreateNewUnspecifiedIntroducedAttribute (sp).Yield ();
|
||||
return AttributeFactory.CreateNewAttribute<IntroducedAttribute> (sp).Yield ();
|
||||
else
|
||||
return AttributeFactory.CreateNewIntroducedAttribute (sp, sv.Major, sv.Minor).Yield ();
|
||||
return AttributeFactory.CreateNewAttribute<IntroducedAttribute> (sp, sv.Major, sv.Minor).Yield ();
|
||||
case "UnsupportedOSPlatformAttribute":
|
||||
var uarg = attribute.ConstructorArguments [0].Value as string;
|
||||
(var up, var uv) = ParseOSPlatformAttribute (uarg);
|
||||
// might have been available for a while...
|
||||
if (uv == null)
|
||||
return AttributeFactory.CreateUnavailableAttribute (up).Yield ();
|
||||
return AttributeFactory.CreateNewAttribute<UnavailableAttribute> (up).Yield ();
|
||||
else
|
||||
return Enumerable.Empty<System.Attribute> ();
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
#if NET
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using ObjCRuntime;
|
||||
|
||||
#nullable enable
|
||||
|
||||
public partial class Generator {
|
||||
|
||||
AvailabilityBaseAttribute [] GetPlatformAttributesToPrint (MemberInfo mi, MemberInfo? context, MemberInfo? inlinedType)
|
||||
{
|
||||
// Attributes are directly on the member
|
||||
List<AvailabilityBaseAttribute> memberAvailability = AttributeManager.GetCustomAttributes<AvailabilityBaseAttribute> (mi).ToList ();
|
||||
|
||||
// Due to differences between Xamarin and NET6 availability attributes, we have to synthesize many duplicates for NET6
|
||||
// See https://github.com/xamarin/xamarin-macios/issues/10170 for details
|
||||
if (context is null)
|
||||
context = FindContainingContext (mi);
|
||||
// Attributes on the _target_ context, the class itself or the target of the protocol inlining
|
||||
List<AvailabilityBaseAttribute> parentContextAvailability = GetAllParentAttributes (context);
|
||||
// (Optional) Attributes from the inlined protocol type itself
|
||||
var inlinedTypeAvailability = inlinedType is not null ? GetAllParentAttributes (inlinedType) : null;
|
||||
|
||||
// We must consider attributes if we have any on our type, or if we're inlining and that inlined type has attributes
|
||||
// If neither are true, we have zero attributes that are relevant
|
||||
bool shouldConsiderAttributes = memberAvailability.Any () || inlinedTypeAvailability != null && inlinedTypeAvailability.Any ();
|
||||
if (shouldConsiderAttributes) {
|
||||
// We will consider any inlinedType attributes first, if any, before any from our parent context
|
||||
List<AvailabilityBaseAttribute> availabilityToConsider = new List<AvailabilityBaseAttribute> ();
|
||||
if (inlinedTypeAvailability != null) {
|
||||
availabilityToConsider.AddRange (inlinedTypeAvailability);
|
||||
// Don't copy parent attributes if the conflict with the type we're inlining members into
|
||||
// Example: don't copy Introduced on top of Unavailable.
|
||||
AttributeFactory.CopyValidAttributes (availabilityToConsider, parentContextAvailability);
|
||||
AttributeFactory.FindHighestIntroducedAttributes (availabilityToConsider, parentContextAvailability);
|
||||
} else {
|
||||
availabilityToConsider.AddRange (parentContextAvailability);
|
||||
}
|
||||
|
||||
// We do not support Watch, so strip from both our input sources before any processing
|
||||
memberAvailability = memberAvailability.Where (x => x.Platform != PlatformName.WatchOS).ToList ();
|
||||
availabilityToConsider = availabilityToConsider.Where (x => x.Platform != PlatformName.WatchOS).ToList ();
|
||||
|
||||
// Add any implied non-catalyst introduced (Catalyst will come later)
|
||||
AddUnlistedAvailability (context, availabilityToConsider);
|
||||
|
||||
// Copy down any unavailable from the parent before expanding, since a [NoMacCatalyst] on the type trumps [iOS] on a member
|
||||
AttributeFactory.CopyValidAttributes (memberAvailability, availabilityToConsider.Where (attr => attr.AvailabilityKind != AvailabilityKind.Introduced));
|
||||
|
||||
if (inlinedType is not null && inlinedType != mi.DeclaringType && memberAvailability.Count > 1) {
|
||||
// We might have gotten conflicting availability attributes for inlined members, where the inlined member
|
||||
// might be available on a platform the target type isn't. The target type's unavailability will come
|
||||
// later in the list, which means that if we have an unavailable attribute after an introduced attribute,
|
||||
// then we need to remove the introduced attribute.
|
||||
for (var i = memberAvailability.Count - 1; i >= 0; i--) {
|
||||
if (memberAvailability [i].AvailabilityKind != AvailabilityKind.Unavailable)
|
||||
continue;
|
||||
for (var k = i - 1; k >= 0; k--) {
|
||||
if (memberAvailability [k].AvailabilityKind == AvailabilityKind.Introduced && memberAvailability [k].Platform == memberAvailability [i].Platform) {
|
||||
memberAvailability.RemoveAt (k);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now copy it down introduced from the parent
|
||||
AttributeFactory.FindHighestIntroducedAttributes (memberAvailability, availabilityToConsider.Where (attr => attr.AvailabilityKind == AvailabilityKind.Introduced));
|
||||
|
||||
if (!BindThirdPartyLibrary) {
|
||||
// If all of this implication gives us something silly, like being introduced
|
||||
// on a type that is on a namespace we don't support, ignore those Supported
|
||||
StripIntroducedOnNamespaceNotIncluded (memberAvailability, context);
|
||||
if (inlinedType != null) {
|
||||
StripIntroducedOnNamespaceNotIncluded (memberAvailability, inlinedType);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove any duplicates attributes as well
|
||||
memberAvailability = memberAvailability.Distinct ().ToList ();
|
||||
}
|
||||
return memberAvailability.ToArray ();
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using ObjCRuntime;
|
||||
|
||||
#nullable enable
|
||||
|
||||
public partial class Generator {
|
||||
|
||||
AvailabilityBaseAttribute [] GetPlatformAttributesToPrint (MemberInfo mi, MemberInfo? context, MemberInfo? inlinedType)
|
||||
=> AttributeManager.GetCustomAttributes<AvailabilityBaseAttribute> (mi).ToArray ();
|
||||
}
|
||||
#endif
|
|
@ -2400,89 +2400,6 @@ public partial class Generator : IMemberGatherer {
|
|||
#endif
|
||||
}
|
||||
|
||||
static AvailabilityBaseAttribute CloneFromOtherPlatform (AvailabilityBaseAttribute attr, PlatformName platform)
|
||||
{
|
||||
if (attr.Version is null) {
|
||||
switch (attr.AvailabilityKind) {
|
||||
case AvailabilityKind.Introduced:
|
||||
return new IntroducedAttribute (platform, message: attr.Message);
|
||||
case AvailabilityKind.Deprecated:
|
||||
return new DeprecatedAttribute (platform, message: attr.Message);
|
||||
case AvailabilityKind.Obsoleted:
|
||||
return new ObsoletedAttribute (platform, message: attr.Message);
|
||||
case AvailabilityKind.Unavailable:
|
||||
return new UnavailableAttribute (platform, message: attr.Message);
|
||||
default:
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
} else {
|
||||
// Due to the absurd API of Version, you can not pass a -1 to the build constructor
|
||||
// nor can you coerse to 0, as that will fail with "16.0.0 <= 16.0" => false in the registrar
|
||||
// So determine if the build is -1, and use the 2 or 3 param ctor...
|
||||
var version = attr.Version;
|
||||
var minimum = Xamarin.SdkVersions.GetMinVersion (platform.AsApplePlatform ());
|
||||
if (version < minimum)
|
||||
version = minimum;
|
||||
if (version.Build == -1) {
|
||||
switch (attr.AvailabilityKind) {
|
||||
case AvailabilityKind.Introduced:
|
||||
return new IntroducedAttribute (platform, version.Major, version.Minor, message: attr.Message);
|
||||
case AvailabilityKind.Deprecated:
|
||||
return new DeprecatedAttribute (platform, version.Major, version.Minor, message: attr.Message);
|
||||
case AvailabilityKind.Obsoleted:
|
||||
return new ObsoletedAttribute (platform, version.Major, version.Minor, message: attr.Message);
|
||||
case AvailabilityKind.Unavailable:
|
||||
return new UnavailableAttribute (platform, message: attr.Message);
|
||||
default:
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
} else {
|
||||
switch (attr.AvailabilityKind) {
|
||||
case AvailabilityKind.Introduced:
|
||||
return new IntroducedAttribute (platform, version.Major, version.Minor, version.Build, message: attr.Message);
|
||||
case AvailabilityKind.Deprecated:
|
||||
return new DeprecatedAttribute (platform, version.Major, version.Minor, version.Build, message: attr.Message);
|
||||
case AvailabilityKind.Obsoleted:
|
||||
return new ObsoletedAttribute (platform, version.Major, version.Minor, version.Build, message: attr.Message);
|
||||
case AvailabilityKind.Unavailable:
|
||||
return new UnavailableAttribute (platform, message: attr.Message);
|
||||
default:
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static AvailabilityBaseAttribute CreateNoVersionSupportedAttribute (PlatformName platform)
|
||||
{
|
||||
switch (platform) {
|
||||
case PlatformName.iOS:
|
||||
case PlatformName.TvOS:
|
||||
case PlatformName.MacOSX:
|
||||
case PlatformName.MacCatalyst:
|
||||
return new IntroducedAttribute (platform);
|
||||
case PlatformName.WatchOS:
|
||||
throw new InvalidOperationException ("CreateNoVersionSupportedAttribute for WatchOS never makes sense");
|
||||
default:
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
}
|
||||
|
||||
static AvailabilityBaseAttribute CreateUnsupportedAttribute (PlatformName platform)
|
||||
{
|
||||
switch (platform) {
|
||||
case PlatformName.iOS:
|
||||
case PlatformName.MacCatalyst:
|
||||
case PlatformName.MacOSX:
|
||||
case PlatformName.TvOS:
|
||||
return new UnavailableAttribute (platform);
|
||||
case PlatformName.WatchOS:
|
||||
throw new InvalidOperationException ("CreateUnsupportedAttribute for WatchOS never makes sense");
|
||||
default:
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
}
|
||||
|
||||
HashSet<string> GetFrameworkListForPlatform (PlatformName platform)
|
||||
{
|
||||
HashSet<string> frameworkList = null;
|
||||
|
@ -2533,7 +2450,7 @@ public partial class Generator : IMemberGatherer {
|
|||
// add a supported introduced (without version) since it was "unlisted"
|
||||
foreach (var platform in BindingTouch.AllPlatformNames) {
|
||||
if (!PlatformMarkedUnavailable (platform, availability) && IsInSupportedFramework (containingClass, platform)) {
|
||||
availability.Add (CreateNoVersionSupportedAttribute (platform));
|
||||
availability.Add (AttributeFactory.CreateNoVersionSupportedAttribute (platform));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2572,61 +2489,12 @@ public partial class Generator : IMemberGatherer {
|
|||
// For each attribute we dropped, if we don't have an existing non-introduced, create one
|
||||
foreach (var platform in droppedPlatforms) {
|
||||
if (!memberAvailability.Any (a => platform == a.Platform && a.AvailabilityKind != AvailabilityKind.Introduced)) {
|
||||
memberAvailability.Add (CreateUnsupportedAttribute (platform));
|
||||
memberAvailability.Add (AttributeFactory.CreateUnsupportedAttribute (platform));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsValidToCopyTo (List<AvailabilityBaseAttribute> dest, AvailabilityBaseAttribute addition, bool allowIntroducedOnUnavailable = false)
|
||||
{
|
||||
// If we are duplicating an existing attribute
|
||||
if (dest.Any (d => d.Platform == addition.Platform && d.AvailabilityKind == addition.AvailabilityKind))
|
||||
return false;
|
||||
// If we are introduced and there is already an Unavailable
|
||||
if (!allowIntroducedOnUnavailable && (addition is IntroducedAttribute && dest.Any (d => d.Platform == addition.Platform && d.AvailabilityKind == AvailabilityKind.Unavailable)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static void CopyValidAttributes (List<AvailabilityBaseAttribute> dest, IEnumerable<AvailabilityBaseAttribute> additions)
|
||||
{
|
||||
foreach (var addition in additions.Where (a => IsValidToCopyTo (dest, a))) {
|
||||
dest.Add (CloneFromOtherPlatform (addition, addition.Platform));
|
||||
}
|
||||
}
|
||||
|
||||
// Find the introduced attribute with the highest version between the target list and the additions.
|
||||
// If the destination list has an introduced attribute, replace it if it's not the one with the highest version
|
||||
// If the destination list does not have an introduced attribute, then add one if there's one in the additions and there's not already an unavailable attribute.
|
||||
static void FindHighestIntroducedAttributes (List<AvailabilityBaseAttribute> dest, IEnumerable<AvailabilityBaseAttribute> additions)
|
||||
{
|
||||
if (!additions.Any ())
|
||||
return;
|
||||
|
||||
foreach (var platform in BindingTouch.AllPlatformNames) {
|
||||
// find the availability attribute with the highest version we're trying to add
|
||||
var latestAddition = additions
|
||||
.Where (v => v.AvailabilityKind == AvailabilityKind.Introduced && v.Platform == platform)
|
||||
.OrderBy (v => v.Version)
|
||||
.LastOrDefault ();
|
||||
if (latestAddition is null)
|
||||
continue;
|
||||
|
||||
var added = CloneFromOtherPlatform (latestAddition, latestAddition.Platform);
|
||||
var idx = dest.FindIndex (v => v.Platform == platform && v.AvailabilityKind == AvailabilityKind.Introduced);
|
||||
if (idx == -1) {
|
||||
// no existing introduced attribute: add it unless there's already an unavailable attribute
|
||||
if (!dest.Any (v => v.Platform == platform && v.AvailabilityKind == AvailabilityKind.Unavailable))
|
||||
dest.Add (added);
|
||||
} else if (added.Version > dest [idx].Version) {
|
||||
// replace any existing introduced attribute if the existing version is lower than the added one
|
||||
dest [idx] = added;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This assumes the compiler implements property methods as get_ or set_ prefixes
|
||||
static PropertyInfo GetProperyFromGetSetMethod (MethodInfo method)
|
||||
{
|
||||
|
@ -2672,83 +2540,6 @@ public partial class Generator : IMemberGatherer {
|
|||
}
|
||||
}
|
||||
|
||||
AvailabilityBaseAttribute [] GetPlatformAttributesToPrint (MemberInfo mi, MemberInfo context, MemberInfo inlinedType)
|
||||
{
|
||||
// Attributes are directly on the member
|
||||
List<AvailabilityBaseAttribute> memberAvailability = AttributeManager.GetCustomAttributes<AvailabilityBaseAttribute> (mi).ToList ();
|
||||
|
||||
// Due to differences between Xamarin and NET6 availability attributes, we have to synthesize many duplicates for NET6
|
||||
// See https://github.com/xamarin/xamarin-macios/issues/10170 for details
|
||||
#if NET
|
||||
if (context is null)
|
||||
context = FindContainingContext (mi);
|
||||
// Attributes on the _target_ context, the class itself or the target of the protocol inlining
|
||||
List<AvailabilityBaseAttribute> parentContextAvailability = GetAllParentAttributes (context);
|
||||
// (Optional) Attributes from the inlined protocol type itself
|
||||
List<AvailabilityBaseAttribute> inlinedTypeAvailability = inlinedType != null ? GetAllParentAttributes (inlinedType) : null;
|
||||
|
||||
// We must consider attributes if we have any on our type, or if we're inlining and that inlined type has attributes
|
||||
// If neither are true, we have zero attributes that are relevant
|
||||
bool shouldConsiderAttributes = memberAvailability.Any () || inlinedTypeAvailability != null && inlinedTypeAvailability.Any ();
|
||||
if (shouldConsiderAttributes) {
|
||||
// We will consider any inlinedType attributes first, if any, before any from our parent context
|
||||
List<AvailabilityBaseAttribute> availabilityToConsider = new List<AvailabilityBaseAttribute> ();
|
||||
if (inlinedTypeAvailability != null) {
|
||||
availabilityToConsider.AddRange (inlinedTypeAvailability);
|
||||
// Don't copy parent attributes if the conflict with the type we're inlining members into
|
||||
// Example: don't copy Introduced on top of Unavailable.
|
||||
CopyValidAttributes (availabilityToConsider, parentContextAvailability);
|
||||
FindHighestIntroducedAttributes (availabilityToConsider, parentContextAvailability);
|
||||
} else {
|
||||
availabilityToConsider.AddRange (parentContextAvailability);
|
||||
}
|
||||
|
||||
// We do not support Watch, so strip from both our input sources before any processing
|
||||
memberAvailability = memberAvailability.Where (x => x.Platform != PlatformName.WatchOS).ToList ();
|
||||
availabilityToConsider = availabilityToConsider.Where (x => x.Platform != PlatformName.WatchOS).ToList ();
|
||||
|
||||
// Add any implied non-catalyst introduced (Catalyst will come later)
|
||||
AddUnlistedAvailability (context, availabilityToConsider);
|
||||
|
||||
// Copy down any unavailable from the parent before expanding, since a [NoMacCatalyst] on the type trumps [iOS] on a member
|
||||
CopyValidAttributes (memberAvailability, availabilityToConsider.Where (attr => attr.AvailabilityKind != AvailabilityKind.Introduced));
|
||||
|
||||
if (inlinedType is not null && inlinedType != mi.DeclaringType && memberAvailability.Count > 1) {
|
||||
// We might have gotten conflicting availability attributes for inlined members, where the inlined member
|
||||
// might be available on a platform the target type isn't. The target type's unavailability will come
|
||||
// later in the list, which means that if we have an unavailable attribute after an introduced attribute,
|
||||
// then we need to remove the introduced attribute.
|
||||
for (var i = memberAvailability.Count - 1; i >= 0; i--) {
|
||||
if (memberAvailability [i].AvailabilityKind != AvailabilityKind.Unavailable)
|
||||
continue;
|
||||
for (var k = i - 1; k >= 0; k--) {
|
||||
if (memberAvailability [k].AvailabilityKind == AvailabilityKind.Introduced && memberAvailability [k].Platform == memberAvailability [i].Platform) {
|
||||
memberAvailability.RemoveAt (k);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now copy it down introduced from the parent
|
||||
FindHighestIntroducedAttributes (memberAvailability, availabilityToConsider.Where (attr => attr.AvailabilityKind == AvailabilityKind.Introduced));
|
||||
|
||||
if (!BindThirdPartyLibrary) {
|
||||
// If all of this implication gives us something silly, like being introduced
|
||||
// on a type that is on a namespace we don't support, ignore those Supported
|
||||
StripIntroducedOnNamespaceNotIncluded (memberAvailability, context);
|
||||
if (inlinedType != null) {
|
||||
StripIntroducedOnNamespaceNotIncluded (memberAvailability, inlinedType);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove any duplicates attributes as well
|
||||
memberAvailability = memberAvailability.Distinct ().ToList ();
|
||||
}
|
||||
#endif
|
||||
return memberAvailability.ToArray ();
|
||||
}
|
||||
|
||||
public bool PrintPlatformAttributes (MemberInfo mi, Type inlinedType = null)
|
||||
{
|
||||
bool printed = false;
|
||||
|
|
|
@ -99,6 +99,7 @@
|
|||
<Compile Include="..\src\bgen\AsyncMethodKind.cs" />
|
||||
<Compile Include="..\src\bgen\AttributeManager.cs" />
|
||||
<Compile Include="..\src\bgen\Attributes.cs" />
|
||||
<Compile Include="..\src\bgen\AttributeFactory.ConstructorArguments.cs" />
|
||||
<Compile Include="..\src\bgen\AttributeFactory.cs" />
|
||||
<Compile Include="..\src\bgen\BodyOption.cs" />
|
||||
<Compile Include="..\src\bgen\BindingTouch.cs" />
|
||||
|
@ -111,6 +112,7 @@
|
|||
<Compile Include="..\src\bgen\GeneratedType.cs" />
|
||||
<Compile Include="..\src\bgen\GeneratedTypes.cs" />
|
||||
<Compile Include="..\src\bgen\Generator.cs" />
|
||||
<Compile Include="..\src\bgen\Generator.PrintAttributes.cs" />
|
||||
<Compile Include="..\src\bgen\MarshalInfo.cs" />
|
||||
<Compile Include="..\src\bgen\MarshalTypeList.cs" />
|
||||
<Compile Include="..\src\bgen\MarshalType.cs" />
|
||||
|
|
|
@ -29,9 +29,21 @@
|
|||
<Compile Include="..\generator\BGenTool.cs">
|
||||
<Link>BGenTool.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\src\bgen\AttributeFactory.ConstructorArguments.cs">
|
||||
<Link>AttributeFactory.ConstructorArguments.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\src\bgen\AttributeFactory.cs">
|
||||
<Link>AttributeFactory.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\generator\AttributeFactoryTests.cs">
|
||||
<Link>AttributeFactoryTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\generator\CollectionsExtensionsTests.cs">
|
||||
<Link>CollectionsExtensionsTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\generator\ConstructorArgumentsTests.cs">
|
||||
<Link>ConstructorArgumentsTests.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\generator\ErrorTests.cs">
|
||||
<Link>ErrorTests.cs</Link>
|
||||
</Compile>
|
||||
|
@ -74,5 +86,8 @@
|
|||
<Compile Include="..\common\BinLog.cs">
|
||||
<Link>BinLog.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\tools\common\SdkVersions.cs">
|
||||
<Link>SdkVersions.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
@ -914,6 +914,10 @@ namespace Xamarin.Tests {
|
|||
|
||||
var extensionPath = Path.Combine (Path.GetDirectoryName (consumingProjectDir)!, "bin", "Debug", platform.ToFramework (), GetDefaultRuntimeIdentifier (platform), "MySimpleApp.app", GetPlugInsRelativePath (platform), "ExtensionProject.appex");
|
||||
Assert.That (Directory.Exists (extensionPath), $"App extension directory does not exist: {extensionPath}");
|
||||
|
||||
var pathToSearch = Path.Combine (Path.GetDirectoryName (consumingProjectDir)!, "bin", "Debug");
|
||||
string [] configFiles = Directory.GetFiles (pathToSearch, "*.runtimeconfig.*", SearchOption.AllDirectories);
|
||||
Assert.AreNotEqual (0, configFiles.Length, "runtimeconfig.json file does not exist");
|
||||
}
|
||||
|
||||
[TestCase (ApplePlatform.iOS, "iossimulator-x64;iossimulator-arm64")]
|
||||
|
|
|
@ -0,0 +1,186 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using NUnit.Framework;
|
||||
using ObjCRuntime;
|
||||
using Xamarin.Utils;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace GeneratorTests {
|
||||
|
||||
[TestFixture]
|
||||
[Parallelizable (ParallelScope.All)]
|
||||
public class AttributeFactoryTests {
|
||||
static void AssertAttributeCreation<T> (Func<PlatformName, int, int, string?, T> callback, PlatformName platform,
|
||||
int major, int minor, string? message = null) where T : AvailabilityBaseAttribute
|
||||
{
|
||||
var typeName = typeof (T).Name;
|
||||
var attr = callback (platform, major, minor, message) as T;
|
||||
Assert.IsNotNull (attr, $"{typeName} attribute type");
|
||||
Assert.AreEqual (platform, attr.Platform, $"{typeName} Platform");
|
||||
Assert.AreEqual (major, attr.Version.Major, $"{typeName} Major");
|
||||
Assert.AreEqual (minor, attr.Version.Minor, $"{typeName} Minor");
|
||||
Assert.AreEqual (message, attr.Message);
|
||||
}
|
||||
|
||||
static void AssertAttributeCreationNotVersion<T> (Func<PlatformName, string?, T> callback, PlatformName platform,
|
||||
string? message = null) where T : AvailabilityBaseAttribute
|
||||
{
|
||||
var typeName = typeof (T).Name;
|
||||
var attr = callback (platform, message) as T;
|
||||
Assert.IsNotNull (attr, $"{typeName} attribute type");
|
||||
Assert.AreEqual (platform, attr.Platform, $"{typeName} Platform");
|
||||
Assert.AreEqual (message, attr.Message);
|
||||
}
|
||||
|
||||
|
||||
// simple tests, but we want to test it
|
||||
[TestCase (PlatformName.iOS, 13, 4, "message")]
|
||||
[TestCase (PlatformName.iOS, 12, 4, null)]
|
||||
public void CreateAttributeTest (PlatformName platform, int major, int minor, string? message)
|
||||
{
|
||||
// call several times with diff types
|
||||
AssertAttributeCreation (AttributeFactory.CreateNewAttribute<IntroducedAttribute>, platform, major, minor, message);
|
||||
AssertAttributeCreation (AttributeFactory.CreateNewAttribute<DeprecatedAttribute>, platform, major, minor, message);
|
||||
AssertAttributeCreation (AttributeFactory.CreateNewAttribute<ObsoletedAttribute>, platform, major, minor, message);
|
||||
}
|
||||
|
||||
[TestCase (PlatformName.iOS, "message")]
|
||||
[TestCase (PlatformName.iOS, null)]
|
||||
public void CreateAttributeNoVersionTest (PlatformName platform, string? message)
|
||||
{
|
||||
// call several times with diff types
|
||||
AssertAttributeCreationNotVersion (AttributeFactory.CreateNewAttribute<IntroducedAttribute>, platform, message);
|
||||
AssertAttributeCreationNotVersion (AttributeFactory.CreateNewAttribute<UnavailableAttribute>, platform, message);
|
||||
AssertAttributeCreationNotVersion (AttributeFactory.CreateNewAttribute<DeprecatedAttribute>, platform, message);
|
||||
AssertAttributeCreationNotVersion (AttributeFactory.CreateNewAttribute<ObsoletedAttribute>, platform, message);
|
||||
}
|
||||
|
||||
[TestCase (PlatformName.iOS)]
|
||||
[TestCase (PlatformName.MacCatalyst)]
|
||||
[TestCase (PlatformName.MacOSX)]
|
||||
[TestCase (PlatformName.TvOS)]
|
||||
public void CreateNoVersionSupportedAttributeTest (PlatformName platform)
|
||||
=> Assert.AreEqual (platform, AttributeFactory.CreateNoVersionSupportedAttribute (platform).Platform);
|
||||
|
||||
[Test]
|
||||
public void CreateNoVersionSupportedAttributeWatchOSTest ()
|
||||
=> Assert.Throws<InvalidOperationException> (
|
||||
() => AttributeFactory.CreateNoVersionSupportedAttribute (PlatformName.WatchOS));
|
||||
|
||||
[TestCase (PlatformName.iOS)]
|
||||
[TestCase (PlatformName.MacCatalyst)]
|
||||
[TestCase (PlatformName.MacOSX)]
|
||||
[TestCase (PlatformName.TvOS)]
|
||||
public void CreateUnsupportedAttributeTest (PlatformName platform)
|
||||
=> Assert.AreEqual (platform, AttributeFactory.CreateUnsupportedAttribute (platform).Platform);
|
||||
|
||||
[TestCase (PlatformName.iOS)]
|
||||
[TestCase (PlatformName.MacCatalyst)]
|
||||
[TestCase (PlatformName.MacOSX)]
|
||||
[TestCase (PlatformName.TvOS)]
|
||||
public void CreateUnsupportedAttributeWatchOSTest (PlatformName platform)
|
||||
=> Assert.AreEqual (platform, AttributeFactory.CreateUnsupportedAttribute (platform).Platform);
|
||||
|
||||
class CloneCasesNoVersionClass : IEnumerable {
|
||||
public IEnumerator GetEnumerator ()
|
||||
{
|
||||
yield return new object [] {
|
||||
|
||||
new IntroducedAttribute (PlatformName.iOS),
|
||||
PlatformName.TvOS,
|
||||
};
|
||||
yield return new object [] {
|
||||
new DeprecatedAttribute (PlatformName.MacCatalyst),
|
||||
PlatformName.iOS,
|
||||
};
|
||||
yield return new object [] {
|
||||
new ObsoletedAttribute(PlatformName.WatchOS),
|
||||
PlatformName.iOS
|
||||
};
|
||||
yield return new object [] {
|
||||
new UnavailableAttribute (PlatformName.MacOSX),
|
||||
PlatformName.MacCatalyst
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[TestCaseSource (typeof (CloneCasesNoVersionClass))]
|
||||
public void CloneNoVersionTest (AvailabilityBaseAttribute attributeToClone, PlatformName targetPlatform)
|
||||
{
|
||||
var clone = AttributeFactory.CloneFromOtherPlatform (attributeToClone, targetPlatform);
|
||||
Assert.AreEqual (targetPlatform, clone.Platform, "platform");
|
||||
Assert.AreEqual (attributeToClone.Message, clone.Message, "message");
|
||||
Assert.AreEqual (attributeToClone.GetType (), clone.GetType (), "type");
|
||||
}
|
||||
|
||||
class CloneCasesMinVersionClass : IEnumerable {
|
||||
public IEnumerator GetEnumerator ()
|
||||
{
|
||||
yield return new object [] {
|
||||
new IntroducedAttribute (PlatformName.iOS, 1, 0),
|
||||
PlatformName.TvOS,
|
||||
};
|
||||
yield return new object [] {
|
||||
new DeprecatedAttribute (PlatformName.MacCatalyst, 1, 0),
|
||||
PlatformName.iOS,
|
||||
};
|
||||
yield return new object [] {
|
||||
new ObsoletedAttribute(PlatformName.WatchOS, 1, 0),
|
||||
PlatformName.iOS
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[TestCaseSource (typeof (CloneCasesMinVersionClass))]
|
||||
public void CloneMinVersion (AvailabilityBaseAttribute attributeToClone, PlatformName targetPlatform)
|
||||
{
|
||||
var clone = AttributeFactory.CloneFromOtherPlatform (attributeToClone, targetPlatform);
|
||||
Assert.AreEqual (targetPlatform, clone.Platform, "platform");
|
||||
Assert.AreEqual (attributeToClone.Message, clone.Message, "message");
|
||||
Assert.AreEqual (attributeToClone.GetType (), clone.GetType (), "type");
|
||||
#if NET
|
||||
if (clone.AvailabilityKind == AvailabilityKind.Introduced) {
|
||||
Assert.Null (clone.Version, "Version");
|
||||
} else {
|
||||
Assert.AreEqual (Xamarin.SdkVersions.GetMinVersion (targetPlatform.AsApplePlatform ()), clone.Version, "Version");
|
||||
}
|
||||
#else
|
||||
Assert.AreEqual (Xamarin.SdkVersions.GetMinVersion (targetPlatform.AsApplePlatform ()), clone.Version, "Version");
|
||||
#endif
|
||||
}
|
||||
|
||||
class CloneCasesBuildVersionClass : IEnumerable {
|
||||
public IEnumerator GetEnumerator ()
|
||||
{
|
||||
var tvOsMin = Xamarin.SdkVersions.GetMinVersion (ApplePlatform.TVOS);
|
||||
tvOsMin = new Version (tvOsMin.Major, tvOsMin.Minor, tvOsMin.Build + 3);
|
||||
var iOSMin = Xamarin.SdkVersions.GetMinVersion (ApplePlatform.iOS);
|
||||
iOSMin = new Version (iOSMin.Major, iOSMin.Minor, iOSMin.Build + 3);
|
||||
yield return new object [] {
|
||||
new IntroducedAttribute (PlatformName.iOS, tvOsMin.Major, tvOsMin.Minor, tvOsMin.Build),
|
||||
PlatformName.TvOS,
|
||||
};
|
||||
yield return new object [] {
|
||||
new DeprecatedAttribute (PlatformName.MacCatalyst, iOSMin.Major, iOSMin.Minor, iOSMin.Build),
|
||||
PlatformName.iOS,
|
||||
};
|
||||
yield return new object [] {
|
||||
new ObsoletedAttribute(PlatformName.WatchOS, iOSMin.Major, iOSMin.Minor, iOSMin.Build),
|
||||
PlatformName.iOS
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[TestCaseSource (typeof (CloneCasesBuildVersionClass))]
|
||||
public void CloneBuildVersion (AvailabilityBaseAttribute attributeToClone, PlatformName targetPlatform)
|
||||
{
|
||||
var clone = AttributeFactory.CloneFromOtherPlatform (attributeToClone, targetPlatform);
|
||||
Assert.AreEqual (targetPlatform, clone.Platform, "platform");
|
||||
Assert.AreEqual (attributeToClone.Message, clone.Message, "message");
|
||||
Assert.AreEqual (attributeToClone.GetType (), clone.GetType (), "type");
|
||||
Assert.AreEqual (attributeToClone.Version, clone.Version);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,217 @@
|
|||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using NUnit.Framework;
|
||||
using ObjCRuntime;
|
||||
|
||||
namespace GeneratorTests {
|
||||
|
||||
[TestFixture]
|
||||
[Parallelizable (ParallelScope.All)]
|
||||
public class ConstructorArgumentsTests {
|
||||
|
||||
[Test]
|
||||
public void GetCtorValuesNullVersion ()
|
||||
{
|
||||
var args = new AttributeFactory.ConstructorArguments (PlatformName.iOS, "test");
|
||||
var values = args.GetCtorValues ();
|
||||
#if NET
|
||||
Assert.AreEqual (2, values.Length, "Length");
|
||||
Assert.AreEqual ((byte)PlatformName.iOS, values[0], "Platform");
|
||||
Assert.AreEqual ("test", values[1], "Message");
|
||||
#else
|
||||
Assert.AreEqual (3, values.Length, "Length");
|
||||
Assert.AreEqual ((byte) PlatformName.iOS, values [0], "Platform");
|
||||
Assert.AreEqual ((byte) 0xff, values [1], "Flag");
|
||||
Assert.AreEqual ("test", values [2], "Message");
|
||||
#endif
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetCtorValuesNullBuild ()
|
||||
{
|
||||
var args = new AttributeFactory.ConstructorArguments (PlatformName.iOS, 13, 0, "test");
|
||||
var values = args.GetCtorValues ();
|
||||
#if NET
|
||||
Assert.AreEqual (4, values.Length, "Length");
|
||||
Assert.AreEqual ((byte)PlatformName.iOS, values[0], "Platform");
|
||||
Assert.AreEqual (13, values[1], "Major");
|
||||
Assert.AreEqual (0, values[2], "Minor");
|
||||
Assert.AreEqual ("test", values[3], "Message");
|
||||
#else
|
||||
Assert.AreEqual (5, values.Length, "Length");
|
||||
Assert.AreEqual ((byte) PlatformName.iOS, values [0], "Platform");
|
||||
Assert.AreEqual (13, values [1], "Major");
|
||||
Assert.AreEqual (0, values [2], "Minor");
|
||||
Assert.AreEqual ((byte) 0xff, values [3], "Flag");
|
||||
Assert.AreEqual ("test", values [4], "Message");
|
||||
#endif
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetCtorValuesFullVersion ()
|
||||
{
|
||||
var args = new AttributeFactory.ConstructorArguments (PlatformName.iOS, 13, 0, 1, "test");
|
||||
var values = args.GetCtorValues ();
|
||||
#if NET
|
||||
Assert.AreEqual (5, values.Length, "Length");
|
||||
Assert.AreEqual ((byte)PlatformName.iOS, values[0], "Platform");
|
||||
Assert.AreEqual (13, values[1], "Major");
|
||||
Assert.AreEqual (0, values[2], "Minor");
|
||||
Assert.AreEqual (1, values[3], "Build");
|
||||
Assert.AreEqual ("test", values[4], "Message");
|
||||
#else
|
||||
Assert.AreEqual (6, values.Length, "Length");
|
||||
Assert.AreEqual ((byte) PlatformName.iOS, values [0], "Platform");
|
||||
Assert.AreEqual (13, values [1], "Major");
|
||||
Assert.AreEqual (0, values [2], "Minor");
|
||||
Assert.AreEqual (1, values [3], "Build");
|
||||
Assert.AreEqual ((byte) 0xff, values [4], "Flag");
|
||||
Assert.AreEqual ("test", values [5], "Message");
|
||||
#endif
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetCtorTypesNullVersion ()
|
||||
{
|
||||
var args = new AttributeFactory.ConstructorArguments (PlatformName.iOS, "test");
|
||||
var types = args.GetCtorTypes ();
|
||||
#if NET
|
||||
Assert.AreEqual (2, types.Length, "Length");
|
||||
Assert.AreEqual (typeof (PlatformName), types [0], "Platform");
|
||||
Assert.AreEqual(typeof(string), types[1], "Message");
|
||||
#else
|
||||
Assert.AreEqual (3, types.Length, "Length");
|
||||
Assert.AreEqual (typeof (PlatformName), types [0], "Platform");
|
||||
Assert.AreEqual (typeof (PlatformArchitecture), types [1], "Arch");
|
||||
Assert.AreEqual (typeof (string), types [2], "Message");
|
||||
#endif
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetCtorTypesNullBuild ()
|
||||
{
|
||||
var args = new AttributeFactory.ConstructorArguments (PlatformName.iOS, 13, 0, "test");
|
||||
var types = args.GetCtorTypes ();
|
||||
#if NET
|
||||
Assert.AreEqual (4, types.Length, "Length");
|
||||
Assert.AreEqual (typeof (PlatformName), types [0], "Platform");
|
||||
Assert.AreEqual (typeof (int), types [1], "Major");
|
||||
Assert.AreEqual (typeof (int), types [2], "Minor");
|
||||
Assert.AreEqual(typeof(string), types[3], "Message");
|
||||
#else
|
||||
Assert.AreEqual (5, types.Length, "Length");
|
||||
Assert.AreEqual (typeof (PlatformName), types [0], "Platform");
|
||||
Assert.AreEqual (typeof (int), types [1], "Major");
|
||||
Assert.AreEqual (typeof (int), types [2], "Minor");
|
||||
Assert.AreEqual (typeof (PlatformArchitecture), types [3], "Arch");
|
||||
Assert.AreEqual (typeof (string), types [4], "Message");
|
||||
#endif
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetCtorTypesFullVersion ()
|
||||
{
|
||||
var args = new AttributeFactory.ConstructorArguments (PlatformName.iOS, 13, 0, 1, "test");
|
||||
var types = args.GetCtorTypes ();
|
||||
#if NET
|
||||
Assert.AreEqual (5, types.Length, "Length");
|
||||
Assert.AreEqual (typeof (PlatformName), types [0], "Platform");
|
||||
Assert.AreEqual (typeof (int), types [1], "Major");
|
||||
Assert.AreEqual (typeof (int), types [2], "Minor");
|
||||
Assert.AreEqual (typeof (int), types [3], "Build");
|
||||
Assert.AreEqual(typeof(string), types[4], "Message");
|
||||
#else
|
||||
Assert.AreEqual (6, types.Length, "Length");
|
||||
Assert.AreEqual (typeof (PlatformName), types [0], "Platform");
|
||||
Assert.AreEqual (typeof (int), types [1], "Major");
|
||||
Assert.AreEqual (typeof (int), types [2], "Minor");
|
||||
Assert.AreEqual (typeof (int), types [3], "Build");
|
||||
Assert.AreEqual (typeof (PlatformArchitecture), types [4], "Arch");
|
||||
Assert.AreEqual (typeof (string), types [5], "Message");
|
||||
#endif
|
||||
}
|
||||
|
||||
class TryGetArgumentsData : IEnumerable {
|
||||
public IEnumerator GetEnumerator ()
|
||||
{
|
||||
#if NET
|
||||
yield return new TestCaseData (
|
||||
new object [] { (byte)13, (byte)0 },
|
||||
PlatformName.iOS,
|
||||
new object? [] { (byte) PlatformName.iOS, (int) (byte) 13, (int) (byte) 0, null },
|
||||
new [] { typeof(PlatformName), typeof (int), typeof (int), typeof (string) }
|
||||
);
|
||||
|
||||
yield return new TestCaseData (
|
||||
new object [] { (byte)13, (byte)0 , (byte)1},
|
||||
PlatformName.iOS,
|
||||
new object? [] { (byte) PlatformName.iOS, (int) (byte) 13, (int) (byte) 0, (int)(byte)1,null },
|
||||
new [] { typeof(PlatformName), typeof (int), typeof (int), typeof(int), typeof (string) }
|
||||
);
|
||||
#else
|
||||
yield return new TestCaseData (
|
||||
new object [] { (byte) 13, (byte) 0 },
|
||||
PlatformName.iOS,
|
||||
new object? [] { (byte) PlatformName.iOS, (int) (byte) 13, (int) (byte) 0, (byte) 0xff, null },
|
||||
new [] { typeof (PlatformName), typeof (int), typeof (int), typeof (PlatformArchitecture), typeof (string) }
|
||||
);
|
||||
yield return new TestCaseData (
|
||||
new object [] { (byte) 13, (byte) 0, (byte) 1 },
|
||||
PlatformName.iOS,
|
||||
new object? [] { (byte) PlatformName.iOS, (int) (byte) 13, (int) (byte) 0, (int) (byte) 1, (byte) 0xff, null },
|
||||
new [] { typeof (PlatformName), typeof (int), typeof (int), typeof (int), typeof (PlatformArchitecture), typeof (string) }
|
||||
);
|
||||
yield return new TestCaseData (
|
||||
new object [] { (byte) 13, (byte) 0, true },
|
||||
PlatformName.iOS,
|
||||
new object? [] { (byte) PlatformName.iOS, (int) (byte) 13, (int) (byte) 0, (byte) 2, null },
|
||||
new [] { typeof (PlatformName), typeof (int), typeof (int), typeof (PlatformArchitecture), typeof (string) }
|
||||
);
|
||||
|
||||
yield return new TestCaseData (
|
||||
new object [] { (byte) 13, (byte) 0, (byte) 1, true },
|
||||
PlatformName.iOS,
|
||||
new object? [] { (byte) PlatformName.iOS, (int) (byte) 13, (int) (byte) 0, (int) (byte) 1, (byte) 2, null },
|
||||
new [] { typeof (PlatformName), typeof (int), typeof (int), typeof (int), typeof (PlatformArchitecture), typeof (string) }
|
||||
);
|
||||
|
||||
yield return new TestCaseData (
|
||||
new object [] { (byte) 13, (byte) 0, (byte) 1, (byte) 2 },
|
||||
PlatformName.iOS,
|
||||
new object? [] { (byte) PlatformName.iOS, (int) (byte) 13, (int) (byte) 0, (int) (byte) 1, (byte) 2, null },
|
||||
new [] { typeof (PlatformName), typeof (int), typeof (int), typeof (int), typeof (PlatformArchitecture), typeof (string) }
|
||||
);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
[TestCaseSource (typeof (TryGetArgumentsData))]
|
||||
public void TryGetCtorArguments (object [] arguments, PlatformName platformName, object [] expectedValues,
|
||||
Type [] expectedTypes)
|
||||
{
|
||||
var success = AttributeFactory.ConstructorArguments.TryGetCtorArguments (arguments, platformName,
|
||||
out var actualValues, out var actualTypes);
|
||||
Assert.True (success, "success");
|
||||
Assert.AreEqual (expectedValues.Length, actualValues.Length, "Values Length");
|
||||
for (int index = 0; index < expectedValues.Length; index++) {
|
||||
Assert.AreEqual (expectedValues [index], actualValues [index], $"Values [{index}]");
|
||||
}
|
||||
Assert.AreEqual (expectedTypes.Length, actualTypes.Length, "Types Length");
|
||||
for (int index = 0; index < expectedTypes.Length; index++) {
|
||||
Assert.AreEqual (expectedTypes [index], actualTypes [index], $"Types [{index}]");
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TryGetCtorArgumentsFail ()
|
||||
{
|
||||
var success = AttributeFactory.ConstructorArguments.TryGetCtorArguments (Array.Empty<object> (), PlatformName.iOS,
|
||||
out var actualValues, out var actualTypes);
|
||||
Assert.False (success, "success");
|
||||
Assert.Null (actualValues, "values");
|
||||
Assert.Null (actualTypes, "type");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -38,7 +38,18 @@
|
|||
<PackageReference Include="MSBuild.StructuredLogger" Version="2.1.787" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\..\src\bgen\AttributeFactory.ConstructorArguments.cs">
|
||||
<Link>AttributeFactory.ConstructorArguments.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\src\bgen\AttributeFactory.cs">
|
||||
<Link>AttributeFactory.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\tools\common\SdkVersions.cs">
|
||||
<Link>SdkVersions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="AttributeFactoryTests.cs" />
|
||||
<Compile Include="CollectionsExtensionsTests.cs" />
|
||||
<Compile Include="ConstructorArgumentsTests.cs" />
|
||||
<Compile Include="ErrorTests.cs" />
|
||||
<Compile Include="BGenTool.cs" />
|
||||
<Compile Include="..\common\ExecutionHelper.cs">
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
# YAML pipeline build definition
|
||||
# https://devdiv.visualstudio.com/DevDiv/_apps/hub/ms.vss-ciworkflow.build-ci-hub?_a=edit-build-definition&id=13947&view=Tab_Tasks
|
||||
#
|
||||
# YAML build pipeline based on the Jenkins multi-stage (main branch) build workflow
|
||||
# https://jenkins.internalx.com/view/Xamarin.MaciOS/job/macios/job/main/
|
||||
# https://jenkins.internalx.com/view/Xamarin.MaciOS/job/macios/configure
|
||||
#
|
||||
parameters:
|
||||
|
||||
- name: runGovernanceTests
|
||||
type: boolean
|
||||
default: true
|
||||
|
||||
variables:
|
||||
- template: templates/variables.yml
|
||||
- name: MaciosUploadPrefix
|
||||
value: ''
|
||||
|
||||
resources:
|
||||
repositories:
|
||||
- repository: self
|
||||
checkoutOptions:
|
||||
submodules: true
|
||||
|
||||
- repository: yaml-templates
|
||||
type: github
|
||||
name: xamarin/yaml-templates
|
||||
ref: refs/heads/main
|
||||
endpoint: xamarin
|
||||
|
||||
- repository: sdk-insertions
|
||||
type: github
|
||||
name: xamarin/sdk-insertions
|
||||
ref: refs/heads/main
|
||||
endpoint: xamarin
|
||||
|
||||
- repository: maccore
|
||||
type: github
|
||||
name: xamarin/maccore
|
||||
ref: refs/heads/main
|
||||
endpoint: xamarin
|
||||
|
||||
- repository: release-scripts
|
||||
type: github
|
||||
name: xamarin/release-scripts
|
||||
ref: refs/heads/only_codesign
|
||||
endpoint: xamarin
|
||||
|
||||
trigger:
|
||||
branches:
|
||||
include:
|
||||
- Localization
|
||||
|
||||
stages:
|
||||
|
||||
- ${{ if eq(parameters.runGovernanceTests, true) }}:
|
||||
- stage: governance_checks
|
||||
displayName: 'Governance Checks'
|
||||
jobs:
|
||||
- job: governance
|
||||
displayName: 'Governance Checks'
|
||||
pool:
|
||||
vmImage: windows-latest
|
||||
steps:
|
||||
- template: templates/governance-checks.yml
|
||||
parameters:
|
||||
isPR: false
|
||||
repositoryAlias: self
|
||||
commit: HEAD
|
||||
|
||||
- job: BringLocChanges
|
||||
displayName: 'Copy over the lcl file changes from Localization branch'
|
||||
pool:
|
||||
vmImage: windows-latest
|
||||
steps:
|
||||
|
||||
- pwsh: |
|
||||
git remote remove origin
|
||||
git remote add origin https://$(GitHub.Token)@github.com/xamarin/xamarin-macios.git
|
||||
git remote # don't add -v else we see the pat
|
||||
|
||||
git config user.email "valco@microsoft.com"
|
||||
git config user.name "vs-mobiletools-engineering-service2"
|
||||
|
||||
git fetch origin
|
||||
|
||||
gh pr create \
|
||||
--title "Bring changes from Localization branch #$(Build.BuildNumber)" \
|
||||
--body "The OneLoc team creates these translations to be consumed later on in the second step of the Localization process. We need to bring these into the main branch in order to continue the process." \
|
||||
--base main \
|
||||
--head Localization \
|
||||
--draft=false
|
||||
|
||||
name: BringLocChanges
|
||||
displayName: "BringLocChanges"
|
||||
workingDirectory: $(System.DefaultWorkingDirectory)
|
||||
condition: startsWith(variables['Build.SourceVersionMessage'], 'LEGO')
|
||||
env:
|
||||
GITHUB_TOKEN: $(GitHub.Token)
|
|
@ -10,6 +10,15 @@ steps:
|
|||
parameters:
|
||||
CleanseProcesses: true
|
||||
|
||||
- bash: |
|
||||
set -x
|
||||
set -e
|
||||
ssh-keygen -R github.com
|
||||
echo "github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl" >> ~/.ssh/known_hosts
|
||||
echo "github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=" >> ~/.ssh/known_hosts
|
||||
echo "github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=" >> ~/.ssh/known_hosts
|
||||
displayName: 'Fix GitHub SSH host key'
|
||||
|
||||
- bash: cd $(System.DefaultWorkingDirectory)/xamarin-macios/ && git clean -xdf
|
||||
displayName: 'Clean workspace'
|
||||
|
||||
|
|
|
@ -32,10 +32,6 @@ parameters:
|
|||
type: boolean
|
||||
default: true
|
||||
|
||||
- name: runTranslations
|
||||
type: boolean
|
||||
default: true
|
||||
|
||||
- name: runSamples
|
||||
type: boolean
|
||||
default: false
|
||||
|
@ -202,18 +198,6 @@ stages:
|
|||
repositoryAlias: ${{ parameters.repositoryAlias }}
|
||||
commit: ${{ parameters.commit }}
|
||||
|
||||
- ${{ if and(eq(parameters.runTranslations, true), eq(variables['Build.SourceBranch'], 'refs/heads/main')) }}:
|
||||
- job: translations
|
||||
displayName: 'Loc translations'
|
||||
pool:
|
||||
vmImage: windows-latest
|
||||
steps:
|
||||
- template: loc-translations.yml
|
||||
parameters:
|
||||
isPR: ${{ parameters.isPR }}
|
||||
repositoryAlias: ${{ parameters.repositoryAlias }}
|
||||
commit: ${{ parameters.commit }}
|
||||
|
||||
|
||||
- ${{ if parameters.isPR }}:
|
||||
- stage: clean
|
||||
|
|
Загрузка…
Ссылка в новой задаче