private static bool TryGetBasicJsonType(ClassName className, out string result)
        {
            if (className.Value.StartsWith("System.") && className.Value.Count((char c) => c == '.') == 1)
            {
                var primitiveType = CodeGeneratorUtils.GetPrimitiveName(className);
                if (primitiveType.Contains("int", StringComparison.OrdinalIgnoreCase) ||
                    primitiveType.Contains("long", StringComparison.OrdinalIgnoreCase) ||
                    primitiveType.Contains("byte", StringComparison.OrdinalIgnoreCase) ||
                    primitiveType.Contains("short", StringComparison.OrdinalIgnoreCase) ||
                    primitiveType.Contains("double", StringComparison.OrdinalIgnoreCase) ||
                    primitiveType.Contains("single", StringComparison.OrdinalIgnoreCase))
                {
                    result = "Number";
                    return(true);
                }

                if (primitiveType.EndsWith("string", StringComparison.OrdinalIgnoreCase) ||
                    primitiveType.Contains("datetime", StringComparison.OrdinalIgnoreCase))
                {
                    result = "String";
                    return(true);
                }

                if (primitiveType.EndsWith("Boolean", StringComparison.OrdinalIgnoreCase))
                {
                    result = "Boolean";
                    return(true);
                }
            }

            result = "";
            return(false);
        }
        private void ReadField(ClassObject classObject, ClassField classField)
        {
            var varString = classField.SafeCamelCaseName;
            var ctorPair  = classObject.CtorFields.FirstOrDefault(pair => pair.Field == classField);

            var inputField = $"input.GetProperty(\"{classField.CamelCaseName}\")";

            if (ctorPair != null && ctorPair.CtorField.HasDefaultValue)
            {
                inputField = classField.CamelCaseName + "Json";
                var startingValue = $"{CodeGeneratorUtils.WriteDefaultValue(this.TrimNameSpace(ctorPair.CtorField.Type.Name), ctorPair.CtorField.DefaultValue)}";

                writer.WriteLine($"var {varString} = {startingValue};");
                writer.WriteLine($"if (input.TryGetProperty(\"{classField.CamelCaseName}\", out var {inputField}))");
                writer.WriteLine("{");

                writer.Indent++;
                var valueString = ReadFieldType(inputField, classField.Name, classField.Type, 0);
                writer.WriteLine($"{varString} = {valueString};");

                writer.Indent--;
                writer.WriteLine("}");
            }
            else
            {
                var valueString = ReadFieldType(inputField, classField.Name, classField.Type, 0);

                if (varString != valueString)
                {
                    writer.WriteLine($"var {varString} = {valueString};");
                }
            }
        }
        public virtual void SaveToFolder(string folder)
        {
            Directory.CreateDirectory(folder);

            foreach (var classBaseObject in this.manager.ClassBaseObjectMap.Values)
            {
                var filename   = $"{CodeGeneratorUtils.GetPrimitiveName(classBaseObject.FullName)}{this.FileSuffix}.cs";
                var outputFile = Path.Combine(folder, filename);

                using (var file = File.Open(outputFile, FileMode.Create))
                {
                    SaveToStream(classBaseObject, file);
                }
            }

            foreach (var classObject in manager.ClassMap.Values)
            {
                if (classObject.IsAbstract || classObject.IsInterface)
                {
                    continue;
                }

                var filename   = $"{CodeGeneratorUtils.GetPrimitiveName(classObject.FullName)}{this.FileSuffix}.cs";
                var outputFile = Path.Combine(folder, filename);

                using (var file = File.Open(outputFile, FileMode.Create))
                {
                    SaveToStream(classObject, file);
                }
            }
        }
Beispiel #4
0
        private static bool TryGetReadListPrimitive(ClassName className, out string result)
        {
            if (className.Value.StartsWith("System.") && className.Value.Count((char c) => c == '.') == 1)
            {
                var primitiveType = CodeGeneratorUtils.GetPrimitiveName(className);
                result = primitiveType;
                return(true);
            }

            result = "";
            return(false);
        }
        protected virtual void WriteClass(ClassObject classObject)
        {
            var generics    = CodeGeneratorUtils.CreateGenericClassString(classObject.Generics);
            var constraints = CodeGeneratorUtils.CreateGenericConstraintsString(classObject.Generics);

            this.WriteClassObjectMethod(generics, constraints, classObject);

            writer.Indent++;
            WriteFields(classObject);
            writer.Indent--;

            writer.WriteLine("}");
        }
Beispiel #6
0
        public static void ReadFieldsToCtor(Manager manager, ClassObject classObject, IndentedTextWriter writer, ReadFieldHandler readFieldHandler)
        {
            foreach (var field in classObject.Fields)
            {
                readFieldHandler(field);
            }

            var ctorArgs = string.Join(", ", classObject.CtorFields.Select(f => f.Field.SafeCamelCaseName));
            var generics = CodeGeneratorUtils.CreateGenericClassString(classObject.Generics);

            writer.WriteLine();
            writer.WriteLine($"return new {classObject.FullName.TrimNameSpace(manager.NameSpace)}{generics}({ctorArgs});");
        }
 public void SaveToStream(ClassObject classObject, Stream output)
 {
     using (var streamWriter = new StreamWriter(output))
         using (this.writer = new IndentedTextWriter(streamWriter))
         {
             CodeGeneratorUtils.WriteOuterClass(manager, classObject.FullName, writer, this.FileSuffix, this.UsingImports,
                                                () =>
             {
                 WriteClass(classObject);
                 writer.WriteLine();
                 ReadClass(classObject);
             });
         }
 }
        protected virtual void WriteBaseClass(ClassBaseObject classBaseObject)
        {
            var generics    = CodeGeneratorUtils.CreateGenericClassString(classBaseObject.Generics);
            var constraints = CodeGeneratorUtils.CreateGenericConstraintsString(classBaseObject.Generics);

            if (!classBaseObject.Subclasses.Any())
            {
                writer.WriteLine($"// No derived classes found for base class: {classBaseObject.FullName.Value}");
                return;
            }

            var interfaceName = this.TrimNameSpace(classBaseObject.InterfaceName.IsEmpty ? classBaseObject.FullName : classBaseObject.InterfaceName);

            this.WriterClassBaseObjectMethod(interfaceName, generics, constraints, classBaseObject);
            writer.WriteLine("{");

            writer.Indent++;
            var addElse = false;

            foreach (var subclass in classBaseObject.Subclasses)
            {
                if (addElse)
                {
                    writer.Write("else ");
                }

                var castedName = $"input{subclass.Subclass.FullName.Value.Replace(".", "")}";
                writer.WriteLine($"if (input is {this.TrimNameSpace(subclass.Subclass.FullName)} {castedName})");
                writer.WriteLine("{");
                writer.Indent++;
                var paramName = $"{this.TrimNameSpace(subclass.Subclass.FullName)}.{classBaseObject.TypeDiscriminator.Name}";

                this.WriteBaseClassHandler(classBaseObject, subclass, castedName);

                writer.Indent--;
                writer.WriteLine("}");

                addElse = true;
            }

            writer.WriteLine("else");
            writer.WriteLine("{");
            writer.Indent++;
            writer.WriteLine("throw new Exception(\"Unknown base class type\");");
            writer.Indent--;
            writer.WriteLine("}");
            writer.Indent--;

            writer.WriteLine("}");
        }
        protected virtual void ReadBaseClass(ClassBaseObject classBaseObject)
        {
            var readName    = this.MakeReadValueMethod(classBaseObject.FullName);
            var generics    = CodeGeneratorUtils.CreateGenericClassString(classBaseObject.Generics);
            var constraints = CodeGeneratorUtils.CreateGenericConstraintsString(classBaseObject.Generics);

            this.WriteReadClassBaseMethod(classBaseObject, readName, generics, constraints);
            writer.WriteLine("{");
            writer.Indent++;

            this.WriteReadBaseClassTypeHandler(classBaseObject);

            var addElse = false;

            foreach (var subclassPair in classBaseObject.Subclasses)
            {
                if (addElse)
                {
                    writer.Write("else ");
                }

                var paramName = $"{subclassPair.Subclass.FullName}.{classBaseObject.TypeDiscriminator.Name}";
                writer.WriteLine($"if (type == {paramName})");
                writer.WriteLine("{");
                writer.Indent++;
                if (manager.ClassMap.TryGetValue(subclassPair.Subclass.FullName, out var fieldClass))
                {
                    this.WriteReadBaseClassHandler(classBaseObject, subclassPair);
                }
                else
                {
                    throw new Exception("Unknown subclass!");
                }
                writer.Indent--;
                writer.WriteLine("}");

                addElse = true;
            }

            writer.WriteLine("else");
            writer.WriteLine("{");
            writer.Indent++;
            writer.WriteLine("throw new Exception(\"Unknown base class type\");");
            writer.Indent--;
            writer.WriteLine("}");

            writer.Indent--;
            writer.WriteLine("}");
        }
        protected virtual void ReadClass(ClassObject classObject)
        {
            var readName    = this.MakeReadValueMethod(classObject.FullName);
            var generics    = CodeGeneratorUtils.CreateGenericClassString(classObject.Generics);
            var constraints = CodeGeneratorUtils.CreateGenericConstraintsString(classObject.Generics);

            writer.Write($"public static {this.TrimNameSpace(classObject.FullName)}{generics} {readName}{generics}({this.ReadObject} input)");
            writer.WriteLine(constraints);
            writer.WriteLine("{");

            writer.Indent++;
            this.ReadClassInner(classObject);
            writer.Indent--;

            writer.WriteLine("}");
        }
        private static bool TryGetReadListPrimitive(ClassName className, out string result)
        {
            if (className.Value.StartsWith("System.") && className.Value.Count((char c) => c == '.') == 1)
            {
                var primitiveType = CodeGeneratorUtils.GetPrimitiveName(className);

                if (primitiveType.Contains("int", StringComparison.OrdinalIgnoreCase))
                {
                    result = "Int32";
                    return(true);
                }
                if (primitiveType.Contains("long", StringComparison.OrdinalIgnoreCase))
                {
                    result = "Int64";
                    return(true);
                }
                if (primitiveType.Contains("float", StringComparison.OrdinalIgnoreCase))
                {
                    result = "Single";
                    return(true);
                }
                if (primitiveType.Contains("double", StringComparison.OrdinalIgnoreCase))
                {
                    result = "Double";
                    return(true);
                }
                if (primitiveType.Contains("decimal", StringComparison.OrdinalIgnoreCase))
                {
                    result = "Decimal";
                    return(true);
                }
                if (primitiveType.Contains("string", StringComparison.OrdinalIgnoreCase))
                {
                    result = "String";
                    return(true);
                }
                if (primitiveType.Contains("bool", StringComparison.OrdinalIgnoreCase))
                {
                    result = "Boolean";
                    return(true);
                }
            }

            result = "";
            return(false);
        }
Beispiel #12
0
        protected void SaveListHandlerToFolder(string folder)
        {
            var filename   = $"List{this.FileSuffix}.cs";
            var outputFile = Path.Combine(folder, filename);

            using (var file = File.Open(outputFile, FileMode.Create))
                using (var streamWriter = new StreamWriter(file))
                    using (this.writer = new IndentedTextWriter(streamWriter))
                    {
                        CodeGeneratorUtils.WriteOuterClass(this.manager, new ClassName("List"), this.writer, this.FileSuffix, this.UsingImports,
                                                           () =>
                        {
                            var template = File.ReadAllText("ListBinaryTemplate.txt");
                            this.writer.Write(template);
                        });
                    }
        }
Beispiel #13
0
        private string WriteFieldType(ClassType classType, string paramName, int depth)
        {
            if (classType.CollectionType == CollectionType.NotACollection)
            {
                return(WriteBasicField(classType.Name, paramName));
            }
            else if (classType.CollectionType == CollectionType.Enum)
            {
                return($"{classType.EnumUnderlayingType.Name}){paramName}");
            }
            else if (classType.CollectionType == CollectionType.Array || classType.CollectionType == CollectionType.List)
            {
                var genericType = classType.GenericTypes.First();

                if (this.manager.IsKnownClassOrBase(genericType.Name))
                {
                    return($"Write({paramName}, Write)");
                }
                else
                {
                    if (TryGetBasicJsonType(genericType.Name, out var jsonType))
                    {
                        return($"Write({paramName})");
                    }
                    else
                    {
                        var itemName = $"item{(depth == 0 ? "" : depth.ToString())}";
                        writer.WriteLine();
                        var arrayName = $"array{CodeGeneratorUtils.ToTitleCase(paramName.Replace(".", ""))}";

                        writer.WriteLine($"var {arrayName} = new JSONArray();");
                        writer.WriteLine($"foreach (var {itemName} in {paramName})");
                        writer.WriteLine("{");
                        writer.Indent++;

                        var arrayValue = WriteFieldType(classType.GenericTypes.First(), itemName, depth + 1);
                        writer.WriteLine($"{arrayName}.Add({arrayValue});");

                        writer.Indent--;
                        writer.WriteLine("}");

                        return(arrayName);
                    }
                }
            }
            else if (classType.CollectionType == CollectionType.Dictionary)
            {
                var itemName   = $"kvp{(depth == 0 ? "" : depth.ToString())}";
                var keyName    = $"{itemName}.Key";
                var valueName  = $"{itemName}.Value";
                var objectName = $"object{CodeGeneratorUtils.ToTitleCase(paramName.Replace(".", ""))}";

                writer.WriteLine();

                // Simple key in dictionary
                if (TryGetBasicJsonType(classType.GenericTypes[0].Name, out var jsonType))
                {
                    writer.WriteLine($"var {objectName} = new JSONObject();");
                    writer.WriteLine($"foreach (var {itemName} in {paramName})");
                    writer.WriteLine("{");
                    writer.Indent++;

                    var keyString   = WriteBasicField(classType.GenericTypes[0].Name, keyName);
                    var valueString = WriteBasicField(classType.GenericTypes[1].Name, valueName);

                    if (jsonType != "String")
                    {
                        keyString += ".ToString()";
                    }

                    writer.WriteLine($"{objectName}[{keyString}] = {valueString};");

                    writer.Indent--;
                    writer.WriteLine("}");
                }
                // Complex key in dictionary
                else
                {
                    writer.WriteLine($"var {objectName} = new JSONArray();");
                    writer.WriteLine($"foreach (var {itemName} in {paramName})");
                    writer.WriteLine("{");
                    writer.Indent++;

                    var keyPairName = $"keypair{(depth == 0 ? "" : depth.ToString())}";

                    writer.WriteLine($"var {keyPairName} = new JSONObject();");
                    writer.WriteLine($"{keyPairName}[\"key\"] = {WriteFieldType(classType.GenericTypes[0], keyName, depth + 1)};");
                    writer.WriteLine($"{keyPairName}[\"value\"] = {WriteFieldType(classType.GenericTypes[1], valueName, depth + 1)};");

                    writer.WriteLine($"{objectName}.Add({keyPairName});");

                    writer.Indent--;
                    writer.WriteLine("}");
                }

                return(objectName);
            }

            return("OH NO");
        }
        private string ReadFieldType(string input, string resultName, ClassType classType, int depth)
        {
            if (classType.CollectionType == CollectionType.NotACollection)
            {
                if (manager.IsKnownClassOrBase(classType.Name))
                {
                    var readName = this.MakeReadValueMethod(classType.Name);
                    if (classType.GenericTypes.Any())
                    {
                        var generics = this.MakeGenericType(classType);
                        return($"{readName}<{generics}>({input})");
                    }
                    return($"{readName}({input})");
                }
                else
                {
                    var primitiveType = CodeGeneratorUtils.GetPrimitiveName(classType.Name);
                    return($"{input}.Get{primitiveType}()");
                }
            }
            else if (classType.CollectionType == CollectionType.Enum)
            {
                var primitiveType = CodeGeneratorUtils.GetPrimitiveName(classType.EnumUnderlayingType.Name);
                return($"({classType.Name.Value}){input}.Get{primitiveType}()");
            }
            else if (classType.CollectionType == CollectionType.List || classType.CollectionType == CollectionType.Array)
            {
                var genericType     = classType.GenericTypes.First();
                var genericTypeName = this.MakeGenericType(classType);
                var depthStr        = depth == 0 ? "" : depth.ToString();
                resultName = CodeGeneratorUtils.ToCamelCase(resultName);
                var indexName = $"value{depthStr}";

                writer.WriteLine($"var {resultName}Json = {input};");
                if (manager.IsKnownClassOrBase(genericType.Name))
                {
                    var readName = this.MakeReadValueMethod(genericType.Name);
                    if (genericType.GenericTypes.Any())
                    {
                        var generics = this.MakeGenericType(genericType);
                        readName += $"<{generics}>";
                    }

                    writer.WriteLine($"var {resultName} = new {genericTypeName}(ReadList({resultName}Json, {readName}));");
                }
                else if (TryGetReadListPrimitive(genericType.Name, out var readListType))
                {
                    writer.WriteLine($"var {resultName} = new {genericTypeName}(ReadList{readListType}({resultName}Json));");
                }
                else
                {
                    writer.WriteLine($"var {resultName} = new {genericTypeName}();");
                    writer.WriteLine($"foreach (var {indexName} in {resultName}Json.EnumerateArray())");
                    writer.WriteLine("{");
                    writer.Indent++;
                    writer.WriteLine($"{resultName}.Add({ReadFieldType(indexName, resultName + (depth + 1), genericType, depth + 1)});");
                    writer.Indent--;
                    writer.WriteLine("}");
                }
                writer.WriteLine();

                return(resultName);
            }
            else if (classType.CollectionType == CollectionType.Dictionary)
            {
                var keyType     = classType.GenericTypes[0];
                var valueType   = classType.GenericTypes[1];
                var depthStr    = depth == 0 ? "" : depth.ToString();
                var indexName   = $"prop{depthStr}";
                var keyName     = $"key{depthStr}";
                var valueName   = $"value{depthStr}";
                var genericName = this.MakeGenericType(classType);
                resultName = CodeGeneratorUtils.ToCamelCase(resultName);


                writer.WriteLine($"var {resultName} = new {genericName}();");

                if (!TryGetBasicJsonType(classType.GenericTypes[0].Name, out var jsonType))
                {
                    var indexKeyName   = $"{indexName}.GetProperty(\"key\")";
                    var indexValueName = $"{indexName}.GetProperty(\"value\")";

                    writer.WriteLine($"foreach (var {indexName} in {input}.EnumerateArray())");
                    writer.WriteLine("{");
                    writer.Indent++;

                    writer.WriteLine($"var {keyName} = {ReadFieldType(indexKeyName, keyName, keyType, depth + 1)};");
                    writer.WriteLine($"var {valueName} = {ReadFieldType(indexValueName, valueName, valueType, depth + 1)};");

                    writer.WriteLine($"{resultName}[{keyName}] = {valueName};");

                    writer.Indent--;
                    writer.WriteLine("}");
                }
                else
                {
                    writer.WriteLine($"foreach (var {indexName} in {input}.EnumerateObject())");
                    writer.WriteLine("{");
                    writer.Indent++;

                    if (jsonType == "String")
                    {
                        writer.WriteLine($"var {keyName} = {indexName}.Name;");
                    }
                    else
                    {
                        var primitiveType = CodeGeneratorUtils.GetPrimitiveName(keyType.Name);
                        writer.WriteLine($"var {keyName} = Convert.To{primitiveType}({indexName}.Name);");
                    }
                    writer.WriteLine($"var {valueName} = {ReadFieldType($"{indexName}.Value", valueName, valueType, depth + 1)};");

                    writer.WriteLine($"{resultName}[{keyName}] = {valueName};");

                    writer.Indent--;
                    writer.WriteLine("}");
                }

                return(resultName);
            }

            return("OH NO");
        }
 protected virtual string MakeGenericType(ClassType classType)
 {
     return(CodeGeneratorUtils.MakeGenericType(classType, this.manager.NameSpace));
 }
Beispiel #16
0
        private string ReadFieldType(string resultName, ClassType classType, int depth)
        {
            if (classType.CollectionType == CollectionType.NotACollection)
            {
                if (manager.IsKnownClassOrBase(classType.Name))
                {
                    var readName = this.MakeReadValueMethod(classType.Name);
                    if (classType.GenericTypes.Any())
                    {
                        var generics = this.MakeGenericType(classType);
                        return($"{readName}<{generics}>(input)");
                    }
                    return($"{readName}(input)");
                }
                else
                {
                    var primitiveType = CodeGeneratorUtils.GetPrimitiveName(classType.Name);
                    return($"input.Read{primitiveType}()");
                }
            }
            else if (classType.CollectionType == CollectionType.Enum)
            {
                var primitiveType = CodeGeneratorUtils.GetPrimitiveName(classType.EnumUnderlayingType.Name);
                return($"({classType.Name.Value})input.Read{primitiveType}()");
            }
            else if (classType.CollectionType == CollectionType.List || classType.CollectionType == CollectionType.Array)
            {
                var genericType     = classType.GenericTypes.First();
                var genericTypeName = this.MakeGenericType(classType);
                resultName = CodeGeneratorUtils.ToCamelCase(resultName);

                if (manager.IsKnownClassOrBase(genericType.Name))
                {
                    var readName = this.MakeReadValueMethod(genericType.Name);
                    if (genericType.GenericTypes.Any())
                    {
                        var generics = this.MakeGenericType(genericType);
                        readName += $"<{generics}>";
                    }

                    writer.WriteLine($"var {resultName} = new {genericTypeName}(ReadList(input, {readName}));");
                }
                else if (TryGetReadListPrimitive(genericType.Name, out var readListType))
                {
                    writer.WriteLine($"var {resultName} = new {genericTypeName}(ReadList{readListType}(input));");
                }
                else
                {
                    var countName   = $"count{CodeGeneratorUtils.ToTitleCase(resultName)}";
                    var depthStr    = depth == 0 ? "" : depth.ToString();
                    var indexString = CodeGeneratorUtils.MakeIndexIterator(depth);
                    resultName = CodeGeneratorUtils.ToCamelCase(resultName);

                    writer.WriteLine($"var {countName} = input.ReadInt32();");
                    writer.WriteLine($"var {resultName} = new {genericTypeName}({countName});");
                    writer.WriteLine($"for (var {indexString} = 0; {indexString} < {countName}; {indexString}++)");
                    writer.WriteLine("{");
                    writer.Indent++;
                    writer.WriteLine($"{resultName}.Add({ReadFieldType(resultName + indexString.ToUpperInvariant(), genericType, depth + 1)});");
                    writer.Indent--;
                    writer.WriteLine("}");
                }
                return(resultName);
            }
            else if (classType.CollectionType == CollectionType.Dictionary)
            {
                var countName   = $"count{CodeGeneratorUtils.ToTitleCase(resultName)}";
                var keyType     = classType.GenericTypes[0];
                var valueType   = classType.GenericTypes[1];
                var depthStr    = depth == 0 ? "" : depth.ToString();
                var keyName     = $"key{depthStr}";
                var valueName   = $"value{depthStr}";
                var indexName   = CodeGeneratorUtils.MakeIndexIterator(depth);
                var genericName = this.MakeGenericType(classType);
                resultName = CodeGeneratorUtils.ToCamelCase(resultName);

                writer.WriteLine($"var {countName} = input.ReadInt32();");
                writer.WriteLine($"var {resultName} = new {genericName}();");
                writer.WriteLine($"for (var {indexName} = 0; {indexName} < {countName}; {indexName}++)");
                writer.WriteLine("{");
                writer.Indent++;
                writer.WriteLine($"var {keyName} = {ReadFieldType(keyName, keyType, depth + 1)};");
                writer.WriteLine($"var {valueName} = {ReadFieldType(valueName, valueType, depth + 1)};");
                writer.WriteLine($"{resultName}[{keyName}] = {valueName};");
                writer.Indent--;
                writer.WriteLine("}");

                return(resultName);
            }

            return("OH NO");
        }
 protected virtual void WriteReadFieldsToCtor(ClassObject classObject, CodeGeneratorUtils.ReadFieldHandler readFieldHandler)
 {
     CodeGeneratorUtils.ReadFieldsToCtor(this.manager, classObject, this.writer, readFieldHandler);
 }