* Implicit handlers building extensions generator refactored
* Telegram.Bot package updated
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Telegrator.RoslynExtensions;
|
using Telegrator.Analyzers.RoslynExtensions;
|
||||||
|
|
||||||
namespace Telegrator.Analyzers
|
namespace Telegrator.Analyzers
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
using Microsoft.CodeAnalysis.CSharp;
|
using Microsoft.CodeAnalysis.CSharp;
|
||||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using Telegrator.RoslynExtensions;
|
using Telegrator.Analyzers.RoslynExtensions;
|
||||||
|
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
@@ -69,7 +70,11 @@ namespace Telegrator.Analyzers
|
|||||||
|
|
||||||
public void Initialize(IncrementalGeneratorInitializationContext context)
|
public void Initialize(IncrementalGeneratorInitializationContext context)
|
||||||
{
|
{
|
||||||
IncrementalValueProvider<ImmutableArray<MethodDeclarationSyntax>> pipeline = context.SyntaxProvider.CreateSyntaxProvider(Provide, Transform).Where(x => x != null).Collect();
|
IncrementalValueProvider<ImmutableArray<MethodDeclarationSyntax>> pipeline = context.SyntaxProvider
|
||||||
|
.CreateSyntaxProvider(Provide, Transform)
|
||||||
|
.Where(x => x != null)
|
||||||
|
.Collect();
|
||||||
|
|
||||||
context.RegisterSourceOutput(pipeline, Execute);
|
context.RegisterSourceOutput(pipeline, Execute);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,21 +188,10 @@ namespace Telegrator.Analyzers
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (model.OriginalMethod.Parent is not ClassDeclarationSyntax containerClass)
|
if (model.OriginalMethod.Parent is not ClassDeclarationSyntax)
|
||||||
throw new MissingMemberException();
|
throw new MissingMemberException();
|
||||||
|
|
||||||
FieldDeclarationSyntax genField = model.GeneratedField
|
NamespaceDeclarationSyntax genNamespace = GeneratedNamespaceDeclaration(model.OriginalMethod, [model.GeneratedField, model.GeneratedMethod]);
|
||||||
.WithLeadingTrivia(NewLineTrivia, TabulationTrivia, TabulationTrivia);
|
|
||||||
|
|
||||||
MethodDeclarationSyntax genMethod = model.GeneratedMethod
|
|
||||||
.WithLeadingTrivia(NewLineTrivia, TabulationTrivia, TabulationTrivia);
|
|
||||||
|
|
||||||
//ClassDeclarationSyntax genClass = GeneratedClassDeclaration(containerClass.Identifier.WithLeadingTrivia(WhitespaceTrivia).WithTrailingTrivia(NewLineTrivia), containerClass.Modifiers, genField, genMethod);
|
|
||||||
NamespaceDeclarationSyntax genNamespace = GeneratedNamespaceDeclaration(model.OriginalMethod, [genField, genMethod]);
|
|
||||||
|
|
||||||
genNamespace = genNamespace
|
|
||||||
.WithCloseBraceToken(genNamespace.CloseBraceToken.WithLeadingTrivia(NewLineTrivia));
|
|
||||||
|
|
||||||
compilationUnit = compilationUnit.AddMembers(genNamespace);
|
compilationUnit = compilationUnit.AddMembers(genNamespace);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -210,30 +204,6 @@ namespace Telegrator.Analyzers
|
|||||||
context.AddSource("GeneratedKeyboards.g", compilationUnit.ToFullString());
|
context.AddSource("GeneratedKeyboards.g", compilationUnit.ToFullString());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
private static NamespaceDeclarationSyntax GeneratedNamespaceDeclaration(NameSyntax name, params IEnumerable<MemberDeclarationSyntax> members)
|
|
||||||
{
|
|
||||||
NamespaceDeclarationSyntax genNamespace = SyntaxFactory.NamespaceDeclaration(name)
|
|
||||||
.WithMembers(new SyntaxList<MemberDeclarationSyntax>(members))
|
|
||||||
.WithLeadingTrivia(NewLineTrivia);
|
|
||||||
|
|
||||||
return genNamespace
|
|
||||||
.WithCloseBraceToken(genNamespace.CloseBraceToken.WithLeadingTrivia(NewLineTrivia));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ClassDeclarationSyntax GeneratedClassDeclaration(SyntaxToken identifier, SyntaxTokenList modifiers, params IEnumerable<MemberDeclarationSyntax> members)
|
|
||||||
{
|
|
||||||
ClassDeclarationSyntax genClass = SyntaxFactory.ClassDeclaration(identifier)
|
|
||||||
.WithMembers(new SyntaxList<MemberDeclarationSyntax>(members))
|
|
||||||
.WithModifiers(modifiers)
|
|
||||||
.WithLeadingTrivia(NewLineTrivia, TabulationTrivia);
|
|
||||||
|
|
||||||
return genClass
|
|
||||||
.WithOpenBraceToken(genClass.OpenBraceToken.WithLeadingTrivia(TabulationTrivia))
|
|
||||||
.WithCloseBraceToken(genClass.CloseBraceToken.WithLeadingTrivia(NewLineTrivia, TabulationTrivia));
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
private static MethodDeclarationSyntax GeneratedMethodDeclaration(string identifier, SyntaxTokenList modifiers, TypeSyntax returnType, FieldDeclarationSyntax field)
|
private static MethodDeclarationSyntax GeneratedMethodDeclaration(string identifier, SyntaxTokenList modifiers, TypeSyntax returnType, FieldDeclarationSyntax field)
|
||||||
{
|
{
|
||||||
return SyntaxFactory.MethodDeclaration(returnType.WithTrailingTrivia(WhitespaceTrivia), identifier)
|
return SyntaxFactory.MethodDeclaration(returnType.WithTrailingTrivia(WhitespaceTrivia), identifier)
|
||||||
@@ -267,11 +237,11 @@ namespace Telegrator.Analyzers
|
|||||||
if (method.Parent is not ClassDeclarationSyntax containerClass)
|
if (method.Parent is not ClassDeclarationSyntax containerClass)
|
||||||
throw new MemberAccessException();
|
throw new MemberAccessException();
|
||||||
|
|
||||||
int times = method.CountParentTree() - 1;
|
int times = method.CountParentTree();
|
||||||
ClassDeclarationSyntax generatedContainerClass = SyntaxFactory.ClassDeclaration(containerClass.Identifier)
|
ClassDeclarationSyntax generatedContainerClass = SyntaxFactory.ClassDeclaration(containerClass.Identifier)
|
||||||
.WithMembers(new SyntaxList<MemberDeclarationSyntax>(generatedMembers.Select(member => member.DecorateMember(times + 1))))
|
.WithMembers(new SyntaxList<MemberDeclarationSyntax>(generatedMembers.Select(member => member.DecorateMember(times + 1))))
|
||||||
.WithModifiers(containerClass.Modifiers.Decorate())
|
.WithModifiers(containerClass.Modifiers.Decorate())
|
||||||
.Decorate(times);
|
.DecorateType(times);
|
||||||
|
|
||||||
MemberDeclarationSyntax generated = generatedContainerClass;
|
MemberDeclarationSyntax generated = generatedContainerClass;
|
||||||
MemberDeclarationSyntax inspecting = containerClass;
|
MemberDeclarationSyntax inspecting = containerClass;
|
||||||
@@ -290,7 +260,7 @@ namespace Telegrator.Analyzers
|
|||||||
generated = SyntaxFactory.ClassDeclaration(classDeclaration.Identifier)
|
generated = SyntaxFactory.ClassDeclaration(classDeclaration.Identifier)
|
||||||
.WithMembers([generated])
|
.WithMembers([generated])
|
||||||
.WithModifiers(classDeclaration.Modifiers.Decorate())
|
.WithModifiers(classDeclaration.Modifiers.Decorate())
|
||||||
.Decorate(times);
|
.DecorateType(times);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -300,7 +270,7 @@ namespace Telegrator.Analyzers
|
|||||||
generated = SyntaxFactory.StructDeclaration(structDeclaration.Identifier)
|
generated = SyntaxFactory.StructDeclaration(structDeclaration.Identifier)
|
||||||
.WithMembers([generated])
|
.WithMembers([generated])
|
||||||
.WithModifiers(structDeclaration.Modifiers.Decorate())
|
.WithModifiers(structDeclaration.Modifiers.Decorate())
|
||||||
.Decorate(times);
|
.DecorateType(times);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
namespace Telegrator.RoslynExtensions
|
namespace Telegrator.Analyzers.RoslynExtensions
|
||||||
{
|
{
|
||||||
public static class CollectionsExtensions
|
public static class CollectionsExtensions
|
||||||
{
|
{
|
||||||
@@ -59,6 +59,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<T> Repeat<T>(this T item, int times)
|
public static IEnumerable<T> Repeat<T>(this T item, int times)
|
||||||
=> Enumerable.Range(0, times - 1).Select(_ => item);
|
=> Enumerable.Range(0, times).Select(_ => item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
using Microsoft.CodeAnalysis;
|
||||||
|
|
||||||
|
namespace Telegrator.Analyzers.RoslynExtensions
|
||||||
|
{
|
||||||
|
public static class DiagnosticsHelper
|
||||||
|
{
|
||||||
|
public static Diagnostic Create(this DiagnosticDescriptor descriptor, Location? location, params object[] messageArgs)
|
||||||
|
=> Diagnostic.Create(descriptor, location, messageArgs);
|
||||||
|
|
||||||
|
public static void Report(this Diagnostic diagnostic, SourceProductionContext context)
|
||||||
|
=> context.ReportDiagnostic(diagnostic);
|
||||||
|
|
||||||
|
public static void Report(this DiagnosticDescriptor descriptor, SourceProductionContext context, Location? location, params object[] messageArgs)
|
||||||
|
=> descriptor.Create(location, messageArgs).Report(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
namespace Telegrator.Analyzers.RoslynExtensions;
|
||||||
|
|
||||||
|
public class TargteterNotFoundException() : Exception() { }
|
||||||
|
|
||||||
|
public class BaseClassTypeNotFoundException() : Exception() { }
|
||||||
|
|
||||||
|
public class AncestorNotFoundException : Exception { }
|
||||||
+11
-4
@@ -2,19 +2,26 @@
|
|||||||
using Microsoft.CodeAnalysis.CSharp;
|
using Microsoft.CodeAnalysis.CSharp;
|
||||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
|
|
||||||
namespace Telegrator.RoslynExtensions
|
namespace Telegrator.Analyzers.RoslynExtensions
|
||||||
{
|
{
|
||||||
public static class MemberDeclarationSyntaxExtensions
|
public static class MemberDeclarationSyntaxExtensions
|
||||||
{
|
{
|
||||||
private static SyntaxTrivia TabulationTrivia => SyntaxFactory.SyntaxTrivia(SyntaxKind.WhitespaceTrivia, "\t");
|
private static SyntaxTrivia TabulationTrivia => SyntaxFactory.SyntaxTrivia(SyntaxKind.WhitespaceTrivia, "\t");
|
||||||
private static SyntaxTrivia WhitespaceTrivia => SyntaxFactory.SyntaxTrivia(SyntaxKind.WhitespaceTrivia, " ");
|
private static SyntaxTrivia WhitespaceTrivia => SyntaxFactory.SyntaxTrivia(SyntaxKind.WhitespaceTrivia, " ");
|
||||||
private static SyntaxTrivia NewLineTrivia => SyntaxFactory.SyntaxTrivia(SyntaxKind.EndOfLineTrivia, "\n");
|
private static SyntaxTrivia NewLineTrivia => SyntaxFactory.SyntaxTrivia(SyntaxKind.EndOfLineTrivia, "\n");
|
||||||
private static SyntaxToken Semicolon => SyntaxFactory.Token(SyntaxKind.SemicolonToken);
|
|
||||||
|
|
||||||
public static SyntaxTokenList Decorate(this SyntaxTokenList tokens)
|
public static SyntaxTokenList Decorate(this SyntaxTokenList tokens)
|
||||||
=> new SyntaxTokenList(tokens.Select(token => token.WithoutTrivia().WithTrailingTrivia(WhitespaceTrivia)).ToArray());
|
=> new SyntaxTokenList(tokens.Select(token => token.WithoutTrivia().WithTrailingTrivia(WhitespaceTrivia)).ToArray());
|
||||||
|
|
||||||
public static T DecorateMember<T>(this T typeDeclaration, int times = 1) where T : MemberDeclarationSyntax => typeDeclaration
|
public static BlockSyntax DecorateBlock(this BlockSyntax block, int times) => block
|
||||||
|
.WithStatements([.. block.Statements.Select(statement => statement.DecorateStatememnt(times + 1))])
|
||||||
|
.WithOpenBraceToken(SyntaxFactory.Token(SyntaxKind.OpenBraceToken).WithLeadingTrivia(TabulationTrivia.Repeat(times)).WithTrailingTrivia(NewLineTrivia))
|
||||||
|
.WithCloseBraceToken(SyntaxFactory.Token(SyntaxKind.CloseBraceToken).WithLeadingTrivia(TabulationTrivia.Repeat(times)).WithTrailingTrivia(NewLineTrivia));
|
||||||
|
|
||||||
|
public static T DecorateStatememnt<T>(this T statememnt, int times) where T : StatementSyntax => statememnt
|
||||||
|
.WithoutTrivia().WithLeadingTrivia(TabulationTrivia.Repeat(times)).WithTrailingTrivia(NewLineTrivia);
|
||||||
|
|
||||||
|
public static T DecorateMember<T>(this T typeDeclaration, int times) where T : MemberDeclarationSyntax => typeDeclaration
|
||||||
.WithoutTrivia().WithLeadingTrivia(TabulationTrivia.Repeat(times)).WithTrailingTrivia(NewLineTrivia);
|
.WithoutTrivia().WithLeadingTrivia(TabulationTrivia.Repeat(times)).WithTrailingTrivia(NewLineTrivia);
|
||||||
|
|
||||||
public static NamespaceDeclarationSyntax Decorate(this NamespaceDeclarationSyntax namespaceDeclaration) => namespaceDeclaration
|
public static NamespaceDeclarationSyntax Decorate(this NamespaceDeclarationSyntax namespaceDeclaration) => namespaceDeclaration
|
||||||
@@ -22,7 +29,7 @@ namespace Telegrator.RoslynExtensions
|
|||||||
.WithOpenBraceToken(SyntaxFactory.Token(SyntaxKind.OpenBraceToken).WithLeadingTrivia(NewLineTrivia).WithTrailingTrivia(NewLineTrivia))
|
.WithOpenBraceToken(SyntaxFactory.Token(SyntaxKind.OpenBraceToken).WithLeadingTrivia(NewLineTrivia).WithTrailingTrivia(NewLineTrivia))
|
||||||
.WithCloseBraceToken(SyntaxFactory.Token(SyntaxKind.CloseBraceToken));
|
.WithCloseBraceToken(SyntaxFactory.Token(SyntaxKind.CloseBraceToken));
|
||||||
|
|
||||||
public static T Decorate<T>(this T typeDeclaration, int times = 1) where T : TypeDeclarationSyntax => (T)typeDeclaration
|
public static T DecorateType<T>(this T typeDeclaration, int times = 1) where T : TypeDeclarationSyntax => (T)typeDeclaration
|
||||||
.WithoutTrivia().WithLeadingTrivia(TabulationTrivia.Repeat(times))
|
.WithoutTrivia().WithLeadingTrivia(TabulationTrivia.Repeat(times))
|
||||||
.WithIdentifier(typeDeclaration.Identifier.WithoutTrivia().WithLeadingTrivia(WhitespaceTrivia).WithTrailingTrivia(NewLineTrivia))
|
.WithIdentifier(typeDeclaration.Identifier.WithoutTrivia().WithLeadingTrivia(WhitespaceTrivia).WithTrailingTrivia(NewLineTrivia))
|
||||||
.WithOpenBraceToken(SyntaxFactory.Token(SyntaxKind.OpenBraceToken).WithLeadingTrivia(TabulationTrivia.Repeat(times)).WithTrailingTrivia(NewLineTrivia))
|
.WithOpenBraceToken(SyntaxFactory.Token(SyntaxKind.OpenBraceToken).WithLeadingTrivia(TabulationTrivia.Repeat(times)).WithTrailingTrivia(NewLineTrivia))
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Telegrator.Analyzers.RoslynExtensions
|
||||||
|
{
|
||||||
|
public static class StringBuilderExtensions
|
||||||
|
{
|
||||||
|
public static StringBuilder AppendTabs(this StringBuilder builder, int count)
|
||||||
|
=> builder.Append(new string('\t', count));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
namespace Telegrator.Analyzers.RoslynExtensions
|
||||||
|
{
|
||||||
|
public static class StringExtensions
|
||||||
|
{
|
||||||
|
public static string FirstLetterToUpper(this string target)
|
||||||
|
{
|
||||||
|
char[] chars = target.ToCharArray();
|
||||||
|
int index = chars.IndexOf(char.IsLetter);
|
||||||
|
chars[index] = char.ToUpper(chars[index]);
|
||||||
|
return new string(chars);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string FirstLetterToLower(this string target)
|
||||||
|
{
|
||||||
|
char[] chars = target.ToCharArray();
|
||||||
|
int index = chars.IndexOf(char.IsLetter);
|
||||||
|
chars[index] = char.ToLower(chars[index]);
|
||||||
|
return new string(chars);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
using Microsoft.CodeAnalysis;
|
||||||
|
|
||||||
|
namespace Telegrator.Analyzers.RoslynExtensions;
|
||||||
|
|
||||||
|
public static class SymbolsExtensions
|
||||||
|
{
|
||||||
|
public static bool IsAssignableFrom(this ITypeSymbol symbol, string className)
|
||||||
|
{
|
||||||
|
if (symbol.BaseType == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (symbol.BaseType.Name == className)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return symbol.BaseType.IsAssignableFrom(className);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ITypeSymbol? Cast(this ITypeSymbol symbol, string className)
|
||||||
|
{
|
||||||
|
if (symbol.BaseType == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (symbol.BaseType.Name == className)
|
||||||
|
return symbol.BaseType;
|
||||||
|
|
||||||
|
return symbol.BaseType.Cast(className);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
using Microsoft.CodeAnalysis;
|
||||||
|
using Microsoft.CodeAnalysis.CSharp;
|
||||||
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
|
|
||||||
|
namespace Telegrator.Analyzers.RoslynExtensions
|
||||||
|
{
|
||||||
|
public static class SyntaxNodesExtensions
|
||||||
|
{
|
||||||
|
public static T FindAncestor<T>(this SyntaxNode node) where T : SyntaxNode
|
||||||
|
{
|
||||||
|
if (node.Parent == null)
|
||||||
|
throw new AncestorNotFoundException();
|
||||||
|
|
||||||
|
if (node.Parent is T found)
|
||||||
|
return found;
|
||||||
|
|
||||||
|
return node.Parent.FindAncestor<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryFindAncestor<T>(this SyntaxNode node, out T syntax) where T : SyntaxNode
|
||||||
|
{
|
||||||
|
if (node.Parent == null)
|
||||||
|
{
|
||||||
|
syntax = null!;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.Parent is T found)
|
||||||
|
{
|
||||||
|
syntax = found;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return node.Parent.TryFindAncestor(out syntax);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static INamedTypeSymbol TryGetNamedType(this BaseTypeDeclarationSyntax syntax, Compilation compilation)
|
||||||
|
{
|
||||||
|
SemanticModel semanticModel = compilation.GetSemanticModel(syntax.SyntaxTree);
|
||||||
|
return semanticModel.GetDeclaredSymbol(syntax)!;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetBaseTypeSyntaxName(this BaseTypeSyntax baseClassSyntax)
|
||||||
|
{
|
||||||
|
if (baseClassSyntax is PrimaryConstructorBaseTypeSyntax parimaryConstructor)
|
||||||
|
return parimaryConstructor.Type.ToString();
|
||||||
|
|
||||||
|
if (baseClassSyntax is SimpleBaseTypeSyntax simpleBaseType)
|
||||||
|
return simpleBaseType.Type.ToString();
|
||||||
|
|
||||||
|
throw new BaseClassTypeNotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int CountParentTree(this SyntaxNode node)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
SyntaxNode inspectNode = node;
|
||||||
|
|
||||||
|
while (inspectNode.Parent != null)
|
||||||
|
{
|
||||||
|
inspectNode = inspectNode.Parent;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SeparatedSyntaxList<TNode> ToSeparatedSyntaxList<TNode>(this IEnumerable<TNode> elements) where TNode : SyntaxNode
|
||||||
|
=> new SeparatedSyntaxList<TNode>().AddRange(elements);
|
||||||
|
|
||||||
|
public static SyntaxList<TNode> ToSyntaxList<TNode>(this IEnumerable<TNode> elements) where TNode : SyntaxNode
|
||||||
|
=> new SyntaxList<TNode>().AddRange(elements);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
using Microsoft.CodeAnalysis;
|
||||||
|
|
||||||
|
namespace Telegrator.Analyzers.RoslynExtensions
|
||||||
|
{
|
||||||
|
public static class SyntaxTokenExtensions
|
||||||
|
{
|
||||||
|
public static bool HasModifiers(this SyntaxTokenList modifiers, params string[] expected)
|
||||||
|
{
|
||||||
|
return modifiers.Count(mod => expected.Contains(mod.ToString())) == expected.Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,7 +6,6 @@
|
|||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
|
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
|
||||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -23,9 +22,4 @@
|
|||||||
</PackageReference>
|
</PackageReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\dev\Telegrator.RoslynExtensions\Telegrator.RoslynExtensions.csproj" PrivateAssets="all" />
|
|
||||||
<None Include="$(OutputPath)\*.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
+7
-7
@@ -20,7 +20,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Telegrator.Hosting.Web", "T
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Telegrator.RoslynGenerators", "dev\Telegrator.RoslynGenerators\Telegrator.RoslynGenerators.csproj", "{93658B7F-C651-4C78-2CB1-2C0AE00C45B5}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Telegrator.RoslynGenerators", "dev\Telegrator.RoslynGenerators\Telegrator.RoslynGenerators.csproj", "{93658B7F-C651-4C78-2CB1-2C0AE00C45B5}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Telegrator.RoslynExtensions", "dev\Telegrator.RoslynExtensions\Telegrator.RoslynExtensions.csproj", "{1E6980BE-32C1-A994-C329-B7C473411C87}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SosalBot", "..\SosalBot\SosalBot\SosalBot.csproj", "{D6AA4D47-0DCE-520E-5779-A14EA9CB1DEC}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
@@ -65,12 +65,12 @@ Global
|
|||||||
{93658B7F-C651-4C78-2CB1-2C0AE00C45B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{93658B7F-C651-4C78-2CB1-2C0AE00C45B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{93658B7F-C651-4C78-2CB1-2C0AE00C45B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{93658B7F-C651-4C78-2CB1-2C0AE00C45B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{93658B7F-C651-4C78-2CB1-2C0AE00C45B5}.Release|Any CPU.Build.0 = Release|Any CPU
|
{93658B7F-C651-4C78-2CB1-2C0AE00C45B5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{1E6980BE-32C1-A994-C329-B7C473411C87}.AnalyzersDebug|Any CPU.ActiveCfg = AnalyzersDebug|Any CPU
|
{D6AA4D47-0DCE-520E-5779-A14EA9CB1DEC}.AnalyzersDebug|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{1E6980BE-32C1-A994-C329-B7C473411C87}.AnalyzersDebug|Any CPU.Build.0 = AnalyzersDebug|Any CPU
|
{D6AA4D47-0DCE-520E-5779-A14EA9CB1DEC}.AnalyzersDebug|Any CPU.Build.0 = Release|Any CPU
|
||||||
{1E6980BE-32C1-A994-C329-B7C473411C87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{D6AA4D47-0DCE-520E-5779-A14EA9CB1DEC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{1E6980BE-32C1-A994-C329-B7C473411C87}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{D6AA4D47-0DCE-520E-5779-A14EA9CB1DEC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{1E6980BE-32C1-A994-C329-B7C473411C87}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{D6AA4D47-0DCE-520E-5779-A14EA9CB1DEC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{1E6980BE-32C1-A994-C329-B7C473411C87}.Release|Any CPU.Build.0 = Release|Any CPU
|
{D6AA4D47-0DCE-520E-5779-A14EA9CB1DEC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
@@ -57,6 +57,8 @@ namespace Telegrator.Handlers
|
|||||||
/// <param name="messageEffectId">The message effect ID.</param>
|
/// <param name="messageEffectId">The message effect ID.</param>
|
||||||
/// <param name="businessConnectionId">The business connection ID.</param>
|
/// <param name="businessConnectionId">The business connection ID.</param>
|
||||||
/// <param name="allowPaidBroadcast">Whether to allow paid broadcast.</param>
|
/// <param name="allowPaidBroadcast">Whether to allow paid broadcast.</param>
|
||||||
|
/// <param name="directMessageTopicId"></param>
|
||||||
|
/// <param name="suggestedPostParameters"></param>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>The sent message.</returns>
|
/// <returns>The sent message.</returns>
|
||||||
protected async Task<Message> Responce(
|
protected async Task<Message> Responce(
|
||||||
@@ -72,6 +74,8 @@ namespace Telegrator.Handlers
|
|||||||
string? messageEffectId = null,
|
string? messageEffectId = null,
|
||||||
string? businessConnectionId = null,
|
string? businessConnectionId = null,
|
||||||
bool allowPaidBroadcast = false,
|
bool allowPaidBroadcast = false,
|
||||||
|
int? directMessageTopicId = null,
|
||||||
|
SuggestedPostParameters? suggestedPostParameters = null,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
=> await Container.Responce(
|
=> await Container.Responce(
|
||||||
text, parseMode, replyParameters,
|
text, parseMode, replyParameters,
|
||||||
@@ -79,7 +83,8 @@ namespace Telegrator.Handlers
|
|||||||
messageThreadId, entities,
|
messageThreadId, entities,
|
||||||
disableNotification, protectContent,
|
disableNotification, protectContent,
|
||||||
messageEffectId, businessConnectionId,
|
messageEffectId, businessConnectionId,
|
||||||
allowPaidBroadcast, cancellationToken);
|
allowPaidBroadcast, directMessageTopicId,
|
||||||
|
suggestedPostParameters, cancellationToken);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Edits the current callback message with new text.
|
/// Edits the current callback message with new text.
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Telegram.Bot;
|
using Telegram.Bot.Types;
|
||||||
using Telegram.Bot.Types;
|
|
||||||
using Telegram.Bot.Types.Enums;
|
using Telegram.Bot.Types.Enums;
|
||||||
using Telegram.Bot.Types.ReplyMarkups;
|
using Telegram.Bot.Types.ReplyMarkups;
|
||||||
using Telegrator.Attributes;
|
using Telegrator.Attributes;
|
||||||
@@ -42,6 +41,8 @@ namespace Telegrator.Handlers
|
|||||||
/// <param name="messageEffectId">The message effect ID.</param>
|
/// <param name="messageEffectId">The message effect ID.</param>
|
||||||
/// <param name="businessConnectionId">The business connection ID.</param>
|
/// <param name="businessConnectionId">The business connection ID.</param>
|
||||||
/// <param name="allowPaidBroadcast">Whether to allow paid broadcast.</param>
|
/// <param name="allowPaidBroadcast">Whether to allow paid broadcast.</param>
|
||||||
|
/// <param name="directMessageTopicId"></param>
|
||||||
|
/// <param name="suggestedPostParameters"></param>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>The sent message.</returns>
|
/// <returns>The sent message.</returns>
|
||||||
protected async Task<Message> Reply(
|
protected async Task<Message> Reply(
|
||||||
@@ -56,6 +57,8 @@ namespace Telegrator.Handlers
|
|||||||
string? messageEffectId = null,
|
string? messageEffectId = null,
|
||||||
string? businessConnectionId = null,
|
string? businessConnectionId = null,
|
||||||
bool allowPaidBroadcast = false,
|
bool allowPaidBroadcast = false,
|
||||||
|
int? directMessageTopicId = null,
|
||||||
|
SuggestedPostParameters? suggestedPostParameters = null,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
=> await Container.Reply(
|
=> await Container.Reply(
|
||||||
text, parseMode,
|
text, parseMode,
|
||||||
@@ -63,7 +66,8 @@ namespace Telegrator.Handlers
|
|||||||
messageThreadId, entities,
|
messageThreadId, entities,
|
||||||
disableNotification, protectContent,
|
disableNotification, protectContent,
|
||||||
messageEffectId, businessConnectionId,
|
messageEffectId, businessConnectionId,
|
||||||
allowPaidBroadcast, cancellationToken);
|
allowPaidBroadcast, directMessageTopicId,
|
||||||
|
suggestedPostParameters, cancellationToken);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sends a response message to the current chat.
|
/// Sends a response message to the current chat.
|
||||||
@@ -80,6 +84,8 @@ namespace Telegrator.Handlers
|
|||||||
/// <param name="messageEffectId">The message effect ID.</param>
|
/// <param name="messageEffectId">The message effect ID.</param>
|
||||||
/// <param name="businessConnectionId">The business connection ID.</param>
|
/// <param name="businessConnectionId">The business connection ID.</param>
|
||||||
/// <param name="allowPaidBroadcast">Whether to allow paid broadcast.</param>
|
/// <param name="allowPaidBroadcast">Whether to allow paid broadcast.</param>
|
||||||
|
/// <param name="directMessageTopicId"></param>
|
||||||
|
/// <param name="suggestedPostParameters"></param>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>The sent message.</returns>
|
/// <returns>The sent message.</returns>
|
||||||
protected async Task<Message> Responce(
|
protected async Task<Message> Responce(
|
||||||
@@ -95,6 +101,8 @@ namespace Telegrator.Handlers
|
|||||||
string? messageEffectId = null,
|
string? messageEffectId = null,
|
||||||
string? businessConnectionId = null,
|
string? businessConnectionId = null,
|
||||||
bool allowPaidBroadcast = false,
|
bool allowPaidBroadcast = false,
|
||||||
|
int? directMessageTopicId = null,
|
||||||
|
SuggestedPostParameters? suggestedPostParameters = null,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
=> await Container.Responce(
|
=> await Container.Responce(
|
||||||
text, parseMode, replyParameters,
|
text, parseMode, replyParameters,
|
||||||
@@ -102,7 +110,8 @@ namespace Telegrator.Handlers
|
|||||||
messageThreadId, entities,
|
messageThreadId, entities,
|
||||||
disableNotification, protectContent,
|
disableNotification, protectContent,
|
||||||
messageEffectId, businessConnectionId,
|
messageEffectId, businessConnectionId,
|
||||||
allowPaidBroadcast, cancellationToken);
|
allowPaidBroadcast, directMessageTopicId,
|
||||||
|
suggestedPostParameters, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -125,6 +134,8 @@ namespace Telegrator.Handlers
|
|||||||
/// <param name="messageEffectId">The message effect ID.</param>
|
/// <param name="messageEffectId">The message effect ID.</param>
|
||||||
/// <param name="businessConnectionId">The business connection ID.</param>
|
/// <param name="businessConnectionId">The business connection ID.</param>
|
||||||
/// <param name="allowPaidBroadcast">Whether to allow paid broadcast.</param>
|
/// <param name="allowPaidBroadcast">Whether to allow paid broadcast.</param>
|
||||||
|
/// <param name="directMessageTopicId"></param>
|
||||||
|
/// <param name="suggestedPostParameters"></param>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>The sent message.</returns>
|
/// <returns>The sent message.</returns>
|
||||||
protected async Task<Message> Reply(
|
protected async Task<Message> Reply(
|
||||||
@@ -139,6 +150,8 @@ namespace Telegrator.Handlers
|
|||||||
string? messageEffectId = null,
|
string? messageEffectId = null,
|
||||||
string? businessConnectionId = null,
|
string? businessConnectionId = null,
|
||||||
bool allowPaidBroadcast = false,
|
bool allowPaidBroadcast = false,
|
||||||
|
int? directMessageTopicId = null,
|
||||||
|
SuggestedPostParameters? suggestedPostParameters = null,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
=> await Container.Reply(
|
=> await Container.Reply(
|
||||||
text, parseMode,
|
text, parseMode,
|
||||||
@@ -146,7 +159,8 @@ namespace Telegrator.Handlers
|
|||||||
messageThreadId, entities,
|
messageThreadId, entities,
|
||||||
disableNotification, protectContent,
|
disableNotification, protectContent,
|
||||||
messageEffectId, businessConnectionId,
|
messageEffectId, businessConnectionId,
|
||||||
allowPaidBroadcast, cancellationToken);
|
allowPaidBroadcast, directMessageTopicId,
|
||||||
|
suggestedPostParameters, cancellationToken);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sends a response message to the current chat.
|
/// Sends a response message to the current chat.
|
||||||
@@ -163,6 +177,8 @@ namespace Telegrator.Handlers
|
|||||||
/// <param name="messageEffectId">The message effect ID.</param>
|
/// <param name="messageEffectId">The message effect ID.</param>
|
||||||
/// <param name="businessConnectionId">The business connection ID.</param>
|
/// <param name="businessConnectionId">The business connection ID.</param>
|
||||||
/// <param name="allowPaidBroadcast">Whether to allow paid broadcast.</param>
|
/// <param name="allowPaidBroadcast">Whether to allow paid broadcast.</param>
|
||||||
|
/// <param name="directMessageTopicId"></param>
|
||||||
|
/// <param name="suggestedPostParameters"></param>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>The sent message.</returns>
|
/// <returns>The sent message.</returns>
|
||||||
protected async Task<Message> Responce(
|
protected async Task<Message> Responce(
|
||||||
@@ -178,6 +194,8 @@ namespace Telegrator.Handlers
|
|||||||
string? messageEffectId = null,
|
string? messageEffectId = null,
|
||||||
string? businessConnectionId = null,
|
string? businessConnectionId = null,
|
||||||
bool allowPaidBroadcast = false,
|
bool allowPaidBroadcast = false,
|
||||||
|
int? directMessageTopicId = null,
|
||||||
|
SuggestedPostParameters? suggestedPostParameters = null,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
=> await Container.Responce(
|
=> await Container.Responce(
|
||||||
text, parseMode, replyParameters,
|
text, parseMode, replyParameters,
|
||||||
@@ -185,6 +203,7 @@ namespace Telegrator.Handlers
|
|||||||
messageThreadId, entities,
|
messageThreadId, entities,
|
||||||
disableNotification, protectContent,
|
disableNotification, protectContent,
|
||||||
messageEffectId, businessConnectionId,
|
messageEffectId, businessConnectionId,
|
||||||
allowPaidBroadcast, cancellationToken);
|
allowPaidBroadcast, directMessageTopicId,
|
||||||
|
suggestedPostParameters, cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace Telegrator.Logging
|
|||||||
/// Minimal level of logging messages.
|
/// Minimal level of logging messages.
|
||||||
/// Any messages below thi value will not be writen!
|
/// Any messages below thi value will not be writen!
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static LogLevel MinimalLevel { get; set; }
|
public static LogLevel MinimalLevel { get; set; } = LogLevel.Information;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a logger adapter to the centralized logging system.
|
/// Adds a logger adapter to the centralized logging system.
|
||||||
|
|||||||
@@ -7,7 +7,14 @@ namespace Telegrator.Markups
|
|||||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
||||||
public sealed class CallbackButtonAttribute(string name, string data) : Attribute
|
public sealed class CallbackButtonAttribute(string name, string data) : Attribute
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Name of button
|
||||||
|
/// </summary>
|
||||||
public string Name { get; } = name;
|
public string Name { get; } = name;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Data that will be send to bot
|
||||||
|
/// </summary>
|
||||||
public string Data { get; } = data;
|
public string Data { get; } = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -15,7 +22,14 @@ namespace Telegrator.Markups
|
|||||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
||||||
public sealed class GameButtonAttribute(string name, string data) : Attribute
|
public sealed class GameButtonAttribute(string name, string data) : Attribute
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Name of button
|
||||||
|
/// </summary>
|
||||||
public string Name { get; } = name;
|
public string Name { get; } = name;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Game to open
|
||||||
|
/// </summary>
|
||||||
public string Game { get; } = data;
|
public string Game { get; } = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,7 +37,14 @@ namespace Telegrator.Markups
|
|||||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
||||||
public sealed class CopyTextButtonAttribute(string name, CopyTextButton copyText) : Attribute
|
public sealed class CopyTextButtonAttribute(string name, CopyTextButton copyText) : Attribute
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Name of button
|
||||||
|
/// </summary>
|
||||||
public string Name { get; } = name;
|
public string Name { get; } = name;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Text to copy
|
||||||
|
/// </summary>
|
||||||
public CopyTextButton CopyText { get; } = copyText;
|
public CopyTextButton CopyText { get; } = copyText;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,6 +52,9 @@ namespace Telegrator.Markups
|
|||||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
||||||
public sealed class PayRequestButtonAttribute(string name) : Attribute
|
public sealed class PayRequestButtonAttribute(string name) : Attribute
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Name of button
|
||||||
|
/// </summary>
|
||||||
public string Name { get; } = name;
|
public string Name { get; } = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,7 +62,14 @@ namespace Telegrator.Markups
|
|||||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
||||||
public sealed class LoginButtonAttribute(string name, LoginUrl url) : Attribute
|
public sealed class LoginButtonAttribute(string name, LoginUrl url) : Attribute
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Name of button
|
||||||
|
/// </summary>
|
||||||
public string Name { get; } = name;
|
public string Name { get; } = name;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Url of app to login to
|
||||||
|
/// </summary>
|
||||||
public LoginUrl Url { get; } = url;
|
public LoginUrl Url { get; } = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,7 +77,14 @@ namespace Telegrator.Markups
|
|||||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
||||||
public sealed class UrlRedirectButtonAttribute(string name, string url) : Attribute
|
public sealed class UrlRedirectButtonAttribute(string name, string url) : Attribute
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Name of button
|
||||||
|
/// </summary>
|
||||||
public string Name { get; } = name;
|
public string Name { get; } = name;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Url to redirect user
|
||||||
|
/// </summary>
|
||||||
public string Url { get; } = url;
|
public string Url { get; } = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +92,14 @@ namespace Telegrator.Markups
|
|||||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
||||||
public sealed class WebAppButtonAttribute(string name, WebAppInfo webApp) : Attribute
|
public sealed class WebAppButtonAttribute(string name, WebAppInfo webApp) : Attribute
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Name of button
|
||||||
|
/// </summary>
|
||||||
public string Name { get; } = name;
|
public string Name { get; } = name;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Info about mini app to open
|
||||||
|
/// </summary>
|
||||||
public WebAppInfo AppInfo { get; } = webApp;
|
public WebAppInfo AppInfo { get; } = webApp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,7 +107,14 @@ namespace Telegrator.Markups
|
|||||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
||||||
public sealed class SwitchQueryButtonAttribute(string name, string switchInlineQuery = "") : Attribute
|
public sealed class SwitchQueryButtonAttribute(string name, string switchInlineQuery = "") : Attribute
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Name of button
|
||||||
|
/// </summary>
|
||||||
public string Name { get; } = name;
|
public string Name { get; } = name;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Query
|
||||||
|
/// </summary>
|
||||||
public string Query { get; } = switchInlineQuery;
|
public string Query { get; } = switchInlineQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +122,14 @@ namespace Telegrator.Markups
|
|||||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
||||||
public sealed class QueryCurrentButtonAttribute(string name, string switchInlineQueryCurrentChat = "") : Attribute
|
public sealed class QueryCurrentButtonAttribute(string name, string switchInlineQueryCurrentChat = "") : Attribute
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Name of button
|
||||||
|
/// </summary>
|
||||||
public string Name { get; } = name;
|
public string Name { get; } = name;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Query
|
||||||
|
/// </summary>
|
||||||
public string Query { get; } = switchInlineQueryCurrentChat;
|
public string Query { get; } = switchInlineQueryCurrentChat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -158,10 +158,6 @@ namespace Telegrator.Polling
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
//IEnumerable<DescribedHandlerInfo> described = DescribeDescriptors(provider, descriptors, updateRouter, client, update, cancellationToken);
|
|
||||||
//Alligator.RouterWriteLine("Described total of {0} handlers for Update ({1}) from {2} provider", described.Count(), update.Id, provider.GetType().Name);
|
|
||||||
//Alligator.RouterWriteLine("Described handlers : {0}", string.Join(", ", described));
|
|
||||||
|
|
||||||
return DescribeDescriptors(provider, descriptors, client, update, cancellationToken);
|
return DescribeDescriptors(provider, descriptors, client, update, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Telegram.Bot" Version="22.5.1" />
|
<PackageReference Include="Telegram.Bot" Version="22.6.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -225,6 +225,8 @@ namespace Telegrator
|
|||||||
/// <param name="messageEffectId">The message effect ID.</param>
|
/// <param name="messageEffectId">The message effect ID.</param>
|
||||||
/// <param name="businessConnectionId">The business connection ID.</param>
|
/// <param name="businessConnectionId">The business connection ID.</param>
|
||||||
/// <param name="allowPaidBroadcast">Whether to allow paid broadcast.</param>
|
/// <param name="allowPaidBroadcast">Whether to allow paid broadcast.</param>
|
||||||
|
/// <param name="directMessageTopicId"></param>
|
||||||
|
/// <param name="suggestedPostParameters"></param>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>The sent message.</returns>
|
/// <returns>The sent message.</returns>
|
||||||
public static async Task<Message> Reply(
|
public static async Task<Message> Reply(
|
||||||
@@ -240,6 +242,8 @@ namespace Telegrator
|
|||||||
string? messageEffectId = null,
|
string? messageEffectId = null,
|
||||||
string? businessConnectionId = null,
|
string? businessConnectionId = null,
|
||||||
bool allowPaidBroadcast = false,
|
bool allowPaidBroadcast = false,
|
||||||
|
int? directMessageTopicId = null,
|
||||||
|
SuggestedPostParameters? suggestedPostParameters = null,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
=> await container.Client.SendMessage(
|
=> await container.Client.SendMessage(
|
||||||
container.ActualUpdate.Chat, text, parseMode, container.ActualUpdate,
|
container.ActualUpdate.Chat, text, parseMode, container.ActualUpdate,
|
||||||
@@ -247,7 +251,8 @@ namespace Telegrator
|
|||||||
messageThreadId, entities,
|
messageThreadId, entities,
|
||||||
disableNotification, protectContent,
|
disableNotification, protectContent,
|
||||||
messageEffectId, businessConnectionId,
|
messageEffectId, businessConnectionId,
|
||||||
allowPaidBroadcast, cancellationToken);
|
allowPaidBroadcast, directMessageTopicId,
|
||||||
|
suggestedPostParameters, cancellationToken);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sends a response message to the current chat.
|
/// Sends a response message to the current chat.
|
||||||
@@ -265,6 +270,8 @@ namespace Telegrator
|
|||||||
/// <param name="messageEffectId">The message effect ID.</param>
|
/// <param name="messageEffectId">The message effect ID.</param>
|
||||||
/// <param name="businessConnectionId">The business connection ID.</param>
|
/// <param name="businessConnectionId">The business connection ID.</param>
|
||||||
/// <param name="allowPaidBroadcast">Whether to allow paid broadcast.</param>
|
/// <param name="allowPaidBroadcast">Whether to allow paid broadcast.</param>
|
||||||
|
/// <param name="directMessageTopicId"></param>
|
||||||
|
/// <param name="suggestedPostParameters"></param>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>The sent message.</returns>
|
/// <returns>The sent message.</returns>
|
||||||
public static async Task<Message> Responce(
|
public static async Task<Message> Responce(
|
||||||
@@ -281,6 +288,8 @@ namespace Telegrator
|
|||||||
string? messageEffectId = null,
|
string? messageEffectId = null,
|
||||||
string? businessConnectionId = null,
|
string? businessConnectionId = null,
|
||||||
bool allowPaidBroadcast = false,
|
bool allowPaidBroadcast = false,
|
||||||
|
int? directMessageTopicId = null,
|
||||||
|
SuggestedPostParameters? suggestedPostParameters = null,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
=> await container.Client.SendMessage(
|
=> await container.Client.SendMessage(
|
||||||
container.ActualUpdate.Chat, text, parseMode, replyParameters,
|
container.ActualUpdate.Chat, text, parseMode, replyParameters,
|
||||||
@@ -288,7 +297,8 @@ namespace Telegrator
|
|||||||
messageThreadId, entities,
|
messageThreadId, entities,
|
||||||
disableNotification, protectContent,
|
disableNotification, protectContent,
|
||||||
messageEffectId, businessConnectionId,
|
messageEffectId, businessConnectionId,
|
||||||
allowPaidBroadcast, cancellationToken);
|
allowPaidBroadcast, directMessageTopicId,
|
||||||
|
suggestedPostParameters, cancellationToken);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Responnces to message that this CallbackQuery was originated from
|
/// Responnces to message that this CallbackQuery was originated from
|
||||||
@@ -306,6 +316,8 @@ namespace Telegrator
|
|||||||
/// <param name="messageEffectId"></param>
|
/// <param name="messageEffectId"></param>
|
||||||
/// <param name="businessConnectionId"></param>
|
/// <param name="businessConnectionId"></param>
|
||||||
/// <param name="allowPaidBroadcast"></param>
|
/// <param name="allowPaidBroadcast"></param>
|
||||||
|
/// <param name="directMessageTopicId"></param>
|
||||||
|
/// <param name="suggestedPostParameters"></param>
|
||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
/// <exception cref="Exception"></exception>
|
/// <exception cref="Exception"></exception>
|
||||||
@@ -323,6 +335,8 @@ namespace Telegrator
|
|||||||
string? messageEffectId = null,
|
string? messageEffectId = null,
|
||||||
string? businessConnectionId = null,
|
string? businessConnectionId = null,
|
||||||
bool allowPaidBroadcast = false,
|
bool allowPaidBroadcast = false,
|
||||||
|
int? directMessageTopicId = null,
|
||||||
|
SuggestedPostParameters? suggestedPostParameters = null,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
CallbackQuery query = container.ActualUpdate;
|
CallbackQuery query = container.ActualUpdate;
|
||||||
@@ -335,7 +349,8 @@ namespace Telegrator
|
|||||||
messageThreadId, entities,
|
messageThreadId, entities,
|
||||||
disableNotification, protectContent,
|
disableNotification, protectContent,
|
||||||
messageEffectId, businessConnectionId,
|
messageEffectId, businessConnectionId,
|
||||||
allowPaidBroadcast, cancellationToken);
|
allowPaidBroadcast, directMessageTopicId,
|
||||||
|
suggestedPostParameters, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
// This file is used by Code Analysis to maintain SuppressMessage
|
|
||||||
// attributes that are applied to this project.
|
|
||||||
// Project-level suppressions either have no target or are given
|
|
||||||
// a specific target and scoped to a namespace, type, member, etc.
|
|
||||||
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
|
|
||||||
[assembly: SuppressMessage("Style", "IDE0090")]
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
|
||||||
<LangVersion>latest</LangVersion>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
|
|
||||||
<IncludeBuildOutput>False</IncludeBuildOutput>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="4.14.0">
|
|
||||||
<PrivateAssets>all</PrivateAssets>
|
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
|
||||||
</PackageReference>
|
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.14.0" />
|
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.14.0" />
|
|
||||||
|
|
||||||
<PackageReference Include="PolySharp" Version="1.15.0">
|
|
||||||
<PrivateAssets>all</PrivateAssets>
|
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
|
||||||
</PackageReference>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -4,14 +4,36 @@ using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Telegrator.RoslynExtensions;
|
using Telegrator.RoslynExtensions;
|
||||||
|
using Telegrator.RoslynGenerators.RoslynExtensions;
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
using System.Diagnostics;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Telegrator.RoslynGenerators
|
namespace Telegrator.RoslynGenerators
|
||||||
{
|
{
|
||||||
[Generator(LanguageNames.CSharp)]
|
[Generator(LanguageNames.CSharp)]
|
||||||
public class ImplicitHandlerBuilderExtensionsGenerator : IIncrementalGenerator
|
public class ImplicitHandlerBuilderExtensionsGenerator : IIncrementalGenerator
|
||||||
{
|
{
|
||||||
|
private static readonly string[] DefaultUsings =
|
||||||
|
[
|
||||||
|
"Telegrator.Handlers.Building",
|
||||||
|
"Telegrator.Handlers.Building.Components"
|
||||||
|
];
|
||||||
|
|
||||||
|
private static readonly ParameterSyntax ExtensionMethodThisParam = SyntaxFactory.Parameter(SyntaxFactory.Identifier("builder")).WithType(SyntaxFactory.IdentifierName("TBuilder").WithLeadingTrivia(SyntaxFactory.SyntaxTrivia(SyntaxKind.WhitespaceTrivia, " ")).WithTrailingTrivia(WhitespaceTrivia)).WithModifiers([SyntaxFactory.Token(SyntaxKind.ThisKeyword)]);
|
||||||
|
private static readonly MemberAccessExpressionSyntax BuilderAdderMethodAccessExpression = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.IdentifierName("builder"), SyntaxFactory.IdentifierName("AddTargetedFilters"));
|
||||||
|
private static readonly IEqualityComparer<UsingDirectiveSyntax> UsingEqualityComparer = new UsingDirectiveEqualityComparer();
|
||||||
|
|
||||||
|
private static SyntaxTrivia TabulationTrivia => SyntaxFactory.SyntaxTrivia(SyntaxKind.WhitespaceTrivia, "\t");
|
||||||
|
private static SyntaxTrivia WhitespaceTrivia => SyntaxFactory.SyntaxTrivia(SyntaxKind.WhitespaceTrivia, " ");
|
||||||
|
private static SyntaxTrivia NewLineTrivia => SyntaxFactory.SyntaxTrivia(SyntaxKind.EndOfLineTrivia, "\n");
|
||||||
|
|
||||||
public void Initialize(IncrementalGeneratorInitializationContext context)
|
public void Initialize(IncrementalGeneratorInitializationContext context)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
Debugger.Launch();
|
||||||
|
#endif
|
||||||
IncrementalValueProvider<ImmutableArray<ClassDeclarationSyntax>> pipeline = context.SyntaxProvider
|
IncrementalValueProvider<ImmutableArray<ClassDeclarationSyntax>> pipeline = context.SyntaxProvider
|
||||||
.CreateSyntaxProvider(SyntaxPredicate, SyntaxTransform)
|
.CreateSyntaxProvider(SyntaxPredicate, SyntaxTransform)
|
||||||
.Where(declaration => declaration != null)
|
.Where(declaration => declaration != null)
|
||||||
@@ -20,12 +42,10 @@ namespace Telegrator.RoslynGenerators
|
|||||||
context.RegisterImplementationSourceOutput(pipeline, GenerateSource);
|
context.RegisterImplementationSourceOutput(pipeline, GenerateSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool SyntaxPredicate(SyntaxNode node, CancellationToken _)
|
private static bool SyntaxPredicate(SyntaxNode node, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (node is not ClassDeclarationSyntax)
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
return false;
|
return node is ClassDeclarationSyntax;
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ClassDeclarationSyntax SyntaxTransform(GeneratorSyntaxContext context, CancellationToken _)
|
private static ClassDeclarationSyntax SyntaxTransform(GeneratorSyntaxContext context, CancellationToken _)
|
||||||
@@ -45,59 +65,246 @@ namespace Telegrator.RoslynGenerators
|
|||||||
|
|
||||||
private static void GenerateSource(SourceProductionContext context, ImmutableArray<ClassDeclarationSyntax> declarations)
|
private static void GenerateSource(SourceProductionContext context, ImmutableArray<ClassDeclarationSyntax> declarations)
|
||||||
{
|
{
|
||||||
StringBuilder source = new StringBuilder();
|
StringBuilder debugExport = new StringBuilder("/*");
|
||||||
|
List<UsingDirectiveSyntax> usings = ParseUsings(DefaultUsings).ToList();
|
||||||
|
|
||||||
|
/*
|
||||||
Dictionary<string, string> targeters = [];
|
Dictionary<string, string> targeters = [];
|
||||||
List<string> usingDirectives =
|
List<string> usingDirectives =
|
||||||
[
|
[
|
||||||
"using Telegrator.Handlers.Building;",
|
"using Telegrator.Handlers.Building;",
|
||||||
"using Telegrator.Handlers.Building.Components;"
|
"using Telegrator.Handlers.Building.Components;"
|
||||||
];
|
];
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
StringBuilder sourceBuilder = new StringBuilder()
|
StringBuilder sourceBuilder = new StringBuilder()
|
||||||
.AppendLine("namespace Telegrator")
|
.AppendLine("namespace Telegrator")
|
||||||
.AppendLine("{")
|
.AppendLine("{")
|
||||||
.Append("\t//").Append(string.Join(", ", declarations.Select(decl => decl.Identifier.ToString()))).AppendLine()
|
.Append("\t//").Append(string.Join(", ", declarations.Select(decl => decl.Identifier.ToString()))).AppendLine()
|
||||||
.AppendLine("\tpublic static partial class HandlerBuilderExtensions")
|
.AppendLine("\tpublic static partial class HandlerBuilderExtensions")
|
||||||
.AppendLine("\t{");
|
.AppendLine("\t{");
|
||||||
|
*/
|
||||||
|
|
||||||
List<ClassDeclarationSyntax> lateTargeterClasses = [];
|
Dictionary<string, MethodDeclarationSyntax> targetters = [];
|
||||||
foreach (ClassDeclarationSyntax classDeclaration in declarations)
|
foreach (ClassDeclarationSyntax classDeclaration in declarations)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
usingDirectives.UnionAdd(classDeclaration.FindAncestor<CompilationUnitSyntax>().Usings.Select(use => use.ToString()));
|
string className = classDeclaration.Identifier.ToString();
|
||||||
ParseClassDeclaration(sourceBuilder, classDeclaration, targeters);
|
if (className == "FilterAnnotation")
|
||||||
}
|
continue;
|
||||||
catch (TargteterNotFoundException)
|
|
||||||
{
|
MethodDeclarationSyntax? targeter = classDeclaration.Members.OfType<MethodDeclarationSyntax>().SingleOrDefault(IsTargeterMethod);
|
||||||
lateTargeterClasses.Add(classDeclaration);
|
if (targeter != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
MethodDeclarationSyntax genTargeter = GenerateTargetterMethod(classDeclaration, targeter);
|
||||||
|
targetters.Add(className, genTargeter);
|
||||||
|
}
|
||||||
|
catch (Exception exc)
|
||||||
|
{
|
||||||
|
string errorFormat = string.Format("\nFailed to generate for {0} : {1}\n", classDeclaration.Identifier.ToString(), exc.ToString());
|
||||||
|
debugExport.AppendLine(errorFormat);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception exc)
|
catch (Exception exc)
|
||||||
{
|
{
|
||||||
string errorFormat = string.Format("\t\t// failed to generate for {0} : {1}", classDeclaration.Identifier.ToString(), exc.GetType().Name);
|
string errorFormat = string.Format("\nFailed to generate for {0} : {1}\n", classDeclaration.Identifier.ToString(), exc.ToString());
|
||||||
sourceBuilder.AppendLine(errorFormat);
|
debugExport.AppendLine(errorFormat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (ClassDeclarationSyntax classDeclaration in lateTargeterClasses)
|
List<MethodDeclarationSyntax> extensions = [];
|
||||||
|
foreach (ClassDeclarationSyntax classDeclaration in declarations)
|
||||||
{
|
{
|
||||||
try
|
if (classDeclaration.Modifiers.HasModifiers("abstract"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
usings.UnionAdd(classDeclaration.FindAncestor<CompilationUnitSyntax>().Usings, UsingEqualityComparer);
|
||||||
|
MethodDeclarationSyntax targeter = FindTargetterMethod(targetters, classDeclaration);
|
||||||
|
|
||||||
|
if (classDeclaration.ParameterList != null && classDeclaration.BaseList != null)
|
||||||
{
|
{
|
||||||
usingDirectives.UnionAdd(classDeclaration.FindAncestor<CompilationUnitSyntax>().Usings.Select(use => use.ToString()));
|
try
|
||||||
ParseClassDeclaration(sourceBuilder, classDeclaration, targeters);
|
{
|
||||||
|
PrimaryConstructorBaseTypeSyntax primaryConstructor = (PrimaryConstructorBaseTypeSyntax)classDeclaration.BaseList.Types.ElementAt(0);
|
||||||
|
MethodDeclarationSyntax genExtension = GeneratedExtensionsMethod(classDeclaration, classDeclaration.ParameterList, primaryConstructor.ArgumentList, targeter);
|
||||||
|
extensions.Add(genExtension);
|
||||||
|
}
|
||||||
|
catch (Exception exc)
|
||||||
|
{
|
||||||
|
string errorFormat = string.Format("\nFailed to generate for {0} : {1}\n", classDeclaration.Identifier.ToString(), exc.ToString());
|
||||||
|
debugExport.AppendLine(errorFormat);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception exc)
|
|
||||||
|
foreach (ConstructorDeclarationSyntax ctor in GetConstructors(classDeclaration))
|
||||||
{
|
{
|
||||||
string errorFormat = string.Format("\t\t// failed to generate for {0} : {1}", classDeclaration.Identifier.ToString(), exc.GetType().Name);
|
try
|
||||||
sourceBuilder.AppendLine(errorFormat);
|
{
|
||||||
|
if (ctor.Initializer == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
MethodDeclarationSyntax genExtension = GeneratedExtensionsMethod(classDeclaration, ctor.ParameterList, ctor.Initializer.ArgumentList, targeter);
|
||||||
|
extensions.Add(genExtension);
|
||||||
|
}
|
||||||
|
catch (Exception exc)
|
||||||
|
{
|
||||||
|
string errorFormat = string.Format("\nFailed to generate for {0} : {1}\n", classDeclaration.Identifier.ToString(), exc.ToString());
|
||||||
|
debugExport.AppendLine(errorFormat);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceBuilder.AppendLine("\t}\n}");
|
try
|
||||||
sourceBuilder.Insert(0, string.Join("\n", usingDirectives.Select(use => use.ToString()).OrderBy(use => use)) + "\n\n");
|
{
|
||||||
context.AddSource("GeneratedHandlerBuilderExtensions.cs", sourceBuilder.ToString());
|
ClassDeclarationSyntax extensionsClass = SyntaxFactory.ClassDeclaration("HandlerBuilderExtensions")
|
||||||
|
.WithModifiers(Modifiers(SyntaxKind.PublicKeyword, SyntaxKind.StaticKeyword, SyntaxKind.PartialKeyword))
|
||||||
|
.AddMembers([.. targetters.Values, .. extensions])
|
||||||
|
.DecorateType(1);
|
||||||
|
|
||||||
|
NamespaceDeclarationSyntax namespaceDeclaration = SyntaxFactory.NamespaceDeclaration(SyntaxFactory.ParseName("Telegrator"))
|
||||||
|
.WithMembers([extensionsClass])
|
||||||
|
.Decorate();
|
||||||
|
|
||||||
|
CompilationUnitSyntax compilationUnit = SyntaxFactory.CompilationUnit()
|
||||||
|
.WithUsings([.. usings])
|
||||||
|
.WithMembers([namespaceDeclaration]);
|
||||||
|
|
||||||
|
context.AddSource("GeneratedHandlerBuilderExtensions.cs", compilationUnit.ToFullString());
|
||||||
|
}
|
||||||
|
catch (Exception exc)
|
||||||
|
{
|
||||||
|
string errorFormat = string.Format("\nFailed to generate : {0}\n", exc.ToString());
|
||||||
|
debugExport.AppendLine(errorFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
context.AddSource("GeneratedHandlerBuilderExtensions.Debug.cs", debugExport.AppendLine("*/").ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static MethodDeclarationSyntax GenerateTargetterMethod(ClassDeclarationSyntax classDeclaration, MethodDeclarationSyntax targetterMethod)
|
||||||
|
{
|
||||||
|
SyntaxToken identifier = SyntaxFactory.Identifier(classDeclaration.Identifier.ToString() + "_" + targetterMethod.Identifier.ToString());
|
||||||
|
MethodDeclarationSyntax method = SyntaxFactory.MethodDeclaration(targetterMethod.ReturnType, identifier)
|
||||||
|
.WithParameterList(targetterMethod.ParameterList)
|
||||||
|
.WithModifiers(Modifiers(SyntaxKind.PrivateKeyword, SyntaxKind.StaticKeyword));
|
||||||
|
|
||||||
|
if (targetterMethod.Body != null)
|
||||||
|
method = method.WithBody(targetterMethod.Body);
|
||||||
|
|
||||||
|
if (targetterMethod.ExpressionBody != null)
|
||||||
|
method = method.WithExpressionBody(targetterMethod.ExpressionBody).WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken));
|
||||||
|
|
||||||
|
return method.DecorateMember(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MethodDeclarationSyntax GeneratedExtensionsMethod(ClassDeclarationSyntax classDeclaration, ParameterListSyntax methodParameters, ArgumentListSyntax invokerArguments, MethodDeclarationSyntax targetterMethod)
|
||||||
|
{
|
||||||
|
ParameterListSyntax parameters = SyntaxFactory.ParameterList([ExtensionMethodThisParam, ..methodParameters.Parameters]);
|
||||||
|
TypeParameterListSyntax typeParameters = SyntaxFactory.TypeParameterList([SyntaxFactory.TypeParameter("TBuilder")]);
|
||||||
|
|
||||||
|
InvocationExpressionSyntax invocationExpression = SyntaxFactory.InvocationExpression(BuilderAdderMethodAccessExpression, AddTargeter(invokerArguments, targetterMethod));
|
||||||
|
BlockSyntax body = SyntaxFactory.Block(new StatementSyntax[]
|
||||||
|
{
|
||||||
|
SyntaxFactory.ExpressionStatement(invocationExpression),
|
||||||
|
SyntaxFactory.ReturnStatement(SyntaxFactory.IdentifierName("builder").WithLeadingTrivia(WhitespaceTrivia))
|
||||||
|
});
|
||||||
|
|
||||||
|
TypeParameterConstraintClauseSyntax typeParameterConstraint = SyntaxFactory.TypeParameterConstraintClause(SyntaxFactory.IdentifierName("TBuilder").WithLeadingTrivia(WhitespaceTrivia).WithTrailingTrivia(WhitespaceTrivia))
|
||||||
|
.WithConstraints([SyntaxFactory.TypeConstraint(SyntaxFactory.ParseTypeName("IHandlerBuilder").WithLeadingTrivia(WhitespaceTrivia))])
|
||||||
|
.WithLeadingTrivia(WhitespaceTrivia);
|
||||||
|
|
||||||
|
string filterName = classDeclaration.Identifier.ToString().Replace("Attribute", string.Empty);
|
||||||
|
if (filterName == "ChatType")
|
||||||
|
filterName = "InChatType"; // Because it conflicting
|
||||||
|
|
||||||
|
SyntaxToken identifier = SyntaxFactory.Identifier(filterName);
|
||||||
|
TypeSyntax returnType = SyntaxFactory.ParseTypeName("TBuilder").WithTrailingTrivia(WhitespaceTrivia);
|
||||||
|
SyntaxTriviaList xmlDoc = BuildExtensionXmlDocTrivia(classDeclaration, methodParameters);
|
||||||
|
|
||||||
|
MethodDeclarationSyntax method = SyntaxFactory.MethodDeclaration(returnType, identifier)
|
||||||
|
.WithParameterList(parameters)
|
||||||
|
.WithBody(body.DecorateBlock(2))
|
||||||
|
.WithTypeParameterList(typeParameters)
|
||||||
|
.WithModifiers(Modifiers(SyntaxKind.PublicKeyword, SyntaxKind.StaticKeyword))
|
||||||
|
.WithConstraintClauses([typeParameterConstraint])
|
||||||
|
.DecorateMember(2)
|
||||||
|
.WithLeadingTrivia(xmlDoc);
|
||||||
|
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SyntaxTokenList Modifiers(params SyntaxKind[] kinds)
|
||||||
|
=> new SyntaxTokenList(kinds.Select(SyntaxFactory.Token).Select(mod => mod.WithTrailingTrivia(WhitespaceTrivia)));
|
||||||
|
|
||||||
|
private static IEnumerable<UsingDirectiveSyntax> ParseUsings(params string[] names) => names
|
||||||
|
.Select(name => SyntaxFactory.IdentifierName(name).WithLeadingTrivia(WhitespaceTrivia))
|
||||||
|
.Select(name => SyntaxFactory.UsingDirective(name).WithTrailingTrivia(NewLineTrivia));
|
||||||
|
|
||||||
|
private static ArgumentListSyntax AddTargeter(ArgumentListSyntax invokerArguments, MethodDeclarationSyntax targetterMethod)
|
||||||
|
=> SyntaxFactory.ArgumentList([SyntaxFactory.Argument(SyntaxFactory.IdentifierName(targetterMethod.Identifier)), ..invokerArguments.Arguments]);
|
||||||
|
|
||||||
|
private static bool IsTargeterMethod(MethodDeclarationSyntax method)
|
||||||
|
=> method.Identifier.ToString() == "GetFilterringTarget";
|
||||||
|
|
||||||
|
private static IEnumerable<ConstructorDeclarationSyntax> GetConstructors(ClassDeclarationSyntax classDeclaration)
|
||||||
|
=> classDeclaration.Members.OfType<ConstructorDeclarationSyntax>().Where(ctor => ctor.Modifiers.HasModifiers("public"));
|
||||||
|
|
||||||
|
private static MethodDeclarationSyntax FindTargetterMethod(Dictionary<string, MethodDeclarationSyntax> targeters, ClassDeclarationSyntax classDeclaration)
|
||||||
|
{
|
||||||
|
if (targeters.TryGetValue(classDeclaration.Identifier.ValueText, out MethodDeclarationSyntax targeter))
|
||||||
|
return targeter;
|
||||||
|
|
||||||
|
if (classDeclaration.BaseList != null && targeters.TryGetValue(classDeclaration.BaseList.Types.ElementAt(0).Type.ToString(), out targeter))
|
||||||
|
return targeter;
|
||||||
|
|
||||||
|
throw new TargteterNotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SyntaxTriviaList BuildExtensionXmlDocTrivia(ClassDeclarationSyntax classDeclaration, ParameterListSyntax methodParameters)
|
||||||
|
{
|
||||||
|
StringBuilder summaryBuilder = new StringBuilder();
|
||||||
|
|
||||||
|
summaryBuilder
|
||||||
|
.Append("\t\t/// <summary>\n")
|
||||||
|
.Append("\t\t/// Adds a ").Append(classDeclaration.Identifier.ToString()).Append(" target filter to the handler builder.\n")
|
||||||
|
.Append("\t\t/// </summary>\n");
|
||||||
|
|
||||||
|
summaryBuilder
|
||||||
|
.AppendLine("\t\t/// <typeparam name=\"TBuilder\">The builder type.</typeparam>")
|
||||||
|
.AppendLine("\t\t/// <param name=\"builder\">The handler builder.</param>");
|
||||||
|
|
||||||
|
foreach (ParameterSyntax param in methodParameters.Parameters)
|
||||||
|
{
|
||||||
|
string name = param.Identifier.ToString();
|
||||||
|
summaryBuilder
|
||||||
|
.Append("\t\t/// <param name=\"").Append(name).Append("\">")
|
||||||
|
.Append("The ").Append(name)
|
||||||
|
.AppendLine(".</param>");
|
||||||
|
}
|
||||||
|
|
||||||
|
summaryBuilder.AppendLine("\t\t/// <returns>The same builder instance.</returns>");
|
||||||
|
summaryBuilder.Append("\t\t");
|
||||||
|
return SyntaxFactory.ParseLeadingTrivia(summaryBuilder.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private class UsingDirectiveEqualityComparer : IEqualityComparer<UsingDirectiveSyntax>
|
||||||
|
{
|
||||||
|
public bool Equals(UsingDirectiveSyntax x, UsingDirectiveSyntax y)
|
||||||
|
{
|
||||||
|
return x.ToString() == y.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetHashCode(UsingDirectiveSyntax obj)
|
||||||
|
{
|
||||||
|
return obj.GetHashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
private static void ParseClassDeclaration(StringBuilder sourceBuilder, ClassDeclarationSyntax classDeclaration, Dictionary<string, string> targeters)
|
private static void ParseClassDeclaration(StringBuilder sourceBuilder, ClassDeclarationSyntax classDeclaration, Dictionary<string, string> targeters)
|
||||||
{
|
{
|
||||||
string className = classDeclaration.Identifier.ToString();
|
string className = classDeclaration.Identifier.ToString();
|
||||||
@@ -130,7 +337,7 @@ namespace Telegrator.RoslynGenerators
|
|||||||
classTargetterMethodName = targeters[baseClassName];
|
classTargetterMethodName = targeters[baseClassName];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (classDeclaration.Modifiers.Any(keyword => keyword.ValueText == "abstract"))
|
if (classDeclaration.Modifiers.HasModifiers("abstract"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (classDeclaration.ParameterList != null)
|
if (classDeclaration.ParameterList != null)
|
||||||
@@ -157,7 +364,9 @@ namespace Telegrator.RoslynGenerators
|
|||||||
sourceBuilder.AppendLine();
|
sourceBuilder.AppendLine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
private static void RenderExtensionMethod(StringBuilder sourceBuilder, string filterName, string classTargetterMethodName, SeparatedSyntaxList<ParameterSyntax> parameters, SeparatedSyntaxList<ArgumentSyntax> arguments)
|
private static void RenderExtensionMethod(StringBuilder sourceBuilder, string filterName, string classTargetterMethodName, SeparatedSyntaxList<ParameterSyntax> parameters, SeparatedSyntaxList<ArgumentSyntax> arguments)
|
||||||
{
|
{
|
||||||
if (filterName == "ChatType")
|
if (filterName == "ChatType")
|
||||||
@@ -205,5 +414,6 @@ namespace Telegrator.RoslynGenerators
|
|||||||
sourceBuilder.Append(targeterMethod.Body.ToFullString());
|
sourceBuilder.Append(targeterMethod.Body.ToFullString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
namespace Telegrator.RoslynExtensions
|
||||||
|
{
|
||||||
|
public static class CollectionsExtensions
|
||||||
|
{
|
||||||
|
public static IEnumerable<TSource> Combine<TSource>(params IEnumerable<TSource>[] collections)
|
||||||
|
=> collections.SelectMany(x => x);
|
||||||
|
|
||||||
|
public static IEnumerable<TSource> IntersectBy<TSource, TValue>(this IEnumerable<TSource> first, IEnumerable<TValue> second, Func<TSource, TValue> selector)
|
||||||
|
{
|
||||||
|
foreach (TSource item in first)
|
||||||
|
{
|
||||||
|
TValue value = selector(item);
|
||||||
|
if (second.Contains(value))
|
||||||
|
yield return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IList<TValue> UnionAdd<TValue>(this IList<TValue> source, IEnumerable<TValue> toUnion, IEqualityComparer<TValue> comparer)
|
||||||
|
{
|
||||||
|
foreach (TValue toUnionValue in toUnion)
|
||||||
|
{
|
||||||
|
if (!source.Contains(toUnionValue, comparer))
|
||||||
|
source.Add(toUnionValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UnionAdd<TSource>(this ICollection<TSource> collection, IEnumerable<TSource> target)
|
||||||
|
{
|
||||||
|
foreach (TSource item in target)
|
||||||
|
{
|
||||||
|
if (!collection.Contains(item))
|
||||||
|
collection.Add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UnionAdd<TSource>(this SortedList<TSource, TSource> collection, IEnumerable<TSource> target)
|
||||||
|
{
|
||||||
|
foreach (TSource item in target)
|
||||||
|
{
|
||||||
|
if (!collection.Values.Contains(item))
|
||||||
|
collection.Add(item, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int IndexOf<T>(this IEnumerable<T> source, Func<T, bool> predicate)
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
foreach (T item in source)
|
||||||
|
{
|
||||||
|
if (predicate.Invoke(item))
|
||||||
|
return index;
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<T> Repeat<T>(this T item, int times)
|
||||||
|
=> Enumerable.Range(0, times).Select(_ => item);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
using Microsoft.CodeAnalysis;
|
||||||
|
using Microsoft.CodeAnalysis.CSharp;
|
||||||
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
|
using Telegrator.RoslynExtensions;
|
||||||
|
|
||||||
|
namespace Telegrator.RoslynGenerators.RoslynExtensions
|
||||||
|
{
|
||||||
|
public static class MemberDeclarationSyntaxExtensions
|
||||||
|
{
|
||||||
|
private static SyntaxTrivia TabulationTrivia => SyntaxFactory.SyntaxTrivia(SyntaxKind.WhitespaceTrivia, "\t");
|
||||||
|
private static SyntaxTrivia WhitespaceTrivia => SyntaxFactory.SyntaxTrivia(SyntaxKind.WhitespaceTrivia, " ");
|
||||||
|
private static SyntaxTrivia NewLineTrivia => SyntaxFactory.SyntaxTrivia(SyntaxKind.EndOfLineTrivia, "\n");
|
||||||
|
|
||||||
|
public static SyntaxTokenList Decorate(this SyntaxTokenList tokens)
|
||||||
|
=> new SyntaxTokenList(tokens.Select(token => token.WithoutTrivia().WithTrailingTrivia(WhitespaceTrivia)).ToArray());
|
||||||
|
|
||||||
|
public static BlockSyntax DecorateBlock(this BlockSyntax block, int times) => block
|
||||||
|
.WithStatements([.. block.Statements.Select(statement => statement.DecorateStatememnt(times + 1))])
|
||||||
|
.WithOpenBraceToken(SyntaxFactory.Token(SyntaxKind.OpenBraceToken).WithLeadingTrivia(WhitespaceTrivia).WithTrailingTrivia(NewLineTrivia))
|
||||||
|
.WithCloseBraceToken(SyntaxFactory.Token(SyntaxKind.CloseBraceToken).WithLeadingTrivia(TabulationTrivia.Repeat(times)).WithTrailingTrivia(NewLineTrivia));
|
||||||
|
|
||||||
|
public static T DecorateStatememnt<T>(this T statememnt, int times) where T : StatementSyntax => statememnt
|
||||||
|
.WithoutTrivia().WithLeadingTrivia(TabulationTrivia.Repeat(times)).WithTrailingTrivia(NewLineTrivia);
|
||||||
|
|
||||||
|
public static T DecorateMember<T>(this T typeDeclaration, int times) where T : MemberDeclarationSyntax => typeDeclaration
|
||||||
|
.WithoutTrivia().WithLeadingTrivia(TabulationTrivia.Repeat(times)).WithTrailingTrivia(NewLineTrivia);
|
||||||
|
|
||||||
|
public static NamespaceDeclarationSyntax Decorate(this NamespaceDeclarationSyntax namespaceDeclaration) => namespaceDeclaration
|
||||||
|
.WithName(namespaceDeclaration.Name.WithoutTrivia().WithLeadingTrivia(WhitespaceTrivia))
|
||||||
|
.WithOpenBraceToken(SyntaxFactory.Token(SyntaxKind.OpenBraceToken).WithLeadingTrivia(NewLineTrivia).WithTrailingTrivia(NewLineTrivia))
|
||||||
|
.WithCloseBraceToken(SyntaxFactory.Token(SyntaxKind.CloseBraceToken));
|
||||||
|
|
||||||
|
public static T DecorateType<T>(this T typeDeclaration, int times = 1) where T : TypeDeclarationSyntax => (T)typeDeclaration
|
||||||
|
.WithoutTrivia().WithLeadingTrivia(TabulationTrivia.Repeat(times))
|
||||||
|
.WithIdentifier(typeDeclaration.Identifier.WithoutTrivia().WithLeadingTrivia(WhitespaceTrivia).WithTrailingTrivia(NewLineTrivia))
|
||||||
|
.WithOpenBraceToken(SyntaxFactory.Token(SyntaxKind.OpenBraceToken).WithLeadingTrivia(TabulationTrivia.Repeat(times)).WithTrailingTrivia(NewLineTrivia))
|
||||||
|
.WithCloseBraceToken(SyntaxFactory.Token(SyntaxKind.CloseBraceToken).WithLeadingTrivia(TabulationTrivia.Repeat(times)).WithTrailingTrivia(NewLineTrivia));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,9 +6,6 @@
|
|||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
|
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
|
||||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
|
||||||
<IsRoslynComponent>True</IsRoslynComponent>
|
|
||||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -20,9 +17,4 @@
|
|||||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.14.0" />
|
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.14.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\Telegrator.RoslynExtensions\Telegrator.RoslynExtensions.csproj" PrivateAssets="all" />
|
|
||||||
<None Include="$(OutputPath)\*.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
Reference in New Issue
Block a user