static Attribute CreateMajorMinorAttribute(System.Type type, PlatformName platform, int major, int minor, byte arch, string message)
    {
        var ctorValues = new object [] { (byte)platform, major, minor, arch, message };
        var ctorTypes  = new System.Type [] { PlatformEnum, typeof(int), typeof(int), PlatformArch, typeof(string) };

        return(CreateNewAttribute(type, ctorTypes, ctorValues));
    }
    public static System.Attribute CreateUnavailableAttribute(PlatformName platformName, byte arch = 0xff, string message = null)
    {
        var ctorValues = new object [] { (byte)platformName, arch, message };
        var ctorTypes  = new System.Type [] { PlatformEnum, PlatformArch, typeof(string) };

        return(CreateNewAttribute(UnavailableAttributeType, ctorTypes, ctorValues));
    }
    static ParsedAvailabilityInfo DetermineOldAvailabilityVersion(CustomAttributeNamedArgument arg)
    {
        string enumName = Enum.GetName(typeof(Platform), (ulong)arg.TypedValue.Value);

        if (enumName == null)
        {
            throw new NotImplementedException($"Unknown version format \"{enumName}\" in DetermineOldAvailabilityVersion. Are there two values | togeather?");
        }

        string [] enumParts = enumName.Split(new char [] { '_' });
        switch (enumParts.Count())
        {
        case 1:
            if (enumName == "None")
            {
                return(new ParsedAvailabilityInfo(PlatformName.None));
            }
            break;

        case 2: {
            if (enumParts [1] != "Version")
            {
                break;
            }

            PlatformName platform = ParsePlatforName(enumParts [0]);
            if (platform == PlatformName.None)
            {
                break;
            }
            return(new ParsedAvailabilityInfo(platform));
        }

        case 3: {
            PlatformName platform = ParsePlatforName(enumParts [0]);
            if (platform == PlatformName.None)
            {
                break;
            }
            int major = int.Parse(enumParts [1]);
            int minor = int.Parse(enumParts [2]);

            return(new ParsedAvailabilityInfo(platform, major, minor));
        }
        }
        throw new NotImplementedException($"Unknown version format \"{enumName}\" in DetermineOldAvailabilityVersion");
    }
 public static System.Attribute CreateDeprecatedAttribute(PlatformName platform, int major, int minor, byte arch = 0xff, string message = null)
 {
     return(CreateMajorMinorAttribute(DeprecatedAttributeType, platform, major, minor, arch, message));
 }
 public ParsedAvailabilityInfo(PlatformName platform)
 {
     Platform = platform;
     Major    = -1;
     Minor    = -1;
 }
 public ParsedAvailabilityInfo(PlatformName platform, int major, int minor)
 {
     Platform = platform;
     Major    = major;
     Minor    = minor;
 }
    public static System.Attribute ConvertPlatformAttribute(CustomAttributeData attribute, PlatformName platform)
    {
        var constructorArguments = new object [attribute.ConstructorArguments.Count];

        for (int i = 0; i < attribute.ConstructorArguments.Count; ++i)
        {
            constructorArguments [i] = attribute.ConstructorArguments [i].Value;
        }

        Func <string> createErrorMessage = () => {
            var b = new System.Text.StringBuilder(" Types { ");
            for (int i = 0; i < constructorArguments.Length; ++i)
            {
                b.Append(constructorArguments[i].GetType().ToString() + " ");
            }
            b.Append("}");
            return(b.ToString());
        };

        Func <string> unknownFormatError = () => $"Unknown format for old style availability attribute {attribute.AttributeType.FullName} {attribute.ConstructorArguments.Count} {createErrorMessage ()}";

        object []      ctorValues;
        System.Type [] ctorTypes;

        switch (attribute.ConstructorArguments.Count)
        {
        case 2:
            if (constructorArguments [0].GetType() == typeof(byte) &&
                constructorArguments [1].GetType() == typeof(byte))
            {
                ctorValues = new object [] { (byte)platform, (int)(byte)constructorArguments [0], (int)(byte)constructorArguments [1], (byte)0xff, null };
                ctorTypes  = new System.Type [] { AttributeFactory.PlatformEnum, typeof(int), typeof(int), AttributeFactory.PlatformArch, typeof(string) };
                break;
            }
            throw new NotImplementedException(unknownFormatError());

        case 3:
            if (constructorArguments [0].GetType() == typeof(byte) &&
                constructorArguments [1].GetType() == typeof(byte) &&
                constructorArguments [2].GetType() == typeof(byte))
            {
                ctorValues = new object [] { (byte)platform, (int)(byte)constructorArguments [0], (int)(byte)constructorArguments [1], (int)(byte)constructorArguments [2], (byte)0xff, null };
                ctorTypes  = new System.Type [] { AttributeFactory.PlatformEnum, typeof(int), typeof(int), typeof(int), AttributeFactory.PlatformArch, typeof(string) };
                break;
            }
            if (constructorArguments [0].GetType() == typeof(byte) &&
                constructorArguments [1].GetType() == typeof(byte) &&
                constructorArguments [2].GetType() == typeof(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 System.Type [] { AttributeFactory.PlatformEnum, typeof(int), typeof(int), AttributeFactory.PlatformArch, typeof(string) };
                break;
            }
            throw new NotImplementedException(unknownFormatError());

        case 4:
            if (constructorArguments [0].GetType() == typeof(byte) &&
                constructorArguments [1].GetType() == typeof(byte) &&
                constructorArguments [2].GetType() == typeof(byte) &&
                constructorArguments [3].GetType() == typeof(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 System.Type [] { AttributeFactory.PlatformEnum, typeof(int), typeof(int), typeof(int), AttributeFactory.PlatformArch, typeof(string) };
                break;
            }
            if (constructorArguments [0].GetType() == typeof(byte) &&
                constructorArguments [1].GetType() == typeof(byte) &&
                constructorArguments [2].GetType() == typeof(byte) &&
                constructorArguments [3].GetType() == typeof(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 System.Type [] { AttributeFactory.PlatformEnum, typeof(int), typeof(int), typeof(int), AttributeFactory.PlatformArch, typeof(string) };
                break;
            }

            throw new NotImplementedException(unknownFormatError());

        default:
            throw new NotImplementedException($"Unknown count {attribute.ConstructorArguments.Count} {createErrorMessage ()}");
        }

        return(AttributeFactory.CreateNewAttribute(AttributeFactory.IntroducedAttributeType, ctorTypes, ctorValues));
    }