mirror of
https://github.com/wiz0u/WTelegramClient.git
synced 2026-04-03 19:55:09 +02:00
Generator: Clean code for generation of abstract classes
This commit is contained in:
parent
c789308d1e
commit
e6c5d94d9d
|
|
@ -128,22 +128,24 @@ namespace WTelegram
|
||||||
if (ctor.ID == 0x5BB8E511) { ctorToTypes[ctor.ID] = structName = ctor.predicate = ctor.type = "_Message"; }
|
if (ctor.ID == 0x5BB8E511) { ctorToTypes[ctor.ID] = structName = ctor.predicate = ctor.type = "_Message"; }
|
||||||
if (typeInfo.ReturnName == null) typeInfo.ReturnName = CSharpName(ctor.type);
|
if (typeInfo.ReturnName == null) typeInfo.ReturnName = CSharpName(ctor.type);
|
||||||
typeInfo.Structs.Add(ctor);
|
typeInfo.Structs.Add(ctor);
|
||||||
if (structName == typeInfo.ReturnName) typeInfo.SameName = ctor;
|
if (structName == typeInfo.ReturnName) typeInfo.MainClass = ctor;
|
||||||
}
|
}
|
||||||
foreach (var (name, typeInfo) in typeInfos)
|
foreach (var (name, typeInfo) in typeInfos)
|
||||||
{
|
{
|
||||||
if (allTypes.Contains(typeInfo.ReturnName))
|
if (allTypes.Contains(typeInfo.ReturnName))
|
||||||
{
|
{
|
||||||
if (typeInfosByLayer[0].TryGetValue(typeInfo.ReturnName, out var existingType))
|
if (typeInfosByLayer[0].TryGetValue(typeInfo.ReturnName, out var existingType))
|
||||||
|
{
|
||||||
typeInfo.ReturnName = existingType.ReturnName;
|
typeInfo.ReturnName = existingType.ReturnName;
|
||||||
typeInfo.NeedAbstract = -2; continue;
|
typeInfo.MainClass = existingType.MainClass;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
if (typeInfo.SameName == null)
|
if (typeInfo.MainClass == null)
|
||||||
{
|
{
|
||||||
typeInfo.NeedAbstract = -1;
|
List<Param> fakeCtorParams = new();
|
||||||
if (typeInfo.Structs.Count > 1)
|
if (typeInfo.Structs.Count > 1)
|
||||||
{
|
{
|
||||||
List<Param> fakeCtorParams = new();
|
|
||||||
while (typeInfo.Structs[0].@params.Length > fakeCtorParams.Count)
|
while (typeInfo.Structs[0].@params.Length > fakeCtorParams.Count)
|
||||||
{
|
{
|
||||||
fakeCtorParams.Add(typeInfo.Structs[0].@params[fakeCtorParams.Count]);
|
fakeCtorParams.Add(typeInfo.Structs[0].@params[fakeCtorParams.Count]);
|
||||||
|
|
@ -153,21 +155,21 @@ namespace WTelegram
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fakeCtorParams.Count > 0)
|
|
||||||
{
|
|
||||||
typeInfo.Structs.Insert(0, typeInfo.SameName = new Constructor
|
|
||||||
{ id = null, @params = fakeCtorParams.ToArray(), predicate = typeInfo.ReturnName, type = typeInfo.ReturnName });
|
|
||||||
typeInfo.NeedAbstract = fakeCtorParams.Count;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
typeInfo.MainClass = new Constructor { id = null, @params = fakeCtorParams.ToArray(), predicate = typeInfo.ReturnName, type = name };
|
||||||
|
typeInfo.Structs.Insert(0, typeInfo.MainClass);
|
||||||
|
typeInfo.CommonFields = fakeCtorParams.Count; // generation of abstract main class with some common fields
|
||||||
}
|
}
|
||||||
else if (typeInfo.Structs.Count > 1)
|
else if (typeInfo.Structs.Count > 1)
|
||||||
{
|
{
|
||||||
typeInfo.NeedAbstract = typeInfo.SameName.@params.Length;
|
if (typeInfo.Structs.All(ctor => ctor == typeInfo.MainClass || HasPrefix(ctor, typeInfo.MainClass.@params)))
|
||||||
foreach (var ctor in typeInfo.Structs)
|
typeInfo.CommonFields = typeInfo.MainClass.@params.Length;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (ctor == typeInfo.SameName) continue;
|
// the previous MainClass (ctor have the same name as ReturnName) is incompatible with other classes fields
|
||||||
if (!HasPrefix(ctor, typeInfo.SameName.@params)) { typeInfo.NeedAbstract = -1; typeInfo.ReturnName += "Base"; break; }
|
typeInfo.MainClass = new Constructor { id = null, @params = Array.Empty<Param>(), predicate = typeInfo.ReturnName + "Base", type = name };
|
||||||
|
typeInfo.Structs.Insert(0, typeInfo.MainClass);
|
||||||
|
typeInfo.ReturnName = typeInfo.MainClass.predicate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -179,7 +181,7 @@ namespace WTelegram
|
||||||
tabIndent = tabIndent[1..];
|
tabIndent = tabIndent[1..];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (typeInfosByLayer[0].GetValueOrDefault("Message")?.SameName.ID == 0x5BB8E511) typeInfosByLayer[0].Remove("Message");
|
if (typeInfosByLayer[0].GetValueOrDefault("Message")?.MainClass.ID == 0x5BB8E511) typeInfosByLayer[0].Remove("Message");
|
||||||
|
|
||||||
if (schema.methods.Count != 0)
|
if (schema.methods.Count != 0)
|
||||||
{
|
{
|
||||||
|
|
@ -187,8 +189,9 @@ namespace WTelegram
|
||||||
var ping = schema.methods.FirstOrDefault(m => m.method == "ping");
|
var ping = schema.methods.FirstOrDefault(m => m.method == "ping");
|
||||||
if (ping != null)
|
if (ping != null)
|
||||||
{
|
{
|
||||||
var typeInfo = new TypeInfo { ReturnName = ping.type };
|
var typeInfo = new TypeInfo { ReturnName = ping.type, MainClass =
|
||||||
typeInfo.Structs.Add(new Constructor { id = ping.id, @params = ping.@params, predicate = ping.method, type = ping.type });
|
new Constructor { id = ping.id, @params = ping.@params, predicate = ping.method, type = ping.type } };
|
||||||
|
typeInfo.Structs.Add(typeInfo.MainClass);
|
||||||
ctorToTypes[int.Parse(ping.id)] = CSharpName(ping.method);
|
ctorToTypes[int.Parse(ping.id)] = CSharpName(ping.method);
|
||||||
WriteTypeInfo(sw, typeInfo, "", false);
|
WriteTypeInfo(sw, typeInfo, "", false);
|
||||||
}
|
}
|
||||||
|
|
@ -216,37 +219,25 @@ namespace WTelegram
|
||||||
|
|
||||||
void WriteTypeInfo(StreamWriter sw, TypeInfo typeInfo, string layerPrefix, bool isMethod)
|
void WriteTypeInfo(StreamWriter sw, TypeInfo typeInfo, string layerPrefix, bool isMethod)
|
||||||
{
|
{
|
||||||
var parentClass = typeInfo.NeedAbstract != 0 ? typeInfo.ReturnName : "ITLObject";
|
|
||||||
var genericType = typeInfo.ReturnName.Length == 1 ? $"<{typeInfo.ReturnName}>" : null;
|
var genericType = typeInfo.ReturnName.Length == 1 ? $"<{typeInfo.ReturnName}>" : null;
|
||||||
if (isMethod) parentClass = "ITLFunction";
|
|
||||||
bool needNewLine = true;
|
bool needNewLine = true;
|
||||||
if (typeInfo.NeedAbstract == -1 && allTypes.Add(layerPrefix + parentClass))
|
|
||||||
{
|
|
||||||
needNewLine = false;
|
|
||||||
sw.WriteLine();
|
|
||||||
if (currentJson != "TL.MTProto")
|
|
||||||
sw.WriteLine($"{tabIndent}///<summary>See <a href=\"https://core.telegram.org/type/{typeInfo.Structs[0].type}\"/></summary>");
|
|
||||||
if (typeInfo.Structs.All(ctor => ctor.@params.Length == 0))
|
|
||||||
{
|
|
||||||
WriteTypeAsEnum(sw, typeInfo);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
sw.WriteLine($"{tabIndent}public abstract partial class {parentClass} : ITLObject {{ }}");
|
|
||||||
}
|
|
||||||
int skipParams = 0;
|
int skipParams = 0;
|
||||||
foreach (var ctor in typeInfo.Structs)
|
foreach (var ctor in typeInfo.Structs)
|
||||||
{
|
{
|
||||||
|
int ctorId = ctor.ID;
|
||||||
string className = CSharpName(ctor.predicate) + genericType;
|
string className = CSharpName(ctor.predicate) + genericType;
|
||||||
//if (typeInfo.ReturnName == "SendMessageAction") System.Diagnostics.Debugger.Break();
|
|
||||||
if (layerPrefix != "" && className == parentClass) { className += "_"; ctorToTypes[ctor.ID] = layerPrefix + className; }
|
|
||||||
if (!allTypes.Add(layerPrefix + className)) continue;
|
if (!allTypes.Add(layerPrefix + className)) continue;
|
||||||
if (needNewLine) { needNewLine = false; sw.WriteLine(); }
|
if (needNewLine) { needNewLine = false; sw.WriteLine(); }
|
||||||
if (ctor.id == null)
|
if (ctorId == 0)
|
||||||
{
|
{
|
||||||
if (currentJson != "TL.MTProto")
|
if (currentJson != "TL.MTProto")
|
||||||
sw.WriteLine($"{tabIndent}///<summary>See <a href=\"https://core.telegram.org/type/{typeInfo.Structs[0].type}\"/></summary>");
|
sw.WriteLine($"{tabIndent}///<summary>See <a href=\"https://core.telegram.org/type/{typeInfo.Structs[0].type}\"/></summary>");
|
||||||
sw.Write($"{tabIndent}public abstract partial class {className} : ITLObject");
|
if (typeInfo.Structs.All(ctor => ctor.@params.Length == 0))
|
||||||
|
{
|
||||||
|
WriteTypeAsEnum(sw, typeInfo);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sw.Write($"{tabIndent}public abstract partial class {ctor.predicate}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -262,9 +253,11 @@ namespace WTelegram
|
||||||
foreach (var parm in ctor.@params) sw.Write($"{parm.name}:{parm.type} ");
|
foreach (var parm in ctor.@params) sw.Write($"{parm.name}:{parm.type} ");
|
||||||
sw.WriteLine($"= {ctor.type}");
|
sw.WriteLine($"= {ctor.type}");
|
||||||
}
|
}
|
||||||
sw.Write($"{tabIndent}public partial class {className} : ");
|
sw.Write($"{tabIndent}public partial class {className}");
|
||||||
sw.Write(skipParams == 0 && typeInfo.NeedAbstract > 0 ? "ITLObject" : parentClass);
|
//sw.Write(skipParams == 0 && typeInfo.NeedAbstract > 0 ? "ITLObject" : parentClass);
|
||||||
}
|
}
|
||||||
|
sw.Write(" : ");
|
||||||
|
sw.Write(ctor == typeInfo.MainClass ? "ITLObject" : typeInfo.ReturnName);
|
||||||
var parms = ctor.@params.Skip(skipParams).ToArray();
|
var parms = ctor.@params.Skip(skipParams).ToArray();
|
||||||
if (parms.Length == 0)
|
if (parms.Length == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -330,7 +323,7 @@ namespace WTelegram
|
||||||
sw.WriteLine(tabIndent + "}");
|
sw.WriteLine(tabIndent + "}");
|
||||||
else
|
else
|
||||||
sw.WriteLine(" }");
|
sw.WriteLine(" }");
|
||||||
skipParams = typeInfo.NeedAbstract;
|
skipParams = typeInfo.CommonFields;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -341,12 +334,13 @@ namespace WTelegram
|
||||||
sw.WriteLine($"{tabIndent}public enum {typeInfo.ReturnName} : uint");
|
sw.WriteLine($"{tabIndent}public enum {typeInfo.ReturnName} : uint");
|
||||||
sw.WriteLine($"{tabIndent}{{");
|
sw.WriteLine($"{tabIndent}{{");
|
||||||
string prefix = "";
|
string prefix = "";
|
||||||
while ((prefix += typeInfo.Structs[0].predicate[prefix.Length]) != null)
|
while ((prefix += typeInfo.Structs[1].predicate[prefix.Length]) != null)
|
||||||
if (!typeInfo.Structs.All(ctor => ctor.predicate.StartsWith(prefix)))
|
if (!typeInfo.Structs.All(ctor => ctor.id == null || ctor.predicate.StartsWith(prefix)))
|
||||||
break;
|
break;
|
||||||
int prefixLen = CSharpName(prefix).Length - 1;
|
int prefixLen = CSharpName(prefix).Length - 1;
|
||||||
foreach (var ctor in typeInfo.Structs)
|
foreach (var ctor in typeInfo.Structs)
|
||||||
{
|
{
|
||||||
|
if (ctor.id == null) continue;
|
||||||
string className = CSharpName(ctor.predicate);
|
string className = CSharpName(ctor.predicate);
|
||||||
if (!allTypes.Add(className)) continue;
|
if (!allTypes.Add(className)) continue;
|
||||||
if (lowercase) className = className.ToLowerInvariant();
|
if (lowercase) className = className.ToLowerInvariant();
|
||||||
|
|
@ -608,9 +602,9 @@ namespace WTelegram
|
||||||
class TypeInfo
|
class TypeInfo
|
||||||
{
|
{
|
||||||
public string ReturnName;
|
public string ReturnName;
|
||||||
public Constructor SameName;
|
public Constructor MainClass;
|
||||||
public List<Constructor> Structs = new();
|
public List<Constructor> Structs = new();
|
||||||
internal int NeedAbstract; // 0:no, -1:create auto, n:use first generated constructor and skip n params
|
internal int CommonFields; // n fields are common among all those classes
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma warning disable IDE1006 // Naming Styles
|
#pragma warning disable IDE1006 // Naming Styles
|
||||||
|
|
@ -628,7 +622,7 @@ namespace WTelegram
|
||||||
public string type { get; set; }
|
public string type { get; set; }
|
||||||
public int layer { get; set; }
|
public int layer { get; set; }
|
||||||
|
|
||||||
public int ID => int.Parse(id);
|
public int ID => string.IsNullOrEmpty(id) ? 0 : int.Parse(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Param
|
public class Param
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue