protected override Expression VisitTypeDefinitionExpression(TypeDefinitionExpression expression)
        {
            var includeExpressions = new List <Expression>
            {
                FickleExpression.Include(expression.Type.Name + ".h")
            };

            var comment = new CommentExpression("This file is AUTO GENERATED");

            var referencedTypes = ReferencedTypesCollector.CollectReferencedTypes(expression);

            referencedTypes.Sort((x, y) => String.Compare(x.Name, y.Name, StringComparison.InvariantCultureIgnoreCase));

            foreach (var referencedType in referencedTypes.Where(ObjectiveBinderHelpers.TypeIsServiceClass))
            {
                includeExpressions.Add(FickleExpression.Include(referencedType.Name + ".h"));
            }

            var headerGroup = includeExpressions.ToStatementisedGroupedExpression();
            var header = new Expression[] { comment, headerGroup }.ToStatementisedGroupedExpression(GroupedExpressionsExpressionStyle.Wide);

            var methods = new List <Expression>
            {
                this.CreateInitMethod(expression),
                this.CreateAllPropertiesAsDictionaryMethod(expression),
                this.CreateScalarPropertiesAsFormEncodedStringMethod(expression),
                this.CreateCopyWithZoneMethod(expression),
            };

            var body = methods.ToStatementisedGroupedExpression(GroupedExpressionsExpressionStyle.Wide);

            return(new TypeDefinitionExpression(expression.Type, header, body, false, expression.Attributes, expression.InterfaceTypes));
        }
Beispiel #2
0
        protected override Expression VisitTypeDefinitionExpression(TypeDefinitionExpression expression)
        {
            try
            {
                currentTypeDefinition = expression;

                var body = this.Visit(expression.Body);

                var include = FickleExpression.Include("Foundation/Foundation.h");

                var comment = new CommentExpression("This file is AUTO GENERATED");
                var header = new Expression[] { comment, include }.ToStatementisedGroupedExpression(GroupedExpressionsExpressionStyle.Wide);

                return(FickleExpression.GroupedWide
                       (
                           new TypeDefinitionExpression(expression.Type, header, body, false, expression.Attributes, expression.InterfaceTypes),
                           this.CreateTryParseMethod(),
                           this.CreateToStringMethod()
                       ));
            }
            finally
            {
                currentTypeDefinition = null;
            }
        }
        private Expression CreateScalarPropertiesAsFormEncodedStringMethod(TypeDefinitionExpression expression)
        {
            var self       = Expression.Parameter(expression.Type, "self");
            var properties = ExpressionGatherer.Gather(expression, ServiceExpressionType.PropertyDefinition).Where(c => !(c.Type is FickleListType)).ToList();
            var parameters = properties.OfType <PropertyDefinitionExpression>().ToDictionary(c => c.PropertyName, c => Expression.Property(self, c.PropertyName));
            var path       = string.Join("", properties.OfType <PropertyDefinitionExpression>().Select(c => c.PropertyName + "={" + c.PropertyName + "}"));

            var formatInfo = ObjectiveStringFormatInfo.GetObjectiveStringFormatInfo
                             (
                path,
                c => parameters[c],
                (s, t) => t == typeof(string) ? s : s + "&",
                c => FickleExpression.Call(c, typeof(string), "stringByAppendingString", Expression.Constant("&"))
                             );

            var parameterInfos = new List <ParameterInfo>
            {
                new FickleParameterInfo(typeof(string), "format")
            };

            parameterInfos.AddRange(formatInfo.ParameterExpressions.Select(c => new ObjectiveParameterInfo(c.Type, c.Name, true)));

            var args = new List <Expression>
            {
                Expression.Constant(formatInfo.Format)
            };

            args.AddRange(formatInfo.ValueExpressions);

            var methodInfo = new FickleMethodInfo(typeof(string), typeof(string), "stringWithFormat", parameterInfos.ToArray(), true);
            var methodBody = Expression.Block(FickleExpression.Return(Expression.Call(null, methodInfo, args)).ToStatement());

            return(new MethodDefinitionExpression("scalarPropertiesAsFormEncodedString", new List <Expression>().ToReadOnlyCollection(), typeof(string), methodBody, false, null));
        }
Beispiel #4
0
        protected override Expression VisitTypeDefinitionExpression(TypeDefinitionExpression expression)
        {
            currentTypeDefinition = expression;
            currentType           = expression.Type;
            var referencedTypes = ReferencedTypesCollector.CollectReferencedTypes(expression);

            referencedTypes.Sort((x, y) => string.Compare(x.Name, y.Name, StringComparison.InvariantCultureIgnoreCase));

            var includeExpressions = new List <IncludeExpression>();

            var lookup = new HashSet <Type>(referencedTypes.Where(TypeSystem.IsPrimitiveType));

            if (lookup.Contains(typeof(Guid)) || lookup.Contains(typeof(Guid?)))
            {
                includeExpressions.Add(FickleExpression.Include("java.util.UUID"));
            }

            if (lookup.Contains(typeof(TimeSpan)) || lookup.Contains(typeof(TimeSpan?)))
            {
                includeExpressions.Add(FickleExpression.Include("java.util.Date"));
            }

            var comment             = new CommentExpression("This file is AUTO GENERATED");
            var namespaceExpression = new NamespaceExpression(codeGenerationContext.Options.Namespace);

            var members = new List <Expression>()
            {
                this.Visit(expression.Body)
            };

            if (((FickleType)currentTypeDefinition.Type).ServiceClass.Properties.Count > 0)
            {
                includeExpressions.Add(FickleExpression.Include("android.util.JsonReader"));
                includeExpressions.Add(FickleExpression.Include("android.util.JsonToken"));
                includeExpressions.Add(FickleExpression.Include("com.jaigo.androiddevkit.*"));
                includeExpressions.Add(FickleExpression.Include("com.jaigo.androiddevkit.utils.*"));
                includeExpressions.Add(FickleExpression.Include("java.lang.Exception"));
                includeExpressions.Add(FickleExpression.Include("java.io.InputStream"));
                includeExpressions.Add(FickleExpression.Include("java.io.InputStreamReader"));
                includeExpressions.Add(FickleExpression.Include("java.util.ArrayList"));

                members.Add(CreateDeserializeStreamMethod());
                members.Add(CreateDeserializeReaderMethod());
                members.Add(CreateDeserializeElementMethod());
                members.Add(CreateSerializeMethod());
            }

            if (CurrentTypeIsResponseType())
            {
                members.Add(CreateCreateErrorResponseMethod());
            }

            var headerGroup = includeExpressions.ToStatementisedGroupedExpression();
            var header = new Expression[] { comment, namespaceExpression, headerGroup }.ToStatementisedGroupedExpression(GroupedExpressionsExpressionStyle.Wide);

            var body = fieldDefinitionsForProperties.Concat(members).ToStatementisedGroupedExpression(GroupedExpressionsExpressionStyle.Wide);

            return(new TypeDefinitionExpression(expression.Type, header, body, false, expression.Attributes, expression.InterfaceTypes));
        }
        public static Expression Build(TypeDefinitionExpression expression, CodeGenerationContext context)
        {
            var builder = new PropertiesToDictionaryExpressionBinder(expression.Type, context);

            builder.Visit(expression);

            return(builder.propertySetterExpressions.ToStatementisedGroupedExpression(GroupedExpressionsExpressionStyle.Wide));
        }
        public static Expression Bind(CodeGenerationContext codeGenerationContext, TypeDefinitionExpression expression, ParameterExpression zone, ParameterExpression theCopy)
        {
            var builder = new PropertiesToCopyExpressionBinder(codeGenerationContext, expression.Type, zone, theCopy);

            builder.Visit(expression);

            return(builder.statements.ToStatementisedGroupedExpression());
        }
Beispiel #7
0
        protected override Expression VisitTypeDefinitionExpression(TypeDefinitionExpression expression)
        {
            var comment = new CommentExpression("This file is AUTO GENERATED");
            var header = new Expression[] { comment }.ToStatementisedGroupedExpression(GroupedExpressionsExpressionStyle.Wide);

            var typeDefinitionExpression = new TypeDefinitionExpression(expression.Type, null, expression.Body, false, expression.Attributes, expression.InterfaceTypes);

            return(new NamespaceExpression(this.codeGenerationContext.Options.Namespace, header, typeDefinitionExpression));
        }
Beispiel #8
0
        protected override Expression VisitTypeDefinitionExpression(TypeDefinitionExpression expression)
        {
            currentTypeDefinitionExpression = expression;
            currentReturnTypes = new HashSet <Type>(ReturnTypesCollector.CollectReturnTypes(expression));

            var includeExpressions = new List <IncludeExpression>
            {
                FickleExpression.Include("java.util.ArrayList"),
                FickleExpression.Include("com.jaigo.androiddevkit.DefaultJsonBuilder"),
                FickleExpression.Include("com.jaigo.androiddevkit.RequestCallback"),
                FickleExpression.Include("com.jaigo.androiddevkit.utils.ConvertUtils"),
                FickleExpression.Include("com.jaigo.androiddevkit.WebServiceClient")
            };

            var comment = new CommentExpression("This file is AUTO GENERATED");

            var client = new FieldDefinitionExpression("webServiceClient", webServiceClientType, AccessModifiers.Private | AccessModifiers.Constant);

            var body = GroupedExpressionsExpression.FlatConcat
                       (
                GroupedExpressionsExpressionStyle.Wide,
                client,
                CreateDefaultConstructor(),
                CreateParameterisedConstructor(),
                this.Visit(expression.Body)
                       );

            var singleValueResponseTypes = currentReturnTypes.Where(c => c.GetUnwrappedNullableType().IsPrimitive).Select(c => FickleType.Define(JavaBinderHelpers.GetValueResponseWrapperTypeName(c))).ToList();

            var referencedTypes = ReferencedTypesCollector.CollectReferencedTypes(body).Concat(singleValueResponseTypes).Distinct().ToList();

            referencedTypes.Sort((x, y) => String.Compare(x.Name, y.Name, StringComparison.InvariantCultureIgnoreCase));

            var lookup = new HashSet <Type>(referencedTypes.Where(TypeSystem.IsPrimitiveType));

            if (lookup.Contains(typeof(FickleListType)))
            {
                includeExpressions.Add(FickleExpression.Include("java.util.ArrayList"));
            }

            if (lookup.Contains(typeof(Guid)) || lookup.Contains(typeof(Guid?)))
            {
                includeExpressions.Add(FickleExpression.Include("java.util.UUID"));
            }

            if (lookup.Contains(typeof(DateTime)) || lookup.Contains(typeof(DateTime?)))
            {
                includeExpressions.Add(FickleExpression.Include("java.util.Date"));
            }

            var headerGroup         = includeExpressions.Sorted(IncludeExpression.Compare).ToGroupedExpression();
            var namespaceExpression = new NamespaceExpression(CodeGenerationContext.Options.Namespace);

            var header = new Expression[] { comment, namespaceExpression, headerGroup }.ToGroupedExpression(GroupedExpressionsExpressionStyle.Wide);

            return(new TypeDefinitionExpression(expression.Type, header, body, false, expression.Attributes, expression.InterfaceTypes));
        }
        protected override Expression VisitTypeDefinitionExpression(TypeDefinitionExpression expression)
        {
            if (expression.Header != null)
            {
                this.Visit(expression.Header);
                this.WriteLine();
                this.WriteLine();
            }

            var fickleType = expression.Type as FickleType;

            if (fickleType != null && fickleType.IsClass)
            {
                this.Write("public class ");
                this.Write(expression.Type.Name, true);

                if (expression.Type.BaseType != null && expression.Type.BaseType != typeof(Object))
                {
                    this.Write(" : ");
                    this.Write(expression.Type.BaseType, true);
                }

                this.WriteLine();

                using (this.AcquireIndentationContext(BraceLanguageStyleIndentationOptions.IncludeBracesNewLineAfter))
                {
                    this.Visit(expression.Body);
                    this.WriteLine();
                }
            }
            else if (fickleType != null && fickleType.BaseType == typeof(Enum))
            {
                this.WriteLine("public enum " + expression.Type.Name);

                using (this.AcquireIndentationContext(BraceLanguageStyleIndentationOptions.IncludeBracesNewLineAfter))
                {
                    var expressions = ((GroupedExpressionsExpression)expression.Body).Expressions;

                    var i = 0;
                    foreach (Expression rootExpression in expressions)
                    {
                        i++;

                        this.Visit(rootExpression);

                        if (i < expressions.Count)
                        {
                            this.Write(',');
                        }

                        this.WriteLine();
                    }
                }
            }

            return(expression);
        }
        public static Expression Bind(TypeDefinitionExpression expression, out int count)
        {
            var builder = new PropertiesFromDictionaryExpressonBinder(expression.Type);

            builder.Visit(expression);

            count = builder.propertyGetterExpressions.Count;

            return(builder.propertyGetterExpressions.ToStatementisedGroupedExpression(GroupedExpressionsExpressionStyle.Wide));
        }
Beispiel #11
0
        protected override Expression VisitTypeDefinitionExpression(TypeDefinitionExpression expression)
        {
            try
            {
                currentTypeDefinition = expression;
                currentType           = expression.Type;

                enumValueField = new FieldDefinitionExpression("value", typeof(int), AccessModifiers.Private | AccessModifiers.Constant);

                var includeExpressions = new List <Expression>()
                {
                    FickleExpression.Include("android.util.JsonReader"),
                    FickleExpression.Include("com.jaigo.androiddevkit.DefaultJsonBuilder"),
                    FickleExpression.Include("java.util.ArrayList")
                };

                var referencedTypes = ReferencedTypesCollector.CollectReferencedTypes(expression);
                referencedTypes.Sort((x, y) => String.Compare(x.Name, y.Name, StringComparison.InvariantCultureIgnoreCase));

                if (!codeGenerationContext.Options.SerializeEnumsAsStrings)
                {
                    includeExpressions.Add(FickleExpression.Include("com.jaigo.androiddevkit.utils.ConvertUtils"));
                }

                var includeStatements = includeExpressions.ToStatementisedGroupedExpression();

                var comment = new CommentExpression("This file is AUTO GENERATED");
                var namespaceExpression = new NamespaceExpression(codeGenerationContext.Options.Namespace);
                var header = new Expression[] { comment, namespaceExpression, includeStatements }.ToStatementisedGroupedExpression(GroupedExpressionsExpressionStyle.Wide);

                var bodyExpressions = new List <Expression>()
                {
                    expression.Body,
                    enumValueField,
                    CreateConstructor(),
                    CreateDeserializeMethod(),
                    CreateDeserializeArrayMethod(),
                    CreateSerializeMethod(),
                    JavaBinderHelpers.CreateSerializeArrayMethod(currentType)
                };

                var body = new GroupedExpressionsExpression(bodyExpressions);

                return(new TypeDefinitionExpression(expression.Type, header, body, false, expression.Attributes, expression.InterfaceTypes));
            }
            finally
            {
                currentTypeDefinition = null;
            }
        }
        private Expression CreateAllPropertiesAsDictionaryMethod(TypeDefinitionExpression expression)
        {
            var dictionaryType   = new FickleType("NSMutableDictionary");
            var retvalExpression = Expression.Parameter(dictionaryType, "retval");

            IEnumerable <ParameterExpression> variables = new[]
            {
                retvalExpression
            };

            var newDictionaryExpression    = Expression.Assign(retvalExpression, FickleExpression.New("NSMutableDictionary", "initWithCapacity", ExpressionTypeCounter.Count(expression, (ExpressionType)ServiceExpressionType.PropertyDefinition) * 2)).ToStatement();
            var makeDictionaryExpression   = PropertiesToDictionaryExpressionBinder.Build(expression, this.codeGenerationContext);
            var returnDictionaryExpression = Expression.Return(Expression.Label(), Expression.Parameter(dictionaryType, "retval")).ToStatement();

            var methodBody = Expression.Block(variables, GroupedExpressionsExpression.FlatConcat(GroupedExpressionsExpressionStyle.Wide, newDictionaryExpression, makeDictionaryExpression, returnDictionaryExpression));

            return(new MethodDefinitionExpression("allPropertiesAsDictionary", new List <Expression>().ToReadOnlyCollection(), dictionaryType, methodBody, false, null));
        }
        private MethodDefinitionExpression CreateInitMethod(TypeDefinitionExpression expression)
        {
            var        type = expression.Type;
            Expression superInitExpression;

            var parameters = new List <Expression>
            {
                Expression.Parameter(new FickleType("NSDictionary"), "properties")
            };

            var methodBodyExpressions = new List <Expression>();

            if (type.BaseType.IsServiceType())
            {
                superInitExpression = Expression.Call(Expression.Parameter(type.BaseType, "super"), new FickleMethodInfo(type.BaseType, type, "initWithPropertyDictionary", new [] { new FickleParameterInfo(parameters[0].Type, "dictionary") }), parameters[0]);
            }
            else
            {
                superInitExpression = Expression.Call(Expression.Parameter(type.BaseType, "super"), new FickleMethodInfo(type.BaseType, type, "init", new ParameterInfo[0]));
            }

            var assignExpression        = Expression.Assign(Expression.Parameter(type, "self"), superInitExpression);
            var compareToNullExpression = Expression.ReferenceEqual(assignExpression, Expression.Constant(null, type));
            int count;

            methodBodyExpressions.Add(Expression.IfThen(compareToNullExpression, Expression.Block(Expression.Return(Expression.Label(), Expression.Constant(null)).ToStatement())));
            methodBodyExpressions.Add(PropertiesFromDictionaryExpressonBinder.Bind(expression, out count));
            methodBodyExpressions.Add(Expression.Return(Expression.Label(), Expression.Parameter(type, "self")).ToStatement());

            IEnumerable <ParameterExpression> variables;

            if (count > 0)
            {
                variables = new[] { Expression.Parameter(FickleType.Define("id"), "currentValueFromDictionary") };
            }
            else
            {
                variables = new ParameterExpression[0];
            }

            var methodBody = Expression.Block(variables, (Expression)methodBodyExpressions.ToStatementisedGroupedExpression(GroupedExpressionsExpressionStyle.Wide));

            return(new MethodDefinitionExpression("initWithPropertyDictionary", parameters.ToReadOnlyCollection(), typeof(object), methodBody, false, null));
        }
        protected virtual Expression VisitTypeDefinitionExpression(TypeDefinitionExpression expression)
        {
            Expression header = null, body = null;

            if (expression.Header != null)
            {
                header = this.Visit(expression.Header);
            }

            if (expression.Body != null)
            {
                body = this.Visit(expression.Body);
            }

            if (header != expression.Header || body != expression.Body)
            {
                return(new TypeDefinitionExpression(expression.Type, header, body, expression.IsPredeclaration, expression.Attributes, expression.InterfaceTypes));
            }

            return(expression);
        }
Beispiel #15
0
        protected override Expression VisitTypeDefinitionExpression(TypeDefinitionExpression expression)
        {
            currentTypeDefinitionExpression = expression;

            var comment = new CommentExpression("This file is AUTO GENERATED");

            var client = new FieldDefinitionExpression("webServiceClient", webServiceClientType, AccessModifiers.Private | AccessModifiers.Constant);

            var body = GroupedExpressionsExpression.FlatConcat
                       (
                GroupedExpressionsExpressionStyle.Wide,
                client,
                CreateDefaultConstructor(),
                CreateParameterisedConstructor(),
                this.Visit(expression.Body)
                       );

            var header = new Expression[] { comment }.ToGroupedExpression(GroupedExpressionsExpressionStyle.Wide);

            return(new TypeDefinitionExpression(expression.Type, header, body, false, expression.Attributes, expression.InterfaceTypes));
        }
        protected override Expression VisitTypeDefinitionExpression(TypeDefinitionExpression expression)
        {
            var comment = new CommentExpression("This file is AUTO GENERATED");

            var includeExpressions = new List <IncludeExpression>
            {
                FickleExpression.Include("System"),
                FickleExpression.Include("System.Collections.Generic")
            };

            foreach (var include in this.codeGenerationContext.Options.Includes)
            {
                includeExpressions.Add(FickleExpression.Include(include));
            }

            var headerGroup = includeExpressions.ToStatementisedGroupedExpression();
            var header = new Expression[] { comment, headerGroup }.ToStatementisedGroupedExpression(GroupedExpressionsExpressionStyle.Wide);

            var typeDefinitionExpression = new TypeDefinitionExpression(expression.Type, null, expression.Body, false, expression.Attributes, expression.InterfaceTypes);

            return(new NamespaceExpression(this.codeGenerationContext.Options.Namespace, header, typeDefinitionExpression));
        }
        protected override Expression VisitTypeDefinitionExpression(TypeDefinitionExpression expression)
        {
            this.currentTypeDefinitionExpression = expression;

            var includeExpressions = new List <IncludeExpression>
            {
                FickleExpression.Include("System"),
                FickleExpression.Include("System.Collections.Generic"),
                FickleExpression.Include("System.Threading.Tasks")
            };

            foreach (var include in this.CodeGenerationContext.Options.Includes)
            {
                includeExpressions.Add(FickleExpression.Include(include));
            }

            var comment = new CommentExpression("This file is AUTO GENERATED");

            var hostname = new FieldDefinitionExpression(HostnameFieldName, typeof(string), AccessModifiers.Public | AccessModifiers.Static | AccessModifiers.ReadOnly);
            var client   = new FieldDefinitionExpression(FickleApiClientFieldName, this.fickleApiClientType, AccessModifiers.Private | AccessModifiers.ReadOnly);

            var body = GroupedExpressionsExpression.FlatConcat
                       (
                GroupedExpressionsExpressionStyle.Wide,
                hostname,
                client,
                this.CreateStaticConstructor(),
                this.CreateParameterisedConstructor(),
                this.Visit(expression.Body)
                       );

            var headerGroup = includeExpressions.Sorted(IncludeExpression.Compare).ToGroupedExpression();

            var header = new Expression[] { comment, headerGroup }.ToGroupedExpression(GroupedExpressionsExpressionStyle.Wide);

            var typeDefinitionExpression = new TypeDefinitionExpression(expression.Type, null, body, false, expression.Attributes, expression.InterfaceTypes);

            return(new NamespaceExpression(this.CodeGenerationContext.Options.Namespace, header, typeDefinitionExpression));
        }
        private Expression CreateCopyWithZoneMethod(TypeDefinitionExpression expression)
        {
            var currentType = (FickleType)expression.Type;
            var zone        = FickleExpression.Parameter("NSZone", "zone");
            var self        = Expression.Parameter(currentType, "self");
            var theCopy     = Expression.Variable(expression.Type, "theCopy");

            Expression newExpression;

            if (expression.Type.BaseType == typeof(object))
            {
                newExpression = FickleExpression.Call(FickleExpression.Call(FickleExpression.Call(self, "Class", "class", null), "allocWithZone", zone), expression.Type, "init", null);
            }
            else
            {
                var super = FickleExpression.Variable(expression.Type.BaseType.Name, "super");

                newExpression = FickleExpression.Call(super, FickleType.Define("id"), "copyWithZone", zone);
            }

            var initTheCopy     = Expression.Assign(theCopy, newExpression).ToStatement();
            var returnStatement = Expression.Return(Expression.Label(), theCopy).ToStatement();
            var copyStatements  = PropertiesToCopyExpressionBinder.Bind(codeGenerationContext, expression, zone, theCopy);

            Expression methodBody = Expression.Block
                                    (
                new[] { theCopy },
                initTheCopy,
                FickleExpression.GroupedWide
                (
                    copyStatements,
                    returnStatement
                )
                                    );

            return(new MethodDefinitionExpression("copyWithZone", new Expression[] { zone }.ToReadOnlyCollection(), typeof(object), methodBody, false, null));
        }
Beispiel #19
0
 protected abstract void GenerateGateway(CodeGenerationContext codeGenerationContext, TypeDefinitionExpression expression);
Beispiel #20
0
        protected override void GenerateGateway(CodeGenerationContext codeGenerationContext, TypeDefinitionExpression expression)
        {
            using (var writer = this.GetTextWriterForFile(expression.Type.Name + ".js"))
            {
                var classFileExpression = GatewayExpressionBinder.Bind(codeGenerationContext, expression);

                var codeGenerator = new JavascriptCodeGenerator(writer);

                codeGenerator.Generate(classFileExpression);
            }
        }
Beispiel #21
0
 protected override void GenerateEnum(CodeGenerationContext codeGenerationContext, TypeDefinitionExpression expression)
 {
 }
Beispiel #22
0
        protected override Expression VisitTypeDefinitionExpression(TypeDefinitionExpression expression)
        {
            if (expression.Header != null)
            {
                this.Visit(expression.Header);
                this.WriteLine();
                this.WriteLine();
            }

            var fickleType = expression.Type as FickleType;

            if (fickleType != null && fickleType.IsClass)
            {
                this.Write("public class ");
                this.Write(expression.Type.Name, true);

                if (expression.Type.BaseType != null && expression.Type.BaseType != typeof(Object))
                {
                    this.Write(" extends ");
                    this.Write(expression.Type.BaseType, true);
                }

                this.WriteLine();

                using (this.AcquireIndentationContext(BraceLanguageStyleIndentationOptions.IncludeBracesNewLineAfter))
                {
                    this.Visit(expression.Body);
                    this.WriteLine();
                }
            }
            else if (fickleType != null && fickleType.BaseType == typeof(Enum))
            {
                this.WriteLine("public enum " + expression.Type.Name);

                using (this.AcquireIndentationContext(BraceLanguageStyleIndentationOptions.IncludeBracesNewLineAfter))
                {
                    var expressions = ((GroupedExpressionsExpression)expression.Body).Expressions;

                    var i = 0;

                    foreach (Expression rootExpression in expressions)
                    {
                        if (rootExpression is GroupedExpressionsExpression)
                        {
                            var binaryExpressions = ((GroupedExpressionsExpression)rootExpression).Expressions;

                            foreach (Expression binaryExpression in binaryExpressions)
                            {
                                var assignment = (BinaryExpression)binaryExpression;

                                this.Write(((ParameterExpression)assignment.Left).Name);
                                this.Write("(");
                                this.Visit(assignment.Right);
                                this.Write(")");

                                if (i++ != binaryExpressions.Count - 1)
                                {
                                    this.WriteLine(',');
                                }
                                else
                                {
                                    this.WriteLine(';');
                                }
                            }
                        }
                        else
                        {
                            this.Visit(rootExpression);
                        }

                        this.WriteLine();
                    }
                }
            }

            return(expression);
        }
        protected override Expression VisitTypeDefinitionExpression(TypeDefinitionExpression expression)
        {
            this.currentType = expression.Type;
            this.currentTypeDefinitionExpression = expression;
            this.currentReturnTypes = new HashSet <Type>(ReturnTypesCollector.CollectReturnTypes(expression));

            var includeExpressions = new List <IncludeExpression>
            {
                FickleExpression.Include(expression.Type.Name + ".h"),
                FickleExpression.Include("PKWebServiceClient.h"),
                FickleExpression.Include("NSArray+PKExtensions.h"),
                FickleExpression.Include(this.CodeGenerationContext.Options.ResponseStatusTypeName + ".h")
            };

            var comment = new CommentExpression("This file is AUTO GENERATED");

            var expressions = new List <Expression>
            {
                CreateCreateClientMethod(),
                CreateInitMethod(),
                CreateInitWithOptionsMethod()
            };

            var rawParameterTypes = ParameterTypesCollector
                                    .Collect(expression, c => c.Attributes["Method"].EqualsIgnoreCase("post") && c.Attributes.ContainsKey("Content"))
                                    .Select(c => new Tuple <Type, string>(c.Item1.GetFickleListElementType() ?? c.Item1, c.Item2))
                                    .Select(c => new Tuple <Type, string>(c.Item1.GetUnwrappedNullableType(), c.Item2))
                                    .Distinct();

            foreach (var value in rawParameterTypes
                     .Select(c => new { Type = c.Item1, Name = this.GetNormalizeRequestMethodName(c.Item1, c.Item2), Format = c.Item2 })
                     .GroupBy(c => c.Name)
                     .Select(c => c.First()))
            {
                var type   = value.Type;
                var format = value.Format;

                expressions.Add(this.CreateNormalizeRequestObjectMethod(type, format));
            }

            expressions.Add(this.Visit(expression.Body));

            if (methodCount > 0)
            {
                expressions.Add(this.CreateCreateErrorResponseWithErrorCodeMethod());
                expressions.Add(this.CreateParseResultMethod());
            }

            expressions.Add(this.CreateSerializeRequestMethod());

            var body = GroupedExpressionsExpression.FlatConcat
                       (
                GroupedExpressionsExpressionStyle.Wide,
                expressions.ToArray()
                       );

            var singleValueResponseTypes = currentReturnTypes.Where(c => c.GetUnwrappedNullableType().IsPrimitive).Select(c => FickleType.Define(ObjectiveBinderHelpers.GetValueResponseWrapperTypeName(c))).ToList();

            var referencedTypes = ReferencedTypesCollector.CollectReferencedTypes(body).Concat(singleValueResponseTypes).Distinct().ToList();

            referencedTypes.Sort((x, y) => string.Compare(x.Name, y.Name, StringComparison.InvariantCultureIgnoreCase));

            foreach (var referencedType in referencedTypes.Where(c => (c as FickleType)?.ServiceClass != null))
            {
                includeExpressions.Add(FickleExpression.Include(referencedType.Name + ".h"));
            }

            var headerGroup = includeExpressions.Sorted(IncludeExpression.Compare).ToGroupedExpression();
            var header = new Expression[] { comment, headerGroup }.ToGroupedExpression(GroupedExpressionsExpressionStyle.Wide);

            this.currentType = null;

            return(new TypeDefinitionExpression(expression.Type, header, body, false, expression.Attributes));
        }
        protected override void GenerateGateway(CodeGenerationContext codeGenerationContext, TypeDefinitionExpression expression)
        {
            List <Expression> methods;

            using (var writer = this.GetTextWriterForFile(expression.Type.Name + ".m"))
            {
                var classFileExpression = GatewaySourceExpressionBinder.Bind(codeGenerationContext, expression);

                var codeGenerator = new ObjectiveCodeGenerator(writer);

                methods = ExpressionGatherer.Gather(classFileExpression, ServiceExpressionType.MethodDefinition);

                codeGenerator.Generate(classFileExpression);
            }

            using (var writer = this.GetTextWriterForFile(expression.Type.Name + ".h"))
            {
                var headerFileExpression = GatewayHeaderExpressionBinder.Bind(codeGenerationContext, expression, methods.Cast <MethodDefinitionExpression>().ToList());

                var codeGenerator = new ObjectiveCodeGenerator(writer);

                codeGenerator.Generate(headerFileExpression);
            }
        }
        protected override void GenerateClass(CodeGenerationContext codeGenerationContext, TypeDefinitionExpression expression)
        {
            using (var writer = this.GetTextWriterForFile(expression.Type.Name + ".h"))
            {
                var headerFileExpression = ClassHeaderExpressionBinder.Bind(codeGenerationContext, expression);

                var codeGenerator = new ObjectiveCodeGenerator(writer);

                codeGenerator.Generate(headerFileExpression);
            }

            using (var writer = this.GetTextWriterForFile(expression.Type.Name + ".m"))
            {
                var classFileExpression = ClassSourceExpressionBinder.Bind(codeGenerationContext, expression);

                var codeGenerator = new ObjectiveCodeGenerator(writer);

                codeGenerator.Generate(classFileExpression);
            }
        }
        protected override Expression VisitTypeDefinitionExpression(TypeDefinitionExpression expression)
        {
            var includeExpressions = new List <IncludeExpression>();
            var importExpressions  = new List <Expression>();
            var referencedTypes    = ReferencedTypesCollector.CollectReferencedTypes(expression);

            referencedTypes.Sort((x, y) => String.Compare(x.Name, y.Name, StringComparison.InvariantCultureIgnoreCase));

            var lookup = new HashSet <Type>(referencedTypes.Where(TypeSystem.IsPrimitiveType));

            if (!this.codeGenerationContext.Options.ImportDependenciesAsFramework)
            {
                if (lookup.Contains(typeof(Guid)) || lookup.Contains(typeof(Guid?)))
                {
                    includeExpressions.Add(FickleExpression.Include("PKUUID.h"));
                }

                if (lookup.Contains(typeof(TimeSpan)) || lookup.Contains(typeof(TimeSpan?)))
                {
                    includeExpressions.Add(FickleExpression.Include("PKTimeSpan.h"));
                }

                includeExpressions.Add(FickleExpression.Include("PKDictionarySerializable.h"));
                includeExpressions.Add(FickleExpression.Include("PKFormEncodingSerializable.h"));
            }
            else
            {
                importExpressions.Add(new CodeLiteralExpression(c => c.WriteLine("@import PlatformKit;")));
            }

            if (ObjectiveBinderHelpers.TypeIsServiceClass(expression.Type.BaseType))
            {
                includeExpressions.Add(FickleExpression.Include(expression.Type.BaseType.Name + ".h"));
            }

            includeExpressions.AddRange(referencedTypes.Where(c => c.IsEnum).Select(c => FickleExpression.Include(c.Name + ".h")));

            includeExpressions.Sort(IncludeExpression.Compare);

            var comment = new CommentExpression("This file is AUTO GENERATED");

            var headerExpressions = new List <Expression>()
            {
                new[] { comment }.ToStatementisedGroupedExpression(),
                importExpressions.Count == 0 ? null : importExpressions.ToStatementisedGroupedExpression(),
                includeExpressions.ToStatementisedGroupedExpression()
            };

            var referencedTypeExpressions = referencedTypes
                                            .Where(ObjectiveBinderHelpers.TypeIsServiceClass)
                                            .Where(c => c != expression.Type.BaseType)
                                            .OrderBy(x => x.Name.Length)
                                            .ThenBy(x => x.Name)
                                            .Select(c => (Expression) new ReferencedTypeExpression(c)).ToList();

            if (referencedTypeExpressions.Count > 0)
            {
                headerExpressions.Add(referencedTypeExpressions.ToStatementisedGroupedExpression());
            }

            var header = headerExpressions.ToStatementisedGroupedExpression(GroupedExpressionsExpressionStyle.Wide);

            var propertyBody = this.Visit(expression.Body);

            var interfaceTypes = new List <Type>
            {
                FickleType.Define("NSCopying"),
                FickleType.Define("PKDictionarySerializable"),
                FickleType.Define("PKFormEncodingSerializable")
            };

            return(new TypeDefinitionExpression(expression.Type, header, propertyBody, true, expression.Attributes, interfaceTypes.ToReadOnlyCollection()));
        }
Beispiel #27
0
        protected override Expression VisitTypeDefinitionExpression(TypeDefinitionExpression expression)
        {
            this.AddType(expression.Type.BaseType);

            return(base.VisitTypeDefinitionExpression(expression));
        }
        protected override Expression VisitTypeDefinitionExpression(TypeDefinitionExpression expression)
        {
            if (expression.Header != null)
            {
                this.Visit(expression.Header);
                this.WriteLine();
            }

            var type = expression.Type as FickleType;

            if (type != null && type.IsClass)
            {
                if (!expression.IsPredeclaration)
                {
                    this.WriteLine("#pragma clang diagnostic push");
                    this.WriteLine("#pragma clang diagnostic ignored \"-Wparentheses\"");
                    this.WriteLine("#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"");
                    this.WriteLine();
                }

                if (expression.IsPredeclaration)
                {
                    this.Write("@interface ");
                    this.Write(expression.Type, true);
                    this.Write(" : ");
                    this.Write(expression.Type.BaseType, true);

                    if (expression.InterfaceTypes != null && expression.InterfaceTypes.Count > 0)
                    {
                        this.Write("<");
                        this.Write(expression.InterfaceTypes.Select(c => c.Name).ToList().JoinToString(", "));
                        this.Write(">");
                    }
                }
                else
                {
                    this.Write("@implementation ");
                    this.Write(expression.Type, true);
                }

                this.WriteLine();

                this.Visit(expression.Body);

                this.WriteLine("@end");
                this.WriteLine();

                if (!expression.IsPredeclaration)
                {
                    this.WriteLine("#pragma clang diagnostic pop");
                }
            }
            else if (type != null && type.BaseType == typeof(Enum))
            {
                this.Write($"typedef {(expression.Attributes.ContainsKey("flags") ? "NS_OPTIONS" : "NS_ENUM")}(NSInteger, ");
                this.Write(expression.Type);
                this.WriteLine(@")");

                using (this.AcquireIndentationContext(BraceLanguageStyleIndentationOptions.IncludeBraces))
                {
                    var expressions = ((GroupedExpressionsExpression)expression.Body).Expressions;

                    var i = 0;

                    foreach (var assignment in expressions.Cast <BinaryExpression>())
                    {
                        this.Write(((ParameterExpression)assignment.Left).Name);
                        this.Write(" = ");
                        this.Visit(assignment.Right);

                        if (i++ != expressions.Count - 1)
                        {
                            this.Write(',');
                        }

                        this.WriteLine();
                    }
                }

                this.WriteLine(";");
            }

            return(expression);
        }
        protected override Expression VisitTypeDefinitionExpression(TypeDefinitionExpression expression)
        {
            var includeExpressions = new List <IncludeExpression>();
            var importExpressions  = new List <Expression>();

            var optionsProperty        = new PropertyDefinitionExpression("options", FickleType.Define("NSDictionary"), true);
            var responseFilterProperty = new PropertyDefinitionExpression("responseFilter", FickleType.Define("FKGatewayResponseFilter", isInterface: true), true, new[] { "weak" });

            var body = FickleExpression.GroupedWide
                       (
                optionsProperty,
                responseFilterProperty,
                new GroupedExpressionsExpression(methods.Select(c => c.ChangePredeclaration(true)))
                       );

            var referencedTypes = ReferencedTypesCollector.CollectReferencedTypes(body);

            referencedTypes.Sort((x, y) => String.Compare(x.Name, y.Name, StringComparison.InvariantCultureIgnoreCase));

            var lookup = new HashSet <Type>(referencedTypes.Where(TypeSystem.IsPrimitiveType));

            if (!this.CodeGenerationContext.Options.ImportDependenciesAsFramework)
            {
                if (lookup.Contains(typeof(Guid)) || lookup.Contains(typeof(Guid?)))
                {
                    includeExpressions.Add(FickleExpression.Include("PKUUID.h"));
                }

                if (lookup.Contains(typeof(TimeSpan)) || lookup.Contains(typeof(TimeSpan?)))
                {
                    includeExpressions.Add(FickleExpression.Include("PKTimeSpan.h"));
                }

                includeExpressions.Add(FickleExpression.Include("PKWebServiceClient.h"));
                includeExpressions.Add(FickleExpression.Include("PKDictionarySerializable.h"));
            }
            else
            {
                importExpressions.Add(new CodeLiteralExpression(c => c.WriteLine("@import PlatformKit;")));
            }

            includeExpressions.Add(FickleExpression.Include("FKGatewayResponseFilter.h"));

            var referencedUserTypes = referencedTypes
                                      .Where(c => (c is FickleType && ((FickleType)c).ServiceClass != null) || c is FickleType && ((FickleType)c).ServiceEnum != null)
                                      .Sorted((x, y) => x.Name.Length == y.Name.Length ? String.CompareOrdinal(x.Name, y.Name) : x.Name.Length - y.Name.Length);

            includeExpressions.AddRange(referencedUserTypes.Select(c => FickleExpression.Include(c.Name + ".h")));

            var comment = new CommentExpression("This file is AUTO GENERATED");

            var header = new Expression[]
            {
                comment,
                importExpressions.Count == 0 ? null : importExpressions.ToStatementisedGroupedExpression(),
                includeExpressions.Sorted(IncludeExpression.Compare).ToStatementisedGroupedExpression()
            }.ToStatementisedGroupedExpression(GroupedExpressionsExpressionStyle.Wide);

            var interfaceTypes = new List <Type>();

            if (expression.InterfaceTypes != null)
            {
                interfaceTypes.AddRange(expression.InterfaceTypes);
            }

            interfaceTypes.Add(FickleType.Define("PKWebServiceClientDelegate"));

            return(new TypeDefinitionExpression(expression.Type, header, body, true, expression.Attributes, interfaceTypes.ToReadOnlyCollection()));
        }
        protected override void GenerateEnum(CodeGenerationContext codeGenerationContext, TypeDefinitionExpression expression)
        {
            using (var writer = this.GetTextWriterForFile(expression.Type.Name + ".java"))
            {
                var enumFileExpression = EnumExpressionBinder.Bind(codeGenerationContext, expression);

                var codeGenerator = new JavaCodeGenerator(writer);

                codeGenerator.Generate(enumFileExpression);
            }
        }