Merge remote-tracking branch 'origin/main' into bump-main-in-net8.0-2023-03-14

This commit is contained in:
Rolf Bjarne Kvinge 2023-03-27 19:53:33 +02:00
Родитель 7acd23109e b18212ac8d
Коммит 226a5f198f
20 изменённых файлов: 1047 добавлений и 358 удалений

Просмотреть файл

@ -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. -->

2
external/Touch.Unit поставляемый

@ -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