public override void VisitInvocationExpression(InvocationExpression invocationExpression)
        {
            var target = invocationExpression.Target as LiteralExpression;
            if (target == null)
                return;

            switch (target.Value) {
            case "Mac":
            case "MacAttribute":
                VisitShorthandIntroducedAttribute (invocationExpression, "PlatformName.MacOSX");
                break;
            case "Since":
            case "SinceAttribute":
            case "iOS":
            case "iOSAttribute":
                VisitShorthandIntroducedAttribute (invocationExpression, "PlatformName.iOS");
                break;
            case "Watch":
            case "WatchAttribute":
                VisitShorthandIntroducedAttribute (invocationExpression, "PlatformName.WatchOS");
                break;
            case "TV":
            case "TVAttribute":
                VisitShorthandIntroducedAttribute (invocationExpression, "PlatformName.TvOS");
                break;
            case "Availability":
            case "AvailabilityAttribute":
                VisitAvailabilityAttribute (invocationExpression);
                break;
            default:
                base.VisitInvocationExpression (invocationExpression);
                break;
            }
        }
 public void VisitInvocationExpression(InvocationExpression invocationExpression)
 {
     invocationExpression.Target.AcceptVisitor (this);
     writer.Write (" (");
     bool first = true;
     foreach (var child in invocationExpression.Arguments) {
         if (!first)
             writer.Write (", ");
         first = false;
         child.AcceptVisitor (this);
     }
     writer.Write (')');
 }
            public override void VisitLiteralExpression(LiteralExpression literalExpression)
            {
                var parts = literalExpression?.Value?.Split ('_');
                if (parts == null || parts.Length < 2)
                    return;

                string platformName;
                switch (parts [0]) {
                case "Platform.Mac":
                    platformName = "PlatformName.MacOSX";
                    break;
                case "Platform.iOS":
                    platformName = "PlatformName.iOS";
                    break;
                default:
                    return;
                }

                if (currentAvailability == null) {
                    switch (originalArgIndex) {
                    case 0:
                        currentAvailability = "Introduced";
                        break;
                    case 1:
                        currentAvailability = "Deprecated";
                        break;
                    case 2:
                        currentAvailability = "Obsoleted";
                        break;
                    case 3:
                        currentAvailability = "Unavailable";
                        break;
                    }
                }

                var attr = new InvocationExpression (currentAvailability);
                attr.AddArgument (new LiteralExpression (platformName));

                if (parts.Length == 2) {
                    switch (parts [1]) {
                    case "Version":
                        break;
                    case "Arch32":
                        attr.AddArgument (new LiteralExpression ("PlatformArchitecture.Arch32"));
                        break;
                    case "Arch64":
                        attr.AddArgument (new LiteralExpression ("PlatformArchitecture.Arch64"));
                        break;
                    }
                } else {
                    for (int i = 1; i < parts.Length; i++)
                        attr.AddArgument (new LiteralExpression (parts [i]));
                }

                invocations.Add (attr);
            }
            public void ProcessAvailabilityAttribute(InvocationExpression invocationExpression)
            {
                originalArgIndex = 0;
                message = null;
                invocations.Clear ();

                foreach (var arg in invocationExpression.Arguments) {
                    currentAvailability = null;

                    arg.AcceptVisitor (this);

                    foreach (var newAttr in invocations) {
                        if (message != null)
                            newAttr.AddArgument (new NamedExpression (
                                new LiteralExpression ("message"),
                                TokenType.Colon,
                                new LiteralExpression (message)
                            ));

                        invocationExpression.Parent.InsertChildBefore (
                            invocationExpression, newAttr);
                    }

                    originalArgIndex++;
                }

                invocationExpression.Remove ();
            }
 void VisitAvailabilityAttribute(InvocationExpression invocationExpression)
 {
     new AvailabilityAttributeVisitor ().ProcessAvailabilityAttribute (invocationExpression);
 }
 static void VisitShorthandUnavailableAttribute(LiteralExpression oldAttr, string platformName)
 {
     var newAttr = new InvocationExpression ("Unavailable");
     newAttr.AddArgument (new LiteralExpression (platformName));
     oldAttr.Parent.InsertChildBefore (oldAttr, newAttr);
     oldAttr.Remove ();
 }
        static void VisitShorthandIntroducedAttribute(InvocationExpression invocationExpression,
            string platformName)
        {
            bool isTripleVersion = invocationExpression.Arguments.Count () > 2 && invocationExpression.Arguments.Take (3).All (x => x is LiteralExpression && IsNumber(((LiteralExpression)x).Value));

            invocationExpression.Target = new LiteralExpression ("Introduced");

            invocationExpression.Parent.InsertChildBefore (
                invocationExpression.FirstArgument,
                new LiteralExpression (platformName),
                InvocationExpression.ArgumentRole
            );

            foreach (var onlyOn64 in invocationExpression.Arguments.Skip (isTripleVersion ? 4 : 3).Take (2)) {
                var onlyOn64BoolValue = onlyOn64 as LiteralExpression;
                if (onlyOn64 is NamedExpression)
                    onlyOn64BoolValue = onlyOn64.GetChild<Expression> (
                        BinaryExpression.RightOperandRole) as LiteralExpression;
                if (onlyOn64BoolValue != null && onlyOn64BoolValue.Value == "true")
                    invocationExpression.AddArgument (
                        new LiteralExpression ("PlatformArchitecture.Arch64"));
                if (onlyOn64BoolValue != null)
                    onlyOn64.Remove ();
            }
        }
 static void VisitMacNamedIntroducedAttribute(LiteralExpression oldAttr, string macMinorVersion)
 {
     var newAttr = new InvocationExpression ("Introduced");
     newAttr.AddArgument (new LiteralExpression ("PlatformName.MacOSX"));
     newAttr.AddArgument (new LiteralExpression ("10"));
     newAttr.AddArgument (new LiteralExpression (macMinorVersion));
     oldAttr.Parent.InsertChildBefore (oldAttr, newAttr);
     oldAttr.Remove ();
 }