private void WriteType(TypeNode classNode, StringBuilder result, bool edition, PrefixModules prefixModule, bool allowObservable)
 {
     switch (classNode.Type)
     {
         case TypeIdentifier.Boolean:
             result.Append("boolean");
             break;
         case TypeIdentifier.DateTime:
             result.Append(allowObservable ? "Date" : "string");
             break;
         case TypeIdentifier.Object:
             if (allowObservable && classNode.IsObservable)
             {
                 if (prefixModule.HasFlag(PrefixModules.KoViews))
                     result.Append("koViews.");
                 result.Append(classNode.Name);
             }
             else
             {
                 if (prefixModule.HasFlag(PrefixModules.Views))
                     result.Append("views.");
                 result.Append(classNode.CleanName);
             }
             if (edition && classNode.HasReadOnly())
             {
                 result.Append("Edit");
             }
             break;
         case TypeIdentifier.Decimal:
         case TypeIdentifier.Double:
         case TypeIdentifier.Float:
         case TypeIdentifier.Int:
         case TypeIdentifier.Long:
             result.Append("number");
             break;
         case TypeIdentifier.Guid:
         case TypeIdentifier.String:
         case TypeIdentifier.TimeSpan:
             result.Append("string");
             break;
         case TypeIdentifier.Enum:
             if (prefixModule.HasFlag(PrefixModules.Views))
                 result.Append("views.");
             result.Append(classNode.CleanName);
             break;
         case TypeIdentifier.Any:
             result.Append("any");
             break;
         case TypeIdentifier.Union:
             {
                 bool first = true;
                 foreach (var type in classNode.Union)
                 {
                     if (first)
                         first = false;
                     else
                         result.Append(" | ");
                     WriteType(type, result, edition, prefixModule, allowObservable);
                 }
                 break;
             }
     }
 }
        private void WriteKoTypeDefinition(TypeNode viewNode, StringBuilder result)
        {
            result.AppendLine();
            AppendFormatDocumentation(result, viewNode.Documentation);

            if (viewNode.Type != TypeIdentifier.Object)
                return;

            result.AppendLine($"export class {viewNode.Name} {{");
            var cleanName = viewNode.CleanName;
            result.AppendLine($"{Tab}originalData: views.{cleanName};");
            result.AppendLine($"{Tab}changed: KnockoutComputed<boolean>;");

            bool first = true;
            foreach (var property in viewNode.Properties)
            {
                
                if (first)
                {
                    first = false;
                }
                else
                {
                    result.AppendLine();
                }

                if (property.IsObservable)
                {
                    WriteKoProperty(property, result);
                }
                else
                {
                    WriteProperty(property, result, false);
                }
            }
            result.AppendLine();

            // constructor
            result.AppendLine($"{Tab}constructor(data: views.{cleanName}) {{");
            result.AppendLine($"{Tab}{Tab}this.load(data);");
            result.AppendLine($"{Tab}{Tab}this.originalData = data;");

            // changed
            result.AppendLine($"{Tab}{Tab}this.changed = ko.computed(() => ");

            first = true;
            foreach (var propertyNode in viewNode.Properties.Where(x => x.IsObservable))
            {
                if (first)
                {
                    first = false;
                    result.Append($"{Tab}{Tab}{Tab}");
                }
                else
                {
                    result.Append($"{Tab}{Tab}{Tab}|| ");
                }

                if (propertyNode.Type.Type == TypeIdentifier.DateTime && !propertyNode.IsCollection)
                    result.Append("fromDate(");
                
                if (propertyNode.IsCollection)
                {
                    if (propertyNode.Type.IsObservable)
                    {
                        result.Append($"this.{propertyNode.Name}()");

                        result.Append(" != undefined && (");
                        result.Append($"this.{propertyNode.Name}().length !== this.originalData.{propertyNode.Name}.length");
                        result.Append($" || this.{propertyNode.Name}().some(x => x.changed())");
                        result.AppendLine(")");
                    }
                    else
                    {
                        if (propertyNode.Type.Type== TypeIdentifier.DateTime)
                            result.AppendLine($"dateArrayChanged(this.{propertyNode.Name}, this.originalData.{propertyNode.Name})");
                        else
                            result.AppendLine($"arrayChanged(this.{propertyNode.Name}, this.originalData.{propertyNode.Name})");
                    }
                }
                else
                {
                    result.Append($"this.{propertyNode.Name}()");

                    if (propertyNode.Type.IsObservable)
                    {
                        result.AppendLine($" != undefined && this.{propertyNode.Name}().changed()");
                    }
                    else
                    {
                        if (propertyNode.Type.Type == TypeIdentifier.DateTime)
                            result.Append(")");
                        result.AppendLine($" !== this.originalData.{propertyNode.Name}");
                    }
                }
            }
            result.AppendLine($"{Tab}{Tab});");
            result.AppendLine($"{Tab}}}");

            // toJs() method
            result.AppendLine($"{Tab}public toJs() {{");
            result.AppendLine($"{Tab}{Tab}return {{");
            foreach (var property in viewNode.Properties)
            {
                result.Append($"{Tab}{Tab}{Tab}{property.Name}: ");
                if (property.Type.Type == TypeIdentifier.DateTime && !property.IsCollection)
                    result.Append("fromDate(");
                result.Append($"this.{property.Name}");
                if (property.IsObservable)
                {
                    result.Append("()");
                }

                if (property.Type.IsObservable)
                {
                    result.Append($" ? this.{property.Name}");
                    if (property.IsObservable)
                    {
                        result.Append("()");
                    }
                    if (property.IsCollection)
                    {
                        result.Append(".map(x => x.toJs())");
                    }
                    else
                    {
                        result.Append(".toJs()");
                    }
                    result.Append(": null");
                }
                else
                {
                    if (property.Type.Type == TypeIdentifier.DateTime)
                    {
                        if (property.IsCollection)
                        {
                            result.Append($" && this.{property.Name}");
                            if (property.IsObservable) result.Append("()");
                            result.Append(".map(x => x.toISOString())");
                        }
                        else
                            result.Append(")");
                    }
                }
                result.AppendLine(",");
            }
            result.AppendLine($"{Tab}{Tab}}}");
            result.AppendLine($"{Tab}}}");

            // load() method
            result.AppendLine($"{Tab}public load(data: views.{cleanName}) {{");
            foreach (var propertyNode in viewNode.Properties)
            {
                result.Append($"{Tab}{Tab}this.{propertyNode.Name}");
                if (propertyNode.IsObservable)
                {
                    if (propertyNode.Type.IsObservable)
                    {
                        if (propertyNode.IsCollection)
                        {
                            result.Append($"(data.{propertyNode.Name} ? data.{propertyNode.Name}.map(x => new {propertyNode.Type.Name}(x)) : null)");
                        }
                        else
                        {
                            result.Append(
                                $"(data.{propertyNode.Name} ? new {propertyNode.Type.Name}(data.{propertyNode.Name}) : null)");
                        }
                    }
                    else
                    {
                        if (propertyNode.Type.Type == TypeIdentifier.DateTime)
                        {
                            if (propertyNode.IsCollection)
                                result.Append($"(data.{propertyNode.Name} && data.{propertyNode.Name}.map(x => new Date(x)))");
                            else
                                result.Append($"(toDate(data.{propertyNode.Name}))");
                        }
                        else
                            result.Append($"(data.{propertyNode.Name})");
                    }
                }
                else
                {
                    if (propertyNode.Type.Type == TypeIdentifier.DateTime)
                        result.Append($" = toDate(data.{propertyNode.Name})");
                    else
                        result.Append($" = data.{propertyNode.Name}");
                }
                result.AppendLine(";");
            }
            result.AppendLine($"{Tab}}}");

            // isValid() property
            if (viewNode.Properties.Any(x => x.NeedValidation()))
            {
                result.AppendLine();
                result.Append($"{Tab}public isValid = ko.computed(() => !loading()");

                foreach (var source in viewNode.Properties.Where(x => x.NeedValidation()))
                {
                    result.Append($" && !this.{source.Name}.validating() && !this.{source.Name}.errorMessage()");
                }
                result.AppendLine(");");
            }
            result.AppendLine("}");
        }
        private void WriteTypeDefinition(TypeNode viewNode, StringBuilder result, bool edition)
        {
            result.AppendLine();
            AppendFormatDocumentation(result, viewNode.Documentation);

            var cleanName = viewNode.CleanName;
            if (edition)
            {
                cleanName += "Edit";
            }

            if (viewNode.Type == TypeIdentifier.Object)
            {
                result.AppendLine($"export interface {cleanName} {{");

                bool first = true;
                foreach (var property in viewNode.Properties)
                {
                    if (!property.IsReadOnly || !edition)
                    {
                        if (first)
                        {
                            first = false;
                        }
                        else
                        {
                            result.AppendLine();
                        }

                        WriteProperty(property, result, edition);
                    }
                }
            }
            else
            {
                result.AppendLine($"export const enum {cleanName} {{");
                bool first = true;
                foreach (var value in viewNode.Values)
                {
                    if (first)
                    {
                        first = false;
                    }
                    else
                    {
                        result.AppendLine(",");
                        result.AppendLine();
                    }
                    if (value.Documentation?.Length > 0)
                    {
                        result.AppendLine($"{Tab}/** {string.Join("\r\n", value.Documentation)} */");
                    }

                    result.Append($"{Tab}{value.Name} = {value.Value}");
                }
                result.AppendLine();
            }
            result.AppendLine("}");
        }
