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); } } }
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("}"); }
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); }
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); }); } }
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)); }
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); }