auto-generate properties helpers for fields shared among derived classes

This commit is contained in:
Wizou 2021-10-23 03:36:46 +02:00
parent c9ccaf2d17
commit 391c7f96f0
5 changed files with 662 additions and 212 deletions

View file

@ -130,6 +130,7 @@ namespace WTelegram
}
continue;
}
if (typeInfo.Structs.All(ctor => ctor.@params.Length == 0))
typeInfo.AsEnum = true;
var nullable = typeInfo.Structs.Where(c => c.predicate == "help.noAppUpdate" ||
@ -181,6 +182,26 @@ namespace WTelegram
typeInfo.ReturnName = typeInfo.MainClass.predicate;
}
typeInfo.AbstractUserOrChat = AbstractUserOrChatTypes.Contains(typeInfo.ReturnName);
if (typeInfo.CommonFields == 0)
{
var autoProps = typeInfo.Structs.OrderByDescending(s => s.@params.Length).First().@params
.Where(p => !p.type.EndsWith("?true")).ToList();
if (typeInfo.AbstractUserOrChat) { autoProps.Remove(ParamUsers); autoProps.Remove(ParamChats); }
autoProps.Remove(ParamFlags);
int autoPropsCount = 0;
foreach (var str in typeInfo.Structs)
{
if (str.ID == 0 ||str.predicate.EndsWith("Empty") || str.predicate.EndsWith("TooLong") || str.predicate.EndsWith("NotModified")) continue;
for (int i = autoProps.Count - 1; i >= 0; i--)
if (!str.@params.Contains(autoProps[i]))
autoProps.RemoveAt(i);
if (autoProps.Count == 0) break;
++autoPropsCount;
}
if (autoProps.Count > 0 && autoPropsCount > 1)
typeInfo.AutoProps = autoProps;
}
}
}
var layers = schema.constructors.Select(c => c.layer).Distinct().ToList();
@ -321,14 +342,14 @@ namespace WTelegram
}
sw.Write(" : ");
sw.Write(parentClass);
if (parms.Length == 0 && !typeInfo.AbstractUserOrChat)
if (parms.Length == 0 && !typeInfo.AbstractUserOrChat && typeInfo.AutoProps == null)
{
sw.WriteLine(" { }");
commonFields = typeInfo.CommonFields;
continue;
}
var hasFlagEnum = parms.Any(p => p.type.StartsWith("flags."));
bool multiline = hasFlagEnum || parms.Length > 1 || typeInfo.AbstractUserOrChat;
bool multiline = hasFlagEnum || parms.Length > 1 || typeInfo.AbstractUserOrChat || typeInfo.AutoProps != null;
if (multiline)
{
sw.WriteLine();
@ -381,6 +402,30 @@ namespace WTelegram
}
if (multiline) sw.WriteLine();
}
if (typeInfo.AutoProps != null)
{
bool firstLine = parms.Length != 0;
string format = $"{tabIndent}\tpublic ";
if (ctorId == 0)
format += "abstract {0} {1} {{ get; }}";
else if (ctor == typeInfo.MainClass)
format += "virtual {0} {1} => {2};";
else
format += "override {0} {1} => {2};";
foreach (var parm in typeInfo.AutoProps)
{
var value = "default";
if (ctor.@params.Any(p => p.name == parm.name))
if (!parms.Any(p => p.name == parm.name)) continue;
else value = MapName(parm.name);
else if (parm.type.StartsWith("Vector<") && className.EndsWith("Empty"))
value = $"Array.Empty<{MapType(parm.type, parm.name).TrimEnd('[', ']')}>()";
string csName = CSharpName(parm.name);
if (csName.EndsWith("Id") && parm.type != "int" && parm.type != "long") csName = csName[..^2];
if (firstLine) { sw.WriteLine(); firstLine = false; }
sw.WriteLine(string.Format(format, MapType(parm.type, parm.name), csName, value));
}
}
var hasUsersChats = parms.Contains(ParamUsers) && parms.Contains(ParamChats);
if (hasUsersChats || (typeInfo.AbstractUserOrChat && (ctor == typeInfo.MainClass || parentClass == typeInfo.ReturnName)))
{
@ -403,11 +448,13 @@ namespace WTelegram
commonFields = typeInfo.CommonFields;
}
}
static readonly Param ParamFlags = new() { name = "flags", type = "#" };
static readonly Param ParamPeer = new() { name = "peer", type = "Peer" };
static readonly Param ParamUsers = new() { name = "users", type = "Vector<User>" };
static readonly Param ParamChats = new() { name = "chats", type = "Vector<Chat>" };
static readonly HashSet<string> AbstractUserOrChatTypes = new() {
"Messages_MessagesBase", "Updates_DifferenceBase", "Updates_ChannelDifferenceBase"
"Messages_MessagesBase", "Updates_DifferenceBase", "Updates_ChannelDifferenceBase",
"Messages_DialogsBase"
};
private static bool IsDerivedName(string derived, string basename)
@ -463,6 +510,7 @@ namespace WTelegram
private string MapType(string type, string name)
{
if (type.StartsWith("flags.")) type = type[(type.IndexOf('?') + 1)..];
if (type.StartsWith("Vector<", StringComparison.OrdinalIgnoreCase))
{
if (name == "users" && type == "Vector<User>")
@ -719,6 +767,7 @@ namespace WTelegram
private static string CSharpName(string name)
{
if (name == "id") return "ID";
name = char.ToUpper(name[0]) + name[1..];
int i;
while ((i = name.IndexOf('_')) > 0)
@ -737,6 +786,7 @@ namespace WTelegram
internal int CommonFields; // n fields are common among all those classes
internal bool AsEnum;
internal bool AbstractUserOrChat;
internal List<Param> AutoProps;
}
#pragma warning disable IDE1006 // Naming Styles

View file

@ -85,8 +85,6 @@ namespace TL
partial class ChatBase : IPeerInfo
{
public abstract long ID { get; }
public abstract string Title { get; }
public abstract bool IsActive { get; }
/// <summary>returns true if you're banned of any of these rights</summary>
public abstract bool IsBanned(ChatBannedRights.Flags flags = 0);
@ -95,8 +93,6 @@ namespace TL
}
partial class ChatEmpty
{
public override long ID => id;
public override string Title => null;
public override bool IsActive => false;
public override bool IsBanned(ChatBannedRights.Flags flags = 0) => true;
public override InputPeer ToInputPeer() => null;
@ -104,8 +100,6 @@ namespace TL
}
partial class Chat
{
public override long ID => id;
public override string Title => title;
public override bool IsActive => (flags & (Flags.kicked | Flags.left | Flags.deactivated)) == 0;
public override bool IsBanned(ChatBannedRights.Flags flags = 0) => ((default_banned_rights?.flags ?? 0) & flags) != 0;
public override InputPeer ToInputPeer() => new InputPeerChat { chat_id = id };
@ -113,8 +107,6 @@ namespace TL
}
partial class ChatForbidden
{
public override long ID => id;
public override string Title => title;
public override bool IsActive => false;
public override bool IsBanned(ChatBannedRights.Flags flags = 0) => true;
public override InputPeer ToInputPeer() => new InputPeerChat { chat_id = id };
@ -122,8 +114,6 @@ namespace TL
}
partial class Channel
{
public override long ID => id;
public override string Title => title;
public override bool IsActive => (flags & Flags.left) == 0;
public override bool IsBanned(ChatBannedRights.Flags flags = 0) => ((banned_rights?.flags ?? 0) & flags) != 0 || ((default_banned_rights?.flags ?? 0) & flags) != 0;
public override InputPeer ToInputPeer() => new InputPeerChannel { channel_id = id, access_hash = access_hash };
@ -133,74 +123,16 @@ namespace TL
}
partial class ChannelForbidden
{
public override long ID => id;
public override string Title => title;
public override bool IsActive => false;
public override bool IsBanned(ChatBannedRights.Flags flags = 0) => true;
public override InputPeer ToInputPeer() => new InputPeerChannel { channel_id = id, access_hash = access_hash };
public override string ToString() => $"ChannelForbidden {id} \"{title}\"";
}
partial class ChatParticipantBase
{
public abstract long UserId { get; }
public abstract bool IsAdmin { get; }
}
partial class ChatParticipant
{
public override long UserId => user_id;
public override bool IsAdmin => false;
}
partial class ChatParticipantCreator
{
public override long UserId => user_id;
public override bool IsAdmin => true;
}
partial class ChatParticipantAdmin
{
public override bool IsAdmin => true;
}
partial class MessageBase
{
public abstract int ID { get; }
public abstract Peer Peer { get; }
public abstract DateTime Date { get; }
}
partial class MessageEmpty
{
public override int ID => id;
public override Peer Peer => peer_id;
public override DateTime Date => default;
}
public partial class Message
{
public override int ID => id;
public override Peer Peer => peer_id;
public override DateTime Date => date;
}
public partial class MessageService
{
public override int ID => id;
public override Peer Peer => peer_id;
public override DateTime Date => date;
}
partial class DialogBase
{
public abstract Peer Peer { get; }
public abstract int TopMessage { get; }
}
partial class Dialog
{
public override Peer Peer => peer;
public override int TopMessage => top_message;
}
partial class DialogFolder
{
public override Peer Peer => peer;
public override int TopMessage => top_message;
}
partial class ChatParticipantBase { public abstract bool IsAdmin { get; } }
partial class ChatParticipant { public override bool IsAdmin => false; }
partial class ChatParticipantCreator { public override bool IsAdmin => true; }
partial class ChatParticipantAdmin { public override bool IsAdmin => true; }
partial class PhotoBase
{
@ -216,7 +148,6 @@ namespace TL
partial class Photo
{
public override long ID => id;
protected override InputPhoto ToInputPhoto() => new() { id = id, access_hash = access_hash, file_reference = file_reference };
public InputPhotoFileLocation ToFileLocation() => ToFileLocation(LargestPhotoSize);
public InputPhotoFileLocation ToFileLocation(PhotoSizeBase photoSize) => new() { id = id, access_hash = access_hash, file_reference = file_reference, thumb_size = photoSize.Type };
@ -225,49 +156,42 @@ namespace TL
partial class PhotoSizeBase
{
public abstract string Type { get; }
public abstract int Width { get; }
public abstract int Height { get; }
public abstract int FileSize { get; }
}
partial class PhotoSizeEmpty
{
public override string Type => type;
public override int Width => 0;
public override int Height => 0;
public override int FileSize => 0;
}
partial class PhotoSize
{
public override string Type => type;
public override int Width => w;
public override int Height => h;
public override int FileSize => size;
}
partial class PhotoCachedSize
{
public override string Type => type;
public override int Width => w;
public override int Height => h;
public override int FileSize => bytes.Length;
}
partial class PhotoStrippedSize
{
public override string Type => type;
public override int Width => bytes[2];
public override int Height => bytes[1];
public override int FileSize => bytes.Length;
}
partial class PhotoSizeProgressive
{
public override string Type => type;
public override int Width => w;
public override int Height => h;
public override int FileSize => sizes.Last();
}
partial class PhotoPathSize
{
public override string Type => type;
public override int Width => -1;
public override int Height => -1;
public override int FileSize => bytes.Length;
@ -276,14 +200,12 @@ namespace TL
{
partial class PhotoSize
{
public override string Type => type;
public override int Width => w;
public override int Height => h;
public override int FileSize => size;
}
partial class PhotoCachedSize
{
public override string Type => type;
public override int Width => w;
public override int Height => h;
public override int FileSize => bytes.Length;
@ -300,66 +222,17 @@ namespace TL
public IPeerInfo UserOrChat(DialogBase dialog) => dialog.Peer.UserOrChat(users, chats);
}
partial class Messages_MessagesBase
{
public abstract int Count { get; }
public abstract MessageBase[] Messages { get; }
}
partial class Messages_Messages
{
public override int Count => messages.Length;
public override MessageBase[] Messages => messages;
}
partial class Messages_MessagesSlice
{
public override int Count => count;
}
partial class Messages_ChannelMessages
{
public override int Count => count;
public override MessageBase[] Messages => messages;
}
partial class Messages_MessagesNotModified
{
public override int Count => count;
public override MessageBase[] Messages => null;
}
partial class Messages_MessagesBase { public abstract int Count { get; } }
partial class Messages_Messages { public override int Count => messages.Length; }
partial class Messages_MessagesSlice { public override int Count => count; }
partial class Messages_ChannelMessages { public override int Count => count; }
partial class Messages_MessagesNotModified { public override int Count => count; }
partial class Updates_DifferenceBase
{
public abstract MessageBase[] NewMessages { get; }
public abstract EncryptedMessageBase[] NewEncryptedMessages { get; }
public abstract Update[] OtherUpdates { get; }
public abstract Updates_State State { get; }
}
partial class Updates_DifferenceEmpty
{
public override MessageBase[] NewMessages => Array.Empty<MessageBase>();
public override EncryptedMessageBase[] NewEncryptedMessages => Array.Empty<EncryptedMessageBase>();
public override Update[] OtherUpdates => Array.Empty<Update>();
public override Updates_State State => null;
}
partial class Updates_Difference
{
public override MessageBase[] NewMessages => new_messages;
public override EncryptedMessageBase[] NewEncryptedMessages => new_encrypted_messages;
public override Update[] OtherUpdates => other_updates;
public override Updates_State State => state;
}
partial class Updates_DifferenceSlice
{
public override MessageBase[] NewMessages => new_messages;
public override EncryptedMessageBase[] NewEncryptedMessages => new_encrypted_messages;
public override Update[] OtherUpdates => other_updates;
public override Updates_State State => intermediate_state;
}
partial class Updates_DifferenceTooLong
{
public override MessageBase[] NewMessages => null;
public override EncryptedMessageBase[] NewEncryptedMessages => null;
public override Update[] OtherUpdates => null;
public override Updates_State State => null;
}
partial class Updates_DifferenceBase { public abstract Updates_State State { get; } }
partial class Updates_DifferenceEmpty { public override Updates_State State => null; }
partial class Updates_Difference { public override Updates_State State => state; }
partial class Updates_DifferenceSlice { public override Updates_State State => intermediate_state; }
partial class Updates_DifferenceTooLong { public override Updates_State State => null; }
partial class EncryptedFile
{
@ -396,12 +269,12 @@ namespace TL
return type.ToLowerInvariant();
}
}
partial class SpeakingInGroupCallAction { public override string ToString() => "speaking in group call"; }
partial class SendMessageTypingAction { public override string ToString() => "typing"; }
partial class SendMessageCancelAction { public override string ToString() => "stopping"; }
partial class SendMessageGeoLocationAction { public override string ToString() => "selecting a location"; }
partial class SendMessageGamePlayAction { public override string ToString() => "playing a game"; }
partial class SendMessageHistoryImportAction { public override string ToString() => "importing history"; }
partial class SpeakingInGroupCallAction { public override string ToString() => "speaking in group call"; }
partial class SendMessageTypingAction { public override string ToString() => "typing"; }
partial class SendMessageCancelAction { public override string ToString() => "stopping"; }
partial class SendMessageGeoLocationAction { public override string ToString() => "selecting a location"; }
partial class SendMessageGamePlayAction { public override string ToString() => "playing a game"; }
partial class SendMessageHistoryImportAction { public override string ToString() => "importing history"; }
partial class StickerSet
{
@ -446,7 +319,7 @@ namespace TL
partial class Messages_PeerDialogs
{
public IPeerInfo UserOrChat(DialogBase dialog) => UserOrChat(dialog.Peer);
public IPeerInfo UserOrChat(DialogBase dialog) => dialog.Peer.UserOrChat(users, chats);
}
partial class SecureFile
@ -455,11 +328,11 @@ namespace TL
public InputSecureFileLocation ToFileLocation() => new() { id = id, access_hash = access_hash };
}
partial class JsonObjectValue { public override string ToString() => $"{HttpUtility.JavaScriptStringEncode(key, true)}:{value}"; }
partial class JsonNull { public override string ToString() => "null"; }
partial class JsonBool { public override string ToString() => value ? "true" : "false"; }
partial class JsonNumber { public override string ToString() => value.ToString(CultureInfo.InvariantCulture); }
partial class JsonString { public override string ToString() => HttpUtility.JavaScriptStringEncode(value, true); }
partial class JsonObjectValue { public override string ToString() => $"{HttpUtility.JavaScriptStringEncode(key, true)}:{value}"; }
partial class JsonNull { public override string ToString() => "null"; }
partial class JsonBool { public override string ToString() => value ? "true" : "false"; }
partial class JsonNumber { public override string ToString() => value.ToString(CultureInfo.InvariantCulture); }
partial class JsonString { public override string ToString() => HttpUtility.JavaScriptStringEncode(value, true); }
partial class JsonArray
{
public override string ToString()

View file

@ -130,7 +130,12 @@ namespace TL
public byte[] info;
}
public abstract partial class MsgDetailedInfoBase : ITLObject { }
public abstract partial class MsgDetailedInfoBase : ITLObject
{
public abstract long AnswerMsgId { get; }
public abstract int Bytes { get; }
public abstract int Status { get; }
}
[TLDef(0x276D3EC6)] //msg_detailed_info#276d3ec6 msg_id:long answer_msg_id:long bytes:int status:int = MsgDetailedInfo
public partial class MsgDetailedInfo : MsgDetailedInfoBase
{
@ -138,6 +143,10 @@ namespace TL
public long answer_msg_id;
public int bytes;
public int status;
public override long AnswerMsgId => answer_msg_id;
public override int Bytes => bytes;
public override int Status => status;
}
[TLDef(0x809DB6DF)] //msg_new_detailed_info#809db6df answer_msg_id:long bytes:int status:int = MsgDetailedInfo
public partial class MsgNewDetailedInfo : MsgDetailedInfoBase
@ -145,6 +154,10 @@ namespace TL
public long answer_msg_id;
public int bytes;
public int status;
public override long AnswerMsgId => answer_msg_id;
public override int Bytes => bytes;
public override int Status => status;
}
[TLDef(0x7D861A08)] //msg_resend_req#7d861a08 msg_ids:Vector<long> = MsgResendReq

File diff suppressed because it is too large Load diff

View file

@ -8,7 +8,10 @@ namespace TL
using Client = WTelegram.Client;
///<summary>See <a href="https://corefork.telegram.org/type/DecryptedMessage"/></summary>
public abstract partial class DecryptedMessageBase : ITLObject { }
public abstract partial class DecryptedMessageBase : ITLObject
{
public abstract long RandomId { get; }
}
///<summary>See <a href="https://corefork.telegram.org/type/DecryptedMessageMedia"/></summary>
///<remarks>a <c>null</c> value means <a href="https://corefork.telegram.org/constructor/decryptedMessageMediaEmpty">decryptedMessageMediaEmpty</a></remarks>
@ -18,7 +21,12 @@ namespace TL
public abstract partial class DecryptedMessageAction : ITLObject { }
///<summary>See <a href="https://corefork.telegram.org/type/FileLocation"/></summary>
public abstract partial class FileLocationBase : ITLObject { }
public abstract partial class FileLocationBase : ITLObject
{
public abstract long VolumeId { get; }
public abstract int LocalId { get; }
public abstract long Secret { get; }
}
namespace Layer8
{
@ -30,6 +38,8 @@ namespace TL
public byte[] random_bytes;
public string message;
public DecryptedMessageMedia media;
public override long RandomId => random_id;
}
///<summary>See <a href="https://corefork.telegram.org/constructor/decryptedMessageService"/></summary>
[TLDef(0xAA48327D)]
@ -38,6 +48,8 @@ namespace TL
public long random_id;
public byte[] random_bytes;
public DecryptedMessageAction action;
public override long RandomId => random_id;
}
///<summary>See <a href="https://corefork.telegram.org/constructor/decryptedMessageMediaPhoto"/></summary>
@ -146,6 +158,8 @@ namespace TL
public int ttl;
public string message;
public DecryptedMessageMedia media;
public override long RandomId => random_id;
}
///<summary>See <a href="https://corefork.telegram.org/constructor/decryptedMessageService"/></summary>
[TLDef(0x73164160)]
@ -153,6 +167,8 @@ namespace TL
{
public long random_id;
public DecryptedMessageAction action;
public override long RandomId => random_id;
}
///<summary>See <a href="https://corefork.telegram.org/constructor/decryptedMessageMediaVideo"/></summary>
@ -238,6 +254,8 @@ namespace TL
[IfFlag(7)] public MessageEntity[] entities;
[IfFlag(11)] public string via_bot_name;
[IfFlag(3)] public long reply_to_random_id;
public override long RandomId => random_id;
}
///<summary>See <a href="https://corefork.telegram.org/constructor/decryptedMessageMediaPhoto"/></summary>
@ -317,6 +335,8 @@ namespace TL
[IfFlag(11)] public string via_bot_name;
[IfFlag(3)] public long reply_to_random_id;
[IfFlag(17)] public long grouped_id;
public override long RandomId => random_id;
}
}
@ -363,6 +383,8 @@ namespace TL
public int w;
public int h;
public int size;
public override string Type => type;
}
///<summary>See <a href="https://corefork.telegram.org/constructor/photoCachedSize"/></summary>
[TLDef(0xE9A734FA)]
@ -373,6 +395,8 @@ namespace TL
public int w;
public int h;
public byte[] bytes;
public override string Type => type;
}
///<summary>See <a href="https://corefork.telegram.org/constructor/documentAttributeSticker"/></summary>
@ -411,6 +435,10 @@ namespace TL
public long volume_id;
public int local_id;
public long secret;
public override long VolumeId => volume_id;
public override int LocalId => local_id;
public override long Secret => secret;
}
///<summary>See <a href="https://corefork.telegram.org/constructor/fileLocation"/></summary>
[TLDef(0x53D69076)]
@ -420,6 +448,10 @@ namespace TL
public long volume_id;
public int local_id;
public long secret;
public override long VolumeId => volume_id;
public override int LocalId => local_id;
public override long Secret => secret;
}
}