mirror of
https://github.com/sochix/TLSharp.git
synced 2025-12-06 08:02:00 +01:00
Improved TL2JSON and formatted code a bit
This commit is contained in:
parent
76d2e9ad40
commit
8055ab3162
|
|
@ -8,29 +8,98 @@ namespace TeleSharp.Generator
|
|||
{
|
||||
class Method
|
||||
{
|
||||
public int id { get; set; }
|
||||
public string method { get; set; }
|
||||
[Newtonsoft.Json.JsonProperty("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("method")]
|
||||
public string MethodName { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("params")]
|
||||
public List<Param> Params { get; set; }
|
||||
public string type { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("type")]
|
||||
public string ResponseType { get; set; }
|
||||
|
||||
public override bool Equals(Object obj)
|
||||
{
|
||||
return obj is Method && this == (Method)obj;
|
||||
}
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Id.GetHashCode() ^ MethodName.GetHashCode() ^ Params.GetHashCode() ^ ResponseType.GetHashCode();
|
||||
}
|
||||
public static bool operator ==(Method x, Method y)
|
||||
{
|
||||
return Enumerable.SequenceEqual(x.Params, y.Params) && x.MethodName == y.MethodName && x.ResponseType == y.ResponseType && x.Id == y.Id;
|
||||
}
|
||||
public static bool operator !=(Method x, Method y)
|
||||
{
|
||||
return !(x == y);
|
||||
}
|
||||
}
|
||||
class Param
|
||||
{
|
||||
public string name { get; set; }
|
||||
public string type { get; set; }
|
||||
[Newtonsoft.Json.JsonProperty("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("type")]
|
||||
public string Type { get; set; }
|
||||
}
|
||||
class Constructor
|
||||
{
|
||||
public int id { get; set; }
|
||||
public string predicate { get; set; }
|
||||
[Newtonsoft.Json.JsonProperty("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("predicate")]
|
||||
public string ConstructorName { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("params")]
|
||||
public List<Param> Params { get; set; }
|
||||
public string type { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("type")]
|
||||
public string BaseType { get; set; }
|
||||
|
||||
public override bool Equals(Object obj)
|
||||
{
|
||||
return obj is Constructor && this == (Constructor)obj;
|
||||
}
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Id.GetHashCode() ^ ConstructorName.GetHashCode() ^ Params.GetHashCode() ^ BaseType.GetHashCode();
|
||||
}
|
||||
public static bool operator ==(Constructor x, Constructor y)
|
||||
{
|
||||
return Enumerable.SequenceEqual(x.Params, y.Params) && x.ConstructorName == y.ConstructorName && x.BaseType == y.BaseType && x.Id == y.Id;
|
||||
}
|
||||
public static bool operator !=(Constructor x, Constructor y)
|
||||
{
|
||||
return !(x == y);
|
||||
}
|
||||
}
|
||||
class Schema
|
||||
{
|
||||
public List<Constructor> constructors { get; set; }
|
||||
public List<Method> methods { get; set; }
|
||||
[Newtonsoft.Json.JsonProperty("constructors")]
|
||||
public List<Constructor> Constructors { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("methods")]
|
||||
public List<Method> Methods { get; set; }
|
||||
|
||||
public override bool Equals(Object obj)
|
||||
{
|
||||
return obj is Schema && this == (Schema)obj;
|
||||
}
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Constructors.GetHashCode() ^ Methods.GetHashCode();
|
||||
}
|
||||
public static bool operator ==(Schema x, Schema y)
|
||||
{
|
||||
return Enumerable.SequenceEqual(x.Methods.OrderBy(t=>t.MethodName),y.Methods.OrderBy(t => t.MethodName)) &&
|
||||
Enumerable.SequenceEqual(x.Constructors.OrderBy(t => t.ConstructorName), y.Constructors.OrderBy(t => t.ConstructorName));
|
||||
}
|
||||
public static bool operator !=(Schema x, Schema y)
|
||||
{
|
||||
return !(x == y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -148,7 +148,6 @@ namespace TeleSharp.Generator
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
inputPath = extra[0];
|
||||
if (!forceFormat)
|
||||
{
|
||||
|
|
@ -189,24 +188,25 @@ namespace TeleSharp.Generator
|
|||
#region Translate to C#
|
||||
|
||||
Schema schema = JsonConvert.DeserializeObject<Schema>(Json);
|
||||
foreach (var c in schema.constructors)
|
||||
foreach (var c in schema.Constructors)
|
||||
{
|
||||
interfacesList.Add(c.type);
|
||||
classesList.Add(c.predicate);
|
||||
interfacesList.Add(c.BaseType);
|
||||
classesList.Add(c.ConstructorName);
|
||||
}
|
||||
Console.WriteLine("Implementing abstract classes...");
|
||||
var abstractParams = new Dictionary<string, List<Property>>();
|
||||
foreach (var c in schema.constructors)
|
||||
var abstractParams = new Dictionary<string, List<Param>>();
|
||||
#region Abstract classes
|
||||
foreach (var c in schema.Constructors)
|
||||
{
|
||||
var list = schema.constructors.Where(x => x.type == c.type); // check if there is a dependence on this type (it is an abstract class)
|
||||
var list = schema.Constructors.Where(x => x.BaseType == c.BaseType); // check if there is a dependence on base type of this class (base type is an abstract class)
|
||||
if (list.Count() > 1)
|
||||
{
|
||||
string path = Path.Combine(outputPath, GetNameSpace(c.type, TargetNamespace).Replace(TargetNamespace, @"TL\").Replace(".", ""), GetNameofClass(c.type, true) + ".cs").Replace(@"\\", @"\");
|
||||
string path = Path.Combine(outputPath, GetNameSpace(c.BaseType, TargetNamespace).Replace(TargetNamespace, @"TL\").Replace(".", ""), GetNameofClass(c.BaseType, true) + ".cs").Replace(@"\\", @"\");
|
||||
FileStream classFile = MakeFile(path);
|
||||
using (StreamWriter writer = new StreamWriter(classFile))
|
||||
{
|
||||
string temp = AbsStyle.Replace("/* NAMESPACE */", GetNameSpace(c.type, TargetNamespace).TrimEnd('.'));
|
||||
temp = temp.Replace("/* NAME */", GetNameofClass(c.type, true));
|
||||
string temp = AbsStyle.Replace("/* NAMESPACE */", GetNameSpace(c.BaseType, TargetNamespace).TrimEnd('.'));
|
||||
temp = temp.Replace("/* NAME */", GetNameofClass(c.BaseType, true));
|
||||
writer.Write(temp);
|
||||
writer.Close();
|
||||
classFile.Close();
|
||||
|
|
@ -214,70 +214,70 @@ namespace TeleSharp.Generator
|
|||
}
|
||||
else
|
||||
{
|
||||
interfacesList.Remove(list.First().type);
|
||||
list.First().type = "himself";
|
||||
interfacesList.Remove(list.First().BaseType);
|
||||
list.First().BaseType = "himself";
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
Console.WriteLine("Implementing types...");
|
||||
foreach (var c in schema.constructors)
|
||||
#region Constructors
|
||||
foreach (var c in schema.Constructors)
|
||||
{
|
||||
string path = Path.Combine(outputPath, GetNameSpace(c.predicate, TargetNamespace).Replace(TargetNamespace, @"TL\").Replace(".", ""), GetNameofClass(c.predicate, false) + ".cs").Replace(@"\\", @"\");
|
||||
string path = Path.Combine(outputPath, GetNameSpace(c.ConstructorName, TargetNamespace).Replace(TargetNamespace, @"TL\").Replace(".", ""), GetNameofClass(c.ConstructorName, false) + ".cs").Replace(@"\\", @"\");
|
||||
FileStream classFile = MakeFile(path);
|
||||
using (StreamWriter writer = new StreamWriter(classFile))
|
||||
{
|
||||
#region About Class
|
||||
string temp = NormalStyle.Replace("/* NAMESPACE */", GetNameSpace(c.predicate, TargetNamespace).TrimEnd('.'));
|
||||
temp = (c.type == "himself") ?
|
||||
string temp = NormalStyle.Replace("/* NAMESPACE */", GetNameSpace(c.ConstructorName, TargetNamespace).TrimEnd('.'));
|
||||
temp = (c.BaseType == "himself") ?
|
||||
temp.Replace("/* PARENT */", "TLObject") :
|
||||
temp.Replace("/* PARENT */", GetNameofClass(c.type, true));
|
||||
temp = temp.Replace("/*Constructor*/", c.id.ToString());
|
||||
temp = temp.Replace("/* NAME */", GetNameofClass(c.predicate, false));
|
||||
temp.Replace("/* PARENT */", GetNameofClass(c.BaseType, true));
|
||||
temp = temp.Replace("/*Constructor*/", c.Id.ToString());
|
||||
temp = temp.Replace("/* NAME */", GetNameofClass(c.ConstructorName, false));
|
||||
#endregion
|
||||
#region Fields
|
||||
/*
|
||||
Note: Fields were mostly moved to abstract classes to provide maximum polymorphism usability.
|
||||
*/
|
||||
//string fields = "";
|
||||
string parent_name = GetNameofClass(c.type, true);
|
||||
if (c.type != "himself")
|
||||
string parent_name = GetNameofClass(c.BaseType, true);
|
||||
|
||||
if (c.BaseType != "himself")
|
||||
{
|
||||
foreach (var tmp in c.Params)
|
||||
{
|
||||
Property field = new Property
|
||||
{
|
||||
Type = CheckForFlagBase(tmp.type, GetTypeName(tmp.type)),
|
||||
Name = CheckForKeyword(tmp.name)
|
||||
};
|
||||
if (!abstractParams.ContainsKey(c.type))
|
||||
abstractParams.Add(c.type, new List<Property>());
|
||||
else if (!abstractParams[c.type].Contains(field))
|
||||
abstractParams[c.type].Add(field);
|
||||
Param field = new Param {Name = tmp.Name, Type = tmp.Type};
|
||||
if (abstractParams.All(item => item.Key != c.BaseType))
|
||||
abstractParams.Add(c.BaseType, new List<Param>());
|
||||
else if (!abstractParams[c.BaseType].Any(f => f.Name == field.Name && f.Type == field.Type))
|
||||
abstractParams[c.BaseType].Add(field);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string fields = "";
|
||||
foreach (var tmp in c.Params)
|
||||
foreach (var param in c.Params)
|
||||
{
|
||||
fields += $" public {CheckForFlagBase(tmp.type, GetTypeName(tmp.type))} {CheckForKeyword(tmp.name)} " + "{ get; set; }" + Environment.NewLine;
|
||||
fields += $" public {CheckForFlagBase(param.Type, GetTypeName(param.Type))} {CheckForKeyword(param.Name)} " + "{ get; set; }" + Environment.NewLine;
|
||||
}
|
||||
temp = temp.Replace("/* PARAMS */", fields);
|
||||
}
|
||||
#endregion
|
||||
#region ComputeFlagFunc
|
||||
if (!c.Params.Any(x => x.name == "flags")) temp = temp.Replace("/* COMPUTE */", "");
|
||||
if (c.Params.All(x => x.Name != "flags")) temp = temp.Replace("/* COMPUTE */", "");
|
||||
else
|
||||
{
|
||||
var compute = "flags = 0;" + Environment.NewLine;
|
||||
foreach (var param in c.Params.Where(x => IsFlagBase(x.type)))
|
||||
foreach (var param in c.Params.Where(x => IsFlagBase(x.Type)))
|
||||
{
|
||||
if (IsTrueFlag(param.type))
|
||||
if (IsTrueFlag(param.Type))
|
||||
{
|
||||
compute += $"flags = {CheckForKeyword(param.name)} ? (flags | {GetBitMask(param.type)}) : (flags & ~{GetBitMask(param.type)});" + Environment.NewLine;
|
||||
compute += $"flags = {CheckForKeyword(param.Name)} ? (flags | {GetBitMask(param.Type)}) : (flags & ~{GetBitMask(param.Type)});" + Environment.NewLine;
|
||||
}
|
||||
else
|
||||
{
|
||||
compute += $"flags = {CheckForKeyword(param.name)} != null ? (flags | {GetBitMask(param.type)}) : (flags & ~{GetBitMask(param.type)});" + Environment.NewLine;
|
||||
compute += $"flags = {CheckForKeyword(param.Name)} != null ? (flags | {GetBitMask(param.Type)}) : (flags & ~{GetBitMask(param.Type)});" + Environment.NewLine;
|
||||
}
|
||||
}
|
||||
temp = temp.Replace("/* COMPUTE */", compute);
|
||||
|
|
@ -286,9 +286,9 @@ namespace TeleSharp.Generator
|
|||
#region SerializeFunc
|
||||
var serialize = "";
|
||||
|
||||
if (c.Params.Any(x => x.name == "flags"))
|
||||
if (c.Params.Any(x => x.Name == "flags"))
|
||||
serialize += "ComputeFlags();" + Environment.NewLine + "bw.Write(flags);" + Environment.NewLine;
|
||||
foreach (var p in c.Params.Where(x => x.name != "flags"))
|
||||
foreach (var p in c.Params.Where(x => x.Name != "flags"))
|
||||
{
|
||||
serialize += WriteWriteCode(p) + Environment.NewLine;
|
||||
}
|
||||
|
|
@ -308,42 +308,45 @@ namespace TeleSharp.Generator
|
|||
classFile.Close();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
Console.WriteLine("Implementing methods...");
|
||||
foreach (var c in schema.methods)
|
||||
#region Methods
|
||||
foreach (var c in schema.Methods)
|
||||
{
|
||||
string path = Path.Combine(outputPath, GetNameSpace(c.method, TargetNamespace).Replace(TargetNamespace, @"TL\").Replace(".", ""), GetNameofClass(c.method, false, true) + ".cs").Replace(@"\\", @"\");
|
||||
string path = Path.Combine(outputPath, GetNameSpace(c.MethodName, TargetNamespace).Replace(TargetNamespace, @"TL\").Replace(".", ""), GetNameofClass(c.MethodName, false, true) + ".cs").Replace(@"\\", @"\");
|
||||
FileStream classFile = MakeFile(path);
|
||||
using (StreamWriter writer = new StreamWriter(classFile))
|
||||
{
|
||||
#region About Class
|
||||
string temp = MethodStyle.Replace("/* NAMESPACE */", GetNameSpace(c.method, TargetNamespace).TrimEnd('.'));
|
||||
string temp = MethodStyle.Replace("/* NAMESPACE */", GetNameSpace(c.MethodName, TargetNamespace).TrimEnd('.'));
|
||||
temp = temp.Replace("/* PARENT */", "TLMethod");
|
||||
temp = temp.Replace("/*Constructor*/", c.id.ToString());
|
||||
temp = temp.Replace("/* NAME */", GetNameofClass(c.method, false, true));
|
||||
temp = temp.Replace("/*Constructor*/", c.Id.ToString());
|
||||
temp = temp.Replace("/* NAME */", GetNameofClass(c.MethodName, false, true));
|
||||
#endregion
|
||||
#region Fields
|
||||
string fields = "";
|
||||
foreach (var tmp in c.Params)
|
||||
{
|
||||
fields += $" public {CheckForFlagBase(tmp.type, GetTypeName(tmp.type))} {CheckForKeyword(tmp.name)} " + "{get;set;}" + Environment.NewLine;
|
||||
fields += $" public {CheckForFlagBase(tmp.Type, GetTypeName(tmp.Type))} {CheckForKeyword(tmp.Name)} " + "{ get; set; }" + Environment.NewLine;
|
||||
}
|
||||
fields += $" public {CheckForFlagBase(c.type, GetTypeName(c.type))} Response" + "{ get; set;}" + Environment.NewLine;
|
||||
fields += $" public {CheckForFlagBase(c.ResponseType, GetTypeName(c.ResponseType))} Response" + "{ get; set; }" + Environment.NewLine;
|
||||
temp = temp.Replace("/* PARAMS */", fields);
|
||||
#endregion
|
||||
#region ComputeFlagFunc
|
||||
if (!c.Params.Any(x => x.name == "flags")) temp = temp.Replace("/* COMPUTE */", "");
|
||||
if (!c.Params.Any(x => x.Name == "flags")) temp = temp.Replace("/* COMPUTE */", "");
|
||||
else
|
||||
{
|
||||
var compute = "flags = 0;" + Environment.NewLine;
|
||||
foreach (var param in c.Params.Where(x => IsFlagBase(x.type)))
|
||||
foreach (var param in c.Params.Where(x => IsFlagBase(x.Type)))
|
||||
{
|
||||
if (IsTrueFlag(param.type))
|
||||
if (IsTrueFlag(param.Type))
|
||||
{
|
||||
compute += $"flags = {CheckForKeyword(param.name)} ? (flags | {GetBitMask(param.type)}) : (flags & ~{GetBitMask(param.type)});" + Environment.NewLine;
|
||||
compute += $"flags = {CheckForKeyword(param.Name)} ? (flags | {GetBitMask(param.Type)}) : (flags & ~{GetBitMask(param.Type)});" + Environment.NewLine;
|
||||
}
|
||||
else
|
||||
{
|
||||
compute += $"flags = {CheckForKeyword(param.name)} != null ? (flags | {GetBitMask(param.type)}) : (flags & ~{GetBitMask(param.type)});" + Environment.NewLine;
|
||||
compute += $"flags = {CheckForKeyword(param.Name)} != null ? (flags | {GetBitMask(param.Type)}) : (flags & ~{GetBitMask(param.Type)});" + Environment.NewLine;
|
||||
}
|
||||
}
|
||||
temp = temp.Replace("/* COMPUTE */", compute);
|
||||
|
|
@ -352,8 +355,8 @@ namespace TeleSharp.Generator
|
|||
#region SerializeFunc
|
||||
var serialize = "";
|
||||
|
||||
if (c.Params.Any(x => x.name == "flags")) serialize += "ComputeFlags();" + Environment.NewLine + "bw.Write(flags);" + Environment.NewLine;
|
||||
foreach (var p in c.Params.Where(x => x.name != "flags"))
|
||||
if (c.Params.Any(x => x.Name == "flags")) serialize += "ComputeFlags();" + Environment.NewLine + "bw.Write(flags);" + Environment.NewLine;
|
||||
foreach (var p in c.Params.Where(x => x.Name != "flags"))
|
||||
{
|
||||
serialize += WriteWriteCode(p) + Environment.NewLine;
|
||||
}
|
||||
|
|
@ -370,7 +373,7 @@ namespace TeleSharp.Generator
|
|||
#endregion
|
||||
#region DeSerializeRespFunc
|
||||
var deserializeResp = "";
|
||||
Param p2 = new Param() { name = "Response", type = c.type };
|
||||
Param p2 = new Param() { Name = "Response", Type = c.ResponseType };
|
||||
deserializeResp += WriteReadCode(p2) + Environment.NewLine;
|
||||
temp = temp.Replace("/* DESERIALIZEResp */", deserializeResp);
|
||||
#endregion
|
||||
|
|
@ -379,28 +382,28 @@ namespace TeleSharp.Generator
|
|||
classFile.Close();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
Console.WriteLine("Adding fields to abstract classes...");
|
||||
// add fields to abstract classes
|
||||
foreach (KeyValuePair<string, List<Property>> absClass in abstractParams)
|
||||
foreach (KeyValuePair<string, List<Param>> absClass in abstractParams)
|
||||
{
|
||||
if(absClass.Key == "himself")
|
||||
throw new InvalidOperationException("ARGH! It was a class without a parent, why it came into the list? :|");
|
||||
string path = Path.Combine(outputPath, GetNameSpace(absClass.Key, TargetNamespace).Replace(TargetNamespace, @"TL\").Replace(".", ""), GetNameofClass(absClass.Key, true) + ".cs").Replace(@"\\", @"\");
|
||||
string tmp = File.ReadAllText(path);
|
||||
tmp = tmp.Replace("/* PARAMS */", ConvertPropertyList(absClass.Value));
|
||||
File.WriteAllText(path, tmp);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
Console.WriteLine("Done.");
|
||||
}
|
||||
|
||||
public static string ConvertPropertyList(List<Property> list)
|
||||
public static string ConvertPropertyList(List<Param> list)
|
||||
{
|
||||
string output = "";
|
||||
foreach (var property in list)
|
||||
foreach (var param in list)
|
||||
{
|
||||
output += $" public {property.Type} {property.Name} {{ get; set; }}" + Environment.NewLine;
|
||||
output += $" public {CheckForFlagBase(param.Type, GetTypeName(param.Type))} {CheckForKeyword(param.Name)} " + "{ get; set; }" + Environment.NewLine;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
|
@ -470,13 +473,16 @@ namespace TeleSharp.Generator
|
|||
{
|
||||
if (type.IndexOf('?') == -1)
|
||||
return result;
|
||||
else
|
||||
{
|
||||
string innerType = type.Split('?')[1];
|
||||
if (innerType == "true") return result;
|
||||
else if ((new string[] { "bool", "int", "uint", "long", "double" }).Contains(result)) return result + "?";
|
||||
else return result;
|
||||
}
|
||||
|
||||
string innerType = type.Split('?')[1];
|
||||
|
||||
if (innerType == "true")
|
||||
return result;
|
||||
|
||||
if ((new string[] { "bool", "int", "uint", "long", "BigMath.Int128", "BigMath.Int256", "double" }).Contains(result))
|
||||
return result + "?";
|
||||
|
||||
return result;
|
||||
}
|
||||
public static string GetTypeName(string type)
|
||||
{
|
||||
|
|
@ -485,6 +491,10 @@ namespace TeleSharp.Generator
|
|||
case "#":
|
||||
case "int":
|
||||
return "int";
|
||||
case "int128":
|
||||
return "BigMath.Int128";
|
||||
case "int256":
|
||||
return "BigMath.Int256";
|
||||
case "uint":
|
||||
return "uint";
|
||||
case "long":
|
||||
|
|
@ -514,7 +524,6 @@ namespace TeleSharp.Generator
|
|||
|
||||
if (type.IndexOf('.') != -1 && type.IndexOf('?') == -1)
|
||||
{
|
||||
|
||||
if (interfacesList.Any(x => x.ToLower() == (type).ToLower()))
|
||||
return FormatName(type.Split('.')[0]) + "." + "TLAbs" + type.Split('.')[1];
|
||||
else if (classesList.Any(x => x.ToLower() == (type).ToLower()))
|
||||
|
|
@ -549,34 +558,34 @@ namespace TeleSharp.Generator
|
|||
}
|
||||
public static string WriteWriteCode(Param p, bool flag = false)
|
||||
{
|
||||
switch (p.type.ToLower())
|
||||
switch (p.Type.ToLower())
|
||||
{
|
||||
case "#":
|
||||
case "int":
|
||||
return flag ? $"bw.Write({CheckForKeyword(p.name)}.Value);" : $"bw.Write({CheckForKeyword(p.name)});";
|
||||
return flag ? $"bw.Write({CheckForKeyword(p.Name)}.Value);" : $"bw.Write({CheckForKeyword(p.Name)});";
|
||||
case "long":
|
||||
return flag ? $"bw.Write({CheckForKeyword(p.name)}.Value);" : $"bw.Write({CheckForKeyword(p.name)});";
|
||||
return flag ? $"bw.Write({CheckForKeyword(p.Name)}.Value);" : $"bw.Write({CheckForKeyword(p.Name)});";
|
||||
case "string":
|
||||
return $"StringUtil.Serialize({CheckForKeyword(p.name)},bw);";
|
||||
return $"StringUtil.Serialize({CheckForKeyword(p.Name)},bw);";
|
||||
case "bool":
|
||||
return flag ? $"BoolUtil.Serialize({CheckForKeyword(p.name)}.Value,bw);" : $"BoolUtil.Serialize({CheckForKeyword(p.name)},bw);";
|
||||
return flag ? $"BoolUtil.Serialize({CheckForKeyword(p.Name)}.Value,bw);" : $"BoolUtil.Serialize({CheckForKeyword(p.Name)},bw);";
|
||||
case "true":
|
||||
return $"BoolUtil.Serialize({CheckForKeyword(p.name)},bw);";
|
||||
return $"BoolUtil.Serialize({CheckForKeyword(p.Name)},bw);";
|
||||
case "bytes":
|
||||
return $"BytesUtil.Serialize({CheckForKeyword(p.name)},bw);";
|
||||
return $"BytesUtil.Serialize({CheckForKeyword(p.Name)},bw);";
|
||||
case "double":
|
||||
return flag ? $"bw.Write({CheckForKeyword(p.name)}.Value);" : $"bw.Write({CheckForKeyword(p.name)});";
|
||||
return flag ? $"bw.Write({CheckForKeyword(p.Name)}.Value);" : $"bw.Write({CheckForKeyword(p.Name)});";
|
||||
default:
|
||||
if (!IsFlagBase(p.type))
|
||||
return $"ObjectUtils.SerializeObject({CheckForKeyword(p.name)},bw);";
|
||||
if (!IsFlagBase(p.Type))
|
||||
return $"ObjectUtils.SerializeObject({CheckForKeyword(p.Name)},bw);";
|
||||
else
|
||||
{
|
||||
if (IsTrueFlag(p.type))
|
||||
if (IsTrueFlag(p.Type))
|
||||
return $"";
|
||||
else
|
||||
{
|
||||
Param p2 = new Param() { name = p.name, type = p.type.Split('?')[1] };
|
||||
return $"if ((flags & {GetBitMask(p.type).ToString()}) != 0)" + Environment.NewLine +
|
||||
Param p2 = new Param() { Name = p.Name, Type = p.Type.Split('?')[1] };
|
||||
return $"if ((flags & {GetBitMask(p.Type).ToString()}) != 0)" + Environment.NewLine +
|
||||
WriteWriteCode(p2, true);
|
||||
}
|
||||
}
|
||||
|
|
@ -584,42 +593,42 @@ namespace TeleSharp.Generator
|
|||
}
|
||||
public static string WriteReadCode(Param p)
|
||||
{
|
||||
switch (p.type.ToLower())
|
||||
switch (p.Type.ToLower())
|
||||
{
|
||||
case "#":
|
||||
case "int":
|
||||
return $"{CheckForKeyword(p.name)} = br.ReadInt32();";
|
||||
return $"{CheckForKeyword(p.Name)} = br.ReadInt32();";
|
||||
case "long":
|
||||
return $"{CheckForKeyword(p.name)} = br.ReadInt64();";
|
||||
return $"{CheckForKeyword(p.Name)} = br.ReadInt64();";
|
||||
case "string":
|
||||
return $"{CheckForKeyword(p.name)} = StringUtil.Deserialize(br);";
|
||||
return $"{CheckForKeyword(p.Name)} = StringUtil.Deserialize(br);";
|
||||
case "bool":
|
||||
case "true":
|
||||
return $"{CheckForKeyword(p.name)} = BoolUtil.Deserialize(br);";
|
||||
return $"{CheckForKeyword(p.Name)} = BoolUtil.Deserialize(br);";
|
||||
case "bytes":
|
||||
return $"{CheckForKeyword(p.name)} = BytesUtil.Deserialize(br);";
|
||||
return $"{CheckForKeyword(p.Name)} = BytesUtil.Deserialize(br);";
|
||||
case "double":
|
||||
return $"{CheckForKeyword(p.name)} = br.ReadDouble();";
|
||||
return $"{CheckForKeyword(p.Name)} = br.ReadDouble();";
|
||||
default:
|
||||
if (!IsFlagBase(p.type))
|
||||
if (!IsFlagBase(p.Type))
|
||||
{
|
||||
if (p.type.ToLower().Contains("vector"))
|
||||
if (p.Type.ToLower().Contains("vector"))
|
||||
{
|
||||
return $"{CheckForKeyword(p.name)} = ({GetTypeName(p.type)})ObjectUtils.DeserializeVector<{GetTypeName(p.type).Replace("TLVector<", "").Replace(">", "")}>(br);";
|
||||
return $"{CheckForKeyword(p.Name)} = ({GetTypeName(p.Type)})ObjectUtils.DeserializeVector<{GetTypeName(p.Type).Replace("TLVector<", "").Replace(">", "")}>(br);";
|
||||
}
|
||||
else return $"{CheckForKeyword(p.name)} = ({GetTypeName(p.type)})ObjectUtils.DeserializeObject(br);";
|
||||
else return $"{CheckForKeyword(p.Name)} = ({GetTypeName(p.Type)})ObjectUtils.DeserializeObject(br);";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsTrueFlag(p.type))
|
||||
return $"{CheckForKeyword(p.name)} = (flags & {GetBitMask(p.type).ToString()}) != 0;";
|
||||
if (IsTrueFlag(p.Type))
|
||||
return $"{CheckForKeyword(p.Name)} = (flags & {GetBitMask(p.Type).ToString()}) != 0;";
|
||||
else
|
||||
{
|
||||
Param p2 = new Param() { name = p.name, type = p.type.Split('?')[1] };
|
||||
return $"if ((flags & {GetBitMask(p.type).ToString()}) != 0)" + Environment.NewLine +
|
||||
Param p2 = new Param() { Name = p.Name, Type = p.Type.Split('?')[1] };
|
||||
return $"if ((flags & {GetBitMask(p.Type).ToString()}) != 0)" + Environment.NewLine +
|
||||
WriteReadCode(p2) + Environment.NewLine +
|
||||
"else" + Environment.NewLine +
|
||||
$"{CheckForKeyword(p.name)} = null;" + Environment.NewLine;
|
||||
$"{CheckForKeyword(p.Name)} = null;" + Environment.NewLine;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ namespace TeleSharp.Generator
|
|||
{
|
||||
static class TL2JSON
|
||||
{
|
||||
|
||||
public static string RemoveComments(string input)
|
||||
{
|
||||
var blockComments = @"/\*(.*?)\*/";
|
||||
|
|
@ -28,84 +27,82 @@ namespace TeleSharp.Generator
|
|||
RegexOptions.Singleline);
|
||||
}
|
||||
public static string RemoveEmptyLines(string input) =>
|
||||
Regex.Replace(input, @"^\s+$[\r\n]*", "", RegexOptions.Multiline);
|
||||
input.Replace("\r\n\r\n", "\r\n").Replace("\n\n","\n");
|
||||
|
||||
public static string ParseTypeLine(string line)
|
||||
public static string ParseLine(string line, BlockType blockType)
|
||||
{
|
||||
List<string> convertedParamsList = new List<string>();
|
||||
var regex = @"([a-zA-Z0-9.]+)#([0-9a-fA-F]+)([a-zA-Z0-9_:<>. !]+)= ([a-zA-Z0-9 .!]+);"; // 0 = type name, 1 = constructor code, 2 = params, 3 = base type name
|
||||
var regex = @"([a-zA-Z0-9._]+)#([0-9a-fA-F]+) ((([{])([A-z0-9_.:\(\)]+)([}]))?)([a-zA-Z0-9_:<>.#? !\(\)]+)?(([ #\[]+)([A-z0-9._ ]+)([\]]))?([ ]?)=([ ]?)([a-zA-Z0-9 .!_<>\(\)]+)([ ]?);";
|
||||
// 1 = type name, 2 = constructor code, 3 = template parameters, 8 = params, 11 = Don't know what it is (seen in vector definition , 15 = base type
|
||||
// template parameters are ignored in json schema
|
||||
|
||||
var match = Regex.Match(line, regex);
|
||||
if (!match.Success)
|
||||
throw new FormatException($"Cannot parse line: \"{line}\"");
|
||||
// now parse the params to json
|
||||
|
||||
string[] paramslist = Regex.Replace(match.Groups[3].Value, "[ ]{2,}", " ", RegexOptions.None).Split(' ');
|
||||
|
||||
foreach (var param in paramslist)
|
||||
string paramsline = Regex.Replace(match.Groups[8].Value, "[ ]{2,}", " ", RegexOptions.None);
|
||||
MatchCollection paramslist =
|
||||
Regex.Matches(
|
||||
paramsline,
|
||||
@"([A-z0-9._]+):(([A-z0-9._?<>]+)|(\([\(A-z0-9._<> \)]+\)))"
|
||||
);
|
||||
foreach (var param in paramslist.Cast<Match>())
|
||||
{
|
||||
string[] param_split = param.Split(':'); // 0=name,1=type
|
||||
if(param_split.Length == 2)
|
||||
convertedParamsList.Add($"{{\"name\": \"{param_split[0]}\", \"type\": \"{param_split[1]}\"}}");
|
||||
convertedParamsList.Add($"{{\"name\":\"{param.Groups[1].Value.Trim()}\", \"type\":\"{param.Groups[2].Value.TrimStart('(').TrimEnd(')').Trim(' ')}\"}}");
|
||||
}
|
||||
string convertedParams = $"[{string.Join(",", convertedParamsList)}]"; // [ {"name":"NAME","type":"TYPE"}, {"name":"NAME","type":"TYPE"} ]
|
||||
|
||||
// now, make the final object
|
||||
return $"{{" +
|
||||
$"\"id\": \"{Convert.ToInt32("0x"+match.Groups[2].Value, 16)}\"" + "," +
|
||||
$"\"predicate\": \"{match.Groups[1].Value}\"" + "," +
|
||||
$"\"{(blockType == BlockType.Class ? "predicate" : "method")}\": \"{match.Groups[1].Value}\"" + "," +
|
||||
$"\"params\": {convertedParams}" + "," +
|
||||
$"\"type\": \"{match.Groups[4].Value}\"" +
|
||||
$"\"type\": \"{match.Groups[15].Value}\"" +
|
||||
$"}}";
|
||||
|
||||
}
|
||||
|
||||
public static string ParseMethodLine(string line)
|
||||
{
|
||||
List<string> convertedParamsList = new List<string>();
|
||||
var regex = @"([a-zA-Z0-9.]+)#([0-9a-fA-F]+)([a-zA-Z0-9_:<>. !]+)= ([a-zA-Z0-9 .!]+);"; // 0 = method name, 1 = method code, 2 = params, 3 = base type name
|
||||
var match = Regex.Match(line, regex);
|
||||
if (!match.Success)
|
||||
throw new FormatException($"Cannot parse line: \"{line}\"");
|
||||
// now parse the params to json
|
||||
|
||||
string[] paramslist = Regex.Replace(match.Groups[3].Value, "[ ]{2,}", " ", RegexOptions.None).Split(' ');
|
||||
|
||||
foreach (var param in paramslist)
|
||||
{
|
||||
string[] param_split = param.Split(':'); // 0=name,1=type
|
||||
if (param_split.Length == 2)
|
||||
convertedParamsList.Add($"{{\"name\": \"{param_split[0]}\", \"type\": \"{param_split[1]}\"}}");
|
||||
}
|
||||
string convertedParams = $"[{string.Join(",", convertedParamsList)}]"; // [ {"name":"NAME","type":"TYPE"}, {"name":"NAME","type":"TYPE"} ]
|
||||
|
||||
// now, make the final object
|
||||
return $"{{" +
|
||||
$"\"id\": \"{Convert.ToInt32("0x" + match.Groups[2].Value, 16)}\"" + "," +
|
||||
$"\"method\": \"{match.Groups[1].Value}\"" + "," +
|
||||
$"\"params\": {convertedParams}" + "," +
|
||||
$"\"type\": \"{match.Groups[4].Value}\"" +
|
||||
$"}}";
|
||||
}
|
||||
|
||||
public static string ParseToJson(string input)
|
||||
{
|
||||
List<string> convertedTypesList = new List<string>();
|
||||
List<string> convertedMethodsList = new List<string>();
|
||||
string[] lines = RemoveEmptyLines(RemoveComments(input)).Replace("\r\n","\n").Split('\n');
|
||||
string[] lines = RemoveEmptyLines(RemoveComments(input)).Replace("\r\n","\n").Trim('\n').Split('\n');
|
||||
|
||||
int functions_splitter = Array.IndexOf(lines, "---functions---");
|
||||
string[] typeLines = lines.Take(functions_splitter - 1).ToArray();
|
||||
string[] methodLines = lines.Skip(functions_splitter + 1).ToArray();
|
||||
foreach (var line in typeLines)
|
||||
//int functions_splitter = Array.IndexOf(lines, "---functions---");
|
||||
//string[] typeLines = lines.Take(functions_splitter - 1).ToArray();
|
||||
//string[] methodLines = lines.Skip(functions_splitter + 1).ToArray();
|
||||
|
||||
BlockType blockType = BlockType.Class;
|
||||
foreach (var line in lines)
|
||||
{
|
||||
convertedTypesList.Add(ParseTypeLine(line));
|
||||
}
|
||||
foreach (var line in typeLines)
|
||||
{
|
||||
convertedMethodsList.Add(ParseMethodLine(line));
|
||||
if (line == "")
|
||||
continue;
|
||||
|
||||
if (line == "---functions---")
|
||||
{
|
||||
blockType = BlockType.Method;
|
||||
continue;
|
||||
}
|
||||
if (line == "---types---")
|
||||
{
|
||||
blockType = BlockType.Class;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (blockType == BlockType.Class)
|
||||
convertedTypesList.Add(ParseLine(line, blockType));
|
||||
else
|
||||
convertedMethodsList.Add(ParseLine(line, blockType));
|
||||
}
|
||||
|
||||
return $"{{\"constructors\":[{string.Join(",", convertedTypesList)}], \"methods\": [{string.Join(",", convertedMethodsList)}]}}"; // { "constructors": [ OBJECT, OBJECT ], "methods": [ OBJECT, OBJECT ] }
|
||||
}
|
||||
|
||||
public enum BlockType
|
||||
{
|
||||
Class,
|
||||
Method
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue