public static string GenerateCustomQueryOptions(JToken method, JToken fields, string entityName, string returns, string rootFilePath, string entityGroup, Compilation compilation)
        {
            var optionsName = $"{TypeHelpers.GetListOptionsName(entityName, returns)}ListOptions";

            var extraQueryParams = method["fields"].Where(
                q => q["in"].GetStringValue() == "query" &&
                q["_key"].GetStringValue() != "after" &&
                q["_key"].GetStringValue() != "include" &&
                q["_key"].GetStringValue() != "limit" &&
                q["_key"].GetStringValue() != "order"
                ).ToList();

            var customQueryOptions = new ClassContainer();

            // namespace
            customQueryOptions.Namespace = UsingKeys.FOUNDATION;

            // modifier (just public for now)
            customQueryOptions.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC);

            // name
            customQueryOptions.Name = optionsName;

            // base type
            customQueryOptions.AddBaseType("BASE_LIST_OPTIONS", "QueryOptions");
            customQueryOptions.AddUsing(nameof(UsingKeys.SDK_COMMON), UsingKeys.SDK_COMMON);

            // interface
            customQueryOptions.AddBaseType("BASE_LIST_OPTIONS_INTERFACE", $"I{customQueryOptions.Name}");

            // doc (just use the name for now)
            customQueryOptions.DocString = customQueryOptions.Name;

            // set the filepath root/groupId/Class/Class.cs
            customQueryOptions.FilePath = $"{rootFilePath}/{entityGroup}/{entityName}/";
            customQueryOptions.FileName = $"{customQueryOptions.Name}.cs";

            if (extraQueryParams.Count > 0)
            {
                extraQueryParams.ForEach(e =>
                {
                    var propContainer = new PropertyWithSummaryContainer
                    {
                        Name         = e["_key"].GetStringValue().ToPascal(),
                        PropertyType = "string",
                    };
                    propContainer.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC);
                    customQueryOptions.AddProperty(propContainer.Name, propContainer);
                });
            }

            var filter = method["x_filter"];

            if (filter.Any())
            {
                var filterPropertyContainer = new PropertyWithSummaryContainer
                {
                    Name         = "Filter",
                    PropertyType = "Filter",
                    DocString    = "Filter object",
                };
                filterPropertyContainer.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC);
                customQueryOptions.AddUsing(nameof(UsingKeys.FILTERS), UsingKeys.FILTERS);
                customQueryOptions.AddProperty(filterPropertyContainer.Name, filterPropertyContainer);

                foreach (var filterValue in filter)
                {
                    if (filterValue is JProperty filterValueProperty)
                    {
                        var filterValueName = filterValueProperty.Name;
                        var filterType      = "string";

                        var correspondingField = fields.FirstOrDefault(f => f["_key"].GetStringValue() == filterValueName);
                        if (correspondingField != null)
                        {
                            filterType = TypeHelpers.GetPropertyType(correspondingField, customQueryOptions);
                            if (filterType == "DateTime")
                            {
                                customQueryOptions.AddUsing(nameof(UsingKeys.SYSTEM), UsingKeys.SYSTEM);
                            }
                            // add usings for list
                            if (filterType.Contains("List<") || filterType.Contains("Dictionary<"))
                            {
                                customQueryOptions.AddUsing(nameof(UsingKeys.GENERIC_COLLECTIONS), UsingKeys.GENERIC_COLLECTIONS);
                            }
                        }

                        var filterOperators = filterValueProperty.Children().FirstOrDefault();
                        if (filterOperators != null)
                        {
                            filterOperators.Children().ToList().ForEach(f =>
                            {
                                var filterOperator          = f.GetStringValue();
                                string enumerableFilterType = null;
                                if (filterOperator == "in" || filterOperator == "nin")
                                {
                                    enumerableFilterType = $"{filterType}[]";
                                    customQueryOptions.AddUsing(nameof(UsingKeys.GENERIC_COLLECTIONS), UsingKeys.GENERIC_COLLECTIONS);
                                }
                                var methodName         = $"{filterValueName}{TypeHelpers.MapFilterName(filterOperator)}".ToPascal();
                                var filterMethodParams = new MethodParameterContainer
                                {
                                    Parameters = new List <ParameterContainer>()
                                    {
                                        new ParameterContainer
                                        {
                                            Key         = "value",
                                            ParamType   = enumerableFilterType ?? filterType,
                                            Required    = true,
                                            MyModifiers = !string.IsNullOrEmpty(enumerableFilterType)
                                                            ? new Dictionary <string, SyntaxToken> {
                                                { nameof(Modifiers.PARAMS), Modifiers.PARAMS }
                                            }
                                                            : new Dictionary <string, SyntaxToken>(),
                                        }
                                    }
                                };

                                var filterMethodContainer = new FilterExtensionMethodContainer
                                {
                                    Name           = methodName,
                                    Returns        = optionsName,
                                    MethodParams   = filterMethodParams,
                                    FilterKey      = filterValueName,
                                    FilterOperator = filterOperator,
                                };
                                filterMethodContainer.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC);
                                customQueryOptions.AddMethod(methodName, filterMethodContainer);
                            });
                        }
                    }
                }

                var customQueryOptionsConstructor = new ListOptionsConstructor
                {
                    Name = customQueryOptions.Name,
                };
                customQueryOptionsConstructor.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC);
                customQueryOptions.AddConstructor(nameof(customQueryOptionsConstructor), customQueryOptionsConstructor);
            }

            compilation.AddClass($"{entityGroup}-{entityName}-{returns}", customQueryOptions);

            var customQueryOptionsInterface = customQueryOptions.Copy();

            // entityRepositoryInterface.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC);
            customQueryOptionsInterface.Name        = $"I{optionsName}";
            customQueryOptionsInterface.FilePath    = $"{rootFilePath}/{entityGroup}/{entityName}/";
            customQueryOptionsInterface.FileName    = $"I{customQueryOptions.FileName}";
            customQueryOptionsInterface.IsInterface = true;
            customQueryOptionsInterface.BaseTypes.Clear();
            customQueryOptionsInterface.AddBaseType("BASE_LIST_OPTIONS_INTERFACE", "IQueryOptions");

            compilation.AddClass($"{entityGroup}-{entityName}-{returns}-interface", customQueryOptionsInterface);

            return(optionsName);
        }
Пример #2
0
        public static void GenerateEntityClass(JToken entity, string entityPascalName, string rootFilePath, string entityGroup, Compilation compilation)
        {
            var entityClass = new ClassContainer();

            // namespace
            entityClass.Namespace = UsingKeys.FOUNDATION;

            // modifier (just public for now)
            entityClass.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC);

            // name
            entityClass.Name = entityPascalName;

            // base type
            entityClass.AddBaseType("BASE_ENTITY", "Entity");
            entityClass.AddUsing(nameof(UsingKeys.SDK_COMMON), UsingKeys.SDK_COMMON);

            // add interface
            entityClass.AddBaseType("Interface", $"I{entityClass.Name}");

            // doc (just use the name for now)
            entityClass.DocString = entityClass.Name;

            // set the filepath root/groupId/Class/Class.cs
            entityClass.FilePath = $"{rootFilePath}/{entityGroup}/{entityClass.Name}/";
            entityClass.FileName = $"{entityClass.Name}.cs";

            // add rename dictionary if any
            if (entity["field_renames"].Count() > 0)
            {
                var renameContainer = new RenameContainer();
                foreach (var rename in entity["field_renames"])
                {
                    var left  = rename["_key"].GetStringValue().ToPascal();
                    var right = rename["api_fieldname"].GetStringValue();

                    renameContainer.AddRename(left, right);
                }

                entityClass.AddPrivateField("RENAMES", renameContainer);

                entityClass.AddUsing(nameof(UsingKeys.GENERIC_COLLECTIONS), UsingKeys.GENERIC_COLLECTIONS);
            }

            // get properties
            var properties = entity["fields"].Where(p => p["_key"].GetStringValue() != "id");

            foreach (var property in properties)
            {
                // extract info from config
                var name = property["_key"].GetStringValue().ToPascal();
                // docstring, fall back to name when no description is provided
                // TODO restore when multiline comment issue is solved
                // var docString = property["description"].GetStringValue() ?? property["_key"].GetStringValue();
                var docString = property["_key"].GetStringValue();

                var isReadOnly = property["readOnly"].GetBoolValue();

                // get type
                var propertyType = TypeHelpers.GetPropertyType(property, entityClass);

                var customGetter = property["getter_custom_method"] != null;
                var customSetter = property["setter_custom_method"] != null;

                var isNullable = isNullableType(propertyType, property);

                if (customGetter || customSetter)
                {
                    var overridePropContainer = new PropertyWithCustomGetterAndSetter
                    {
                        Name             = name,
                        DocString        = docString,
                        PropertyType     = propertyType,
                        GetAccessor      = customGetter,
                        SetAccessor      = customSetter,
                        CustomGetterName = property["getter_custom_method"].GetStringValue().ToPascal(),
                        CustomSetterName = property["setter_custom_method"].GetStringValue().ToPascal(),
                        IsNullable       = isNullable,
                    };

                    // can assume public
                    overridePropContainer.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC);

                    entityClass.AddProperty(name, overridePropContainer);
                    // need common for custom functions
                    entityClass.AddUsing(nameof(UsingKeys.SDK_COMMON), UsingKeys.SDK_COMMON);
                    entityClass.AddUsing(nameof(UsingKeys.JSON), UsingKeys.JSON);

                    var backingField = new PrivateFieldContainer
                    {
                        Name      = name.PascalToCamel(),
                        FieldType = propertyType,
                    };
                    backingField.AddModifier(nameof(Modifiers.INTERNAL), Modifiers.INTERNAL);

                    entityClass.AddPrivateField($"{name}_BACKING_FIELD", backingField);
                }
                else if (propertyType == "DateTime")
                {
                    var format = property["format"].GetStringValue();

                    var propContainer = new DateTimePropertyContainer()
                    {
                        Name                = name,
                        DocString           = docString,
                        PropertyType        = propertyType,
                        IsNullable          = isNullable,
                        SetAccessorModifier = isReadOnly ? Modifiers.INTERNAL : Modifiers.PUBLIC,
                        DateFormat          = format,
                    };

                    propContainer.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC);

                    entityClass.AddProperty(name, propContainer);
                    entityClass.AddUsing(nameof(UsingKeys.JSON), UsingKeys.JSON);
                }
                else
                {
                    var propContainer = new PropertyWithSummaryContainer()
                    {
                        Name                = name,
                        DocString           = docString,
                        PropertyType        = propertyType,
                        IsNullable          = isNullable,
                        SetAccessorModifier = isReadOnly ? Modifiers.INTERNAL : Modifiers.PUBLIC,
                    };

                    propContainer.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC);

                    entityClass.AddProperty(name, propContainer);
                }

                // add usings for foreign keys
                var foreignKey = property["items"] != null ? property["items"]["foreign_key"] : null;
                if (foreignKey != null)
                {
                    var foreignKeyName = foreignKey["entity"].GetStringValue().ToPascal();
                    entityClass.AddUsing("FOREIGN_KEY", UsingKeys.FOUNDATION);
                }

                // add usings for date time
                if (propertyType == "DateTime")
                {
                    entityClass.AddUsing(nameof(UsingKeys.SYSTEM), UsingKeys.SYSTEM);
                }

                // add usings for date time
                if (propertyType == "Filter")
                {
                    entityClass.AddUsing(nameof(UsingKeys.FILTERS), UsingKeys.FILTERS);
                }

                // add usings for list
                if (propertyType.Contains("List<") || propertyType.Contains("Dictionary<"))
                {
                    entityClass.AddUsing(nameof(UsingKeys.GENERIC_COLLECTIONS), UsingKeys.GENERIC_COLLECTIONS);
                }
            }

            compilation.AddClass(entityClass.Name, entityClass);

            var entityClassInterface = entityClass.Copy();

            // entityRepositoryInterface.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC);
            entityClassInterface.Name     = $"I{entityClass.Name}";
            entityClassInterface.FilePath = $"{rootFilePath}/{entityGroup}/{entityPascalName}/";
            entityClassInterface.FileName = $"I{entityClass.FileName}";
            entityClassInterface.BaseTypes.Clear();
            entityClassInterface.IsInterface = true;

            compilation.AddClass(entityClassInterface.Name, entityClassInterface);
        }