diff --git a/TelegramBotBase.SourceGenerators/TelegramBotBase.SourceGenerators.csproj b/TelegramBotBase.SourceGenerators/TelegramBotBase.SourceGenerators.csproj new file mode 100644 index 0000000..440b3de --- /dev/null +++ b/TelegramBotBase.SourceGenerators/TelegramBotBase.SourceGenerators.csproj @@ -0,0 +1,21 @@ + + + + netstandard2.0 + disable + enable + true + Analyzer + false + latest + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + diff --git a/TelegramBotBase.SourceGenerators/TelegramDeviceExtensionGenerator.cs b/TelegramBotBase.SourceGenerators/TelegramDeviceExtensionGenerator.cs new file mode 100644 index 0000000..cff17da --- /dev/null +++ b/TelegramBotBase.SourceGenerators/TelegramDeviceExtensionGenerator.cs @@ -0,0 +1,174 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Text; + +namespace TelegramBotBase +{ + + [Generator(LanguageNames.CSharp)] + public class TelegramDeviceExtensionGenerator : IIncrementalGenerator + { + + public void Initialize(IncrementalGeneratorInitializationContext context) + { + var provider = context.SyntaxProvider.CreateSyntaxProvider( + predicate: (c, _) => c is ClassDeclarationSyntax, + transform: (n, _) => (ClassDeclarationSyntax)n.Node) + .Where(a => a is not null); + + + var compilation = context.CompilationProvider; + + context.RegisterSourceOutput(compilation, (spc, source) => Execute(spc, source)); + + } + + private void Execute(SourceProductionContext context, Compilation compilation) + { + //if (!Debugger.IsAttached) Debugger.Launch(); + + StringBuilder sb = new StringBuilder(); + + var telegram_package = compilation.References.FirstOrDefault(a => a.Display != null && a.Display.Contains("Telegram.Bot")); + if (telegram_package == null) + return; + + var assemblySymbol = compilation.GetAssemblyOrModuleSymbol(telegram_package) as IAssemblySymbol; + + if (assemblySymbol == null) + return; + + if (assemblySymbol.Name != "Telegram.Bot") + return; + + var apiClass = assemblySymbol.GetTypeByMetadataName("Telegram.Bot.TelegramBotClientExtensions"); + if (apiClass == null) + return; + + var methods = apiClass.GetMembers().OfType().ToList(); + + foreach (var method in methods) + { + if (!method.Parameters.Any(a => a.Type.Name == "ITelegramBotClient")) + { + continue; + } + + if (!method.Parameters.Any(a => a.Type.Name == "ChatId")) + { + continue; + } + + if (method.Name == ".ctor") continue; + + String parameters = ""; + String subCallParameters = ""; + foreach (var par in method.Parameters) + { + if (par.Name == "botClient") + continue; + + if (!string.IsNullOrEmpty(parameters)) + { + parameters += ", "; + } + + if (!string.IsNullOrEmpty(subCallParameters)) + { + subCallParameters += ", "; + } + + if (par.Name != "chatId") + { + subCallParameters += $"{par.Name}"; + parameters += $"{par.Type.ToDisplayString()} {par.Name}"; + } + else + { + subCallParameters += $"device.DeviceId"; + } + + } + + + var returnStatement = ""; + + if (method.ReturnType is INamedTypeSymbol namedType && namedType.IsGenericType && namedType.ConstructedFrom.Name == "Task" && namedType.ContainingNamespace.ToDisplayString() == "System.Threading.Tasks") + { + returnStatement = "return await"; + } + else if (method.ReturnType.Name == "Task" && method.ReturnType.ContainingNamespace.ToDisplayString() == "System.Threading.Tasks") + { + returnStatement = "await"; + } + else if (method.ReturnsVoid) + { + returnStatement = ""; + } + else + { + returnStatement = "return "; + } + + sb.AppendLine($$"""" + + + public static async {{method.ReturnType.ToDisplayString()}} {{method.Name}}(this DeviceSession device, {{parameters}}){ + + + {{returnStatement}} device.Client.TelegramClient.{{method.Name}}({{subCallParameters}}); + } + + + """"); + + + } + + + + + // Der generierte Code + var sourceCode = $$""" + using System; + using System.Threading.Tasks; + using TelegramBotBase.Sessions; + using Telegram.Bot; + using Telegram.Bot.Extensions; + using Telegram.Bot.Requests; + using Telegram.Bot.Types.Enums; + using Telegram.Bot.Types.InlineQueryResults; + using Telegram.Bot.Types.Payments; + using Telegram.Bot.Types.ReplyMarkups; + using File = Telegram.Bot.Types.File; + + #nullable enable + namespace TelegramBotBase; + + public static class DeviceExtensions + { + {{sb.ToString()}} + } + + """; + + //Cleanup + + sourceCode = sourceCode.Replace("System.Threading.Tasks.", ""); + //sourceCode = sourceCode.Replace("Telegram.Bot.", ""); + //sourceCode = sourceCode.Replace("Telegram.Bot.Types.", ""); + + + // Fügen Sie den generierten Code der Compilation hinzu + context.AddSource("DeviceExtensions.g.cs", SourceText.From(sourceCode, Encoding.UTF8)); + + } + + } +} \ No newline at end of file diff --git a/TelegramBotBase/TelegramBotBase.csproj b/TelegramBotBase/TelegramBotBase.csproj index 9c37aad..90b1068 100644 --- a/TelegramBotBase/TelegramBotBase.csproj +++ b/TelegramBotBase/TelegramBotBase.csproj @@ -60,4 +60,9 @@ + + + + + diff --git a/TelegramBotFramework.sln b/TelegramBotFramework.sln index 409d950..2fee452 100644 --- a/TelegramBotFramework.sln +++ b/TelegramBotFramework.sln @@ -38,6 +38,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TelegramBotBase.Extensions. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TelegramBotBase.Extensions.Images.IronSoftware", "TelegramBotBase.Extensions.Images.IronSoftware\TelegramBotBase.Extensions.Images.IronSoftware.csproj", "{DC521A4C-7446-46F7-845B-AAF10EDCF8C6}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TelegramBotBase.SourceGenerators", "TelegramBotBase.SourceGenerators\TelegramBotBase.SourceGenerators.csproj", "{B78455D6-8AF2-459C-B56A-210DC89D7793}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -96,6 +98,10 @@ Global {DC521A4C-7446-46F7-845B-AAF10EDCF8C6}.Debug|Any CPU.Build.0 = Debug|Any CPU {DC521A4C-7446-46F7-845B-AAF10EDCF8C6}.Release|Any CPU.ActiveCfg = Release|Any CPU {DC521A4C-7446-46F7-845B-AAF10EDCF8C6}.Release|Any CPU.Build.0 = Release|Any CPU + {B78455D6-8AF2-459C-B56A-210DC89D7793}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B78455D6-8AF2-459C-B56A-210DC89D7793}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B78455D6-8AF2-459C-B56A-210DC89D7793}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B78455D6-8AF2-459C-B56A-210DC89D7793}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE