From d35c9546a40cc9cc8d23de8bbb50d1f19bd09818 Mon Sep 17 00:00:00 2001 From: Maxim Shilov Date: Wed, 3 Nov 2021 02:24:25 +0300 Subject: [PATCH] Fixed hub generator --- samples/Blazor/Server/Hubs/MainHub.cs | 5 ++ src/SignalR.Modules.Generator/HubGenerator.cs | 67 ++++++++++++++++--- src/SignalR.Modules/ModulesEntryHub.cs | 7 ++ 3 files changed, 69 insertions(+), 10 deletions(-) diff --git a/samples/Blazor/Server/Hubs/MainHub.cs b/samples/Blazor/Server/Hubs/MainHub.cs index b3b6621..7f799f6 100644 --- a/samples/Blazor/Server/Hubs/MainHub.cs +++ b/samples/Blazor/Server/Hubs/MainHub.cs @@ -1,6 +1,7 @@ using BlazorSignalR.Server.SignalRModules; using ChatModule.Server; using SignalR.Modules; +using System; using WeatherModule.Server; namespace BlazorSignalR.Server.Hubs @@ -10,5 +11,9 @@ namespace BlazorSignalR.Server.Hubs [SignalRModuleHub(typeof(CounterHub))] public partial class MainHub : ModulesEntryHub { + public MainHub(IServiceProvider provider) + : base(provider) + { + } } } diff --git a/src/SignalR.Modules.Generator/HubGenerator.cs b/src/SignalR.Modules.Generator/HubGenerator.cs index 7ffb860..06eb977 100644 --- a/src/SignalR.Modules.Generator/HubGenerator.cs +++ b/src/SignalR.Modules.Generator/HubGenerator.cs @@ -1,10 +1,14 @@ -using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; +using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; +#nullable enable + namespace SignalR.Modules.Generator { [Generator] @@ -14,16 +18,23 @@ public class HubGenerator : ISourceGenerator private const string AttributeName = "SignalRModuleHubAttribute"; private const string AttributeFullName = AttributeNamespace + "." + AttributeName; private const string AutoGeneratedFileHeader = -@"//------------------------------------------------------------------------------ -// -// This code was generated by the SignalR.Modules Source Generator. -// +@"//------------------------------------------------------------------------------ +// +// This code was generated by the SignalR.Modules Source Generator. +// //------------------------------------------------------------------------------"; public void Initialize(GeneratorInitializationContext context) { // Register a syntax receiver that will be created for each generation pass context.RegisterForSyntaxNotifications(() => new SyntaxReceiver()); + +#if DEBUG + if (!Debugger.IsAttached) + { + Debugger.Launch(); + } +#endif } public void Execute(GeneratorExecutionContext context) @@ -94,14 +105,50 @@ public partial class {entryHubTypeSymbol.Name} } source.Append(@" - } + } }"); return source.ToString(); } private string ProcessModuleHubMethod(INamedTypeSymbol moduleHubTypeSymbol, IMethodSymbol methodSymbol) { + var attributes = methodSymbol.GetAttributes(); + var constructedAttributes = attributes.Where(x => x.ConstructorArguments.Any()).ToList(); + var namedArgumentAttributes = attributes.Where(x => x.NamedArguments.Any()).ToList(); + + var ctorAttributesString = string.Join(Environment.NewLine, constructedAttributes + .Select(x => + { + var ctorArgumentsString = string.Join(",", x.ConstructorArguments + .Select(y => y.Kind switch + { + TypedConstantKind.Enum => $"{y.Type.Name}.{y.Value}", + _ when y.Type.SpecialType == SpecialType.System_String => $"\"{y.Value}\"", + _ => y.Value + }) + ); + return $"[{x.AttributeClass.ContainingNamespace.ToDisplayString()}.{x.AttributeClass.Name.Replace("Attribute", string.Empty)}({ctorArgumentsString})]"; + }) + ); + + var namedAttributesString = string.Join(Environment.NewLine, namedArgumentAttributes + .Select(x => + { + var namedArgumentsString = string.Join(",", x.NamedArguments + .Select(y => $@"{y.Key} = {y.Value.Kind switch + { + TypedConstantKind.Enum => $"{y.Value.Type.Name}.{y.Value}", + _ when y.Value.Type.SpecialType == SpecialType.System_String => $"\"{y.Value.Value}\"", + _ => y.Value.Value + }}") + ); + return $"[{x.AttributeClass.ContainingNamespace.ToDisplayString()}.{x.AttributeClass.Name.Replace("Attribute", string.Empty)}({namedArgumentsString})]"; + }) + ); + return $@" + {ctorAttributesString} + {namedAttributesString} public {(methodSymbol.ReturnsVoid ? string.Empty : methodSymbol.ReturnType.ToDisplayString())} {moduleHubTypeSymbol.Name}_{methodSymbol.Name}({string.Join(", ", methodSymbol.Parameters.Select(p => $"{p.Type.ToDisplayString()} {p.Name}"))}) {{ var hub = ServiceProvider.GetRequiredService<{moduleHubTypeSymbol.ToDisplayString()}>(); @@ -126,7 +173,7 @@ private string ProcessHubClientClass(INamedTypeSymbol entryHubTypeSymbol, INamed namespace {namespaceName} {{ - public class {className} : ClientProxy<{moduleHubTypeSymbol.Name}>, {typedClientInterface.Name} + public class {className} : ClientProxy<{moduleHubTypeSymbol.ToDisplayString()}>, {typedClientInterface.ToDisplayString()} {{ public {className}(IClientProxy clientProxy) : base(clientProxy) @@ -143,7 +190,7 @@ public class {className} : ClientProxy<{moduleHubTypeSymbol.Name}>, {typedClient } source.Append(@" - } + } }"); return source.ToString(); } @@ -153,7 +200,7 @@ private string ProcessHubClientMethod(IMethodSymbol methodSymbol) return $@" public Task {methodSymbol.Name}({string.Join(", ", methodSymbol.Parameters.Select(p => $"{p.Type.ToDisplayString()} {p.Name}"))}) {{ - return SendAsync(""{methodSymbol.Name}"", new[] {{ {string.Join(", ", methodSymbol.Parameters.Select(p => p.Name))} }}); + return SendAsync(""{methodSymbol.Name}"", new object[] {{ {string.Join(", ", methodSymbol.Parameters.Select(p => p.Name))} }}); }}"; } @@ -291,7 +338,7 @@ protected Task ModuleHubsOnDisconnectedAsync(Exception exception) } source.Append(@" - } + } }"); return source.ToString(); } diff --git a/src/SignalR.Modules/ModulesEntryHub.cs b/src/SignalR.Modules/ModulesEntryHub.cs index 9a19618..7ea8964 100644 --- a/src/SignalR.Modules/ModulesEntryHub.cs +++ b/src/SignalR.Modules/ModulesEntryHub.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; using System; namespace SignalR.Modules @@ -16,6 +17,12 @@ public ModulesEntryHub(ILogger logger, IServiceProvider serviceProvider) ServiceProvider = serviceProvider; } + public ModulesEntryHub(IServiceProvider serviceProvider) + { + Logger = NullLogger.Instance; + ServiceProvider = serviceProvider; + } + protected void InitModuleHub(TModuleHub hub) where TModuleHub : ModuleHub {