Exemplo n.º 4
0
        public TypeNode ReadType(Type parameterType, AssemblyNode assembly, Type[] parents, string version)
        {
            var parameterTypeName = parameterType.Name;

            var classNode = new TypeNode { Version = version };

            classNode.Documentation = documentation.GetDocumentation(parameterType);

            if (parameterType.GetTypeInfo().IsEnum)
            {
                if (assembly.Types.ContainsKey(parameterTypeName))
                {
                    return assembly.Types[parameterTypeName];
                }

                var enumNames = parameterType.GetTypeInfo().GetEnumNames();
                var enumValues = parameterType.GetTypeInfo().GetEnumValues();

                classNode.Name = parameterType.Name;
                classNode.Type = TypeIdentifier.Enum;
                classNode.Values = new List<EnumValueNode>();
                for (var i = 0; i < enumValues.Length; i++)
                {
                    var enumValue = new EnumValueNode
                    {
                        Name = enumNames[i],
                        Value = Convert.ToInt32(enumValues.GetValue(i)),
                        Documentation = documentation.GetDocumentation(parameterType, enumNames[i])
                    };
                    classNode.Values.Add(enumValue);
                }
                assembly.Types[classNode.Name] = classNode;
            }
            else if (parameterType == typeof(string))
            {
                classNode.Type = TypeIdentifier.String;
            }
            else if (parameterType == typeof(long))
            {
                classNode.Type = TypeIdentifier.Long;
            }
            else if (parameterType == typeof(int) || parameterType == typeof(short))
            {
                classNode.Type = TypeIdentifier.Int;
            }
            else if (parameterType == typeof(float))
            {
                classNode.Type = TypeIdentifier.Float;
            }
            else if (parameterType == typeof(double))
            {
                classNode.Type = TypeIdentifier.Double;
            }
            else if (parameterType == typeof(DateTime))
            {
                classNode.Type = TypeIdentifier.DateTime;
            }
            else if (parameterType == typeof(bool))
            {
                classNode.Type = TypeIdentifier.Boolean;
            }
            else if (parameterType == typeof(decimal))
            {
                classNode.Type = TypeIdentifier.Decimal;
            }
            else if (parameterType == typeof(Guid))
            {
                classNode.Type = TypeIdentifier.Guid;
            }
            else if (parameterType == typeof(TimeSpan))
            {
                classNode.Type = TypeIdentifier.TimeSpan;
            }
            else if (parameterType == typeof(object))
            {
                classNode.Type = TypeIdentifier.Any;
            }
            else
            {
                if (assembly.Types.ContainsKey(parameterTypeName))
                {
                    return assembly.Types[parameterTypeName];
                }

                classNode.IsReadOnly = true;
                classNode.Name = parameterType.Name;
                classNode.Type = TypeIdentifier.Object;

                assembly.Types[classNode.Name] = classNode;

                if (parents.All(x => x != parameterType))
                {
                    classNode.Properties = ReadProperties(parameterType, parents, assembly, version);
                }

                var jsonAttribute = parameterType.GetTypeInfo().GetCustomAttribute<JsonAttribute>();
                if (jsonAttribute != null)
                {
                    classNode.IsObservable = jsonAttribute.Observable;
                }
            }


            return classNode;
        }