From 5101d82312e5c7e2356ec4268569fde3e6caf14e Mon Sep 17 00:00:00 2001 From: aa89227 Date: Wed, 15 May 2024 23:11:54 +0800 Subject: [PATCH] =?UTF-8?q?feat(Monopoly.Web.Generator):=20=E5=B0=87Genera?= =?UTF-8?q?tor=E7=9A=84provider=E5=9B=9E=E5=82=B3=E9=80=B2=E8=A1=8C?= =?UTF-8?q?=E9=87=8D=E6=A7=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TransformationResult.cs | 94 +++++++++++++++++++ .../TypeClientGenerator.cs | 69 ++------------ 2 files changed, 103 insertions(+), 60 deletions(-) create mode 100644 Monopoly.Web.Generators/TransformationResult.cs diff --git a/Monopoly.Web.Generators/TransformationResult.cs b/Monopoly.Web.Generators/TransformationResult.cs new file mode 100644 index 0000000..7138af8 --- /dev/null +++ b/Monopoly.Web.Generators/TransformationResult.cs @@ -0,0 +1,94 @@ +using Microsoft.CodeAnalysis; + +namespace Monopoly.Web.Generators; + +public class TransformationResult( + string name, + string @namespace, + string requestInterfaceName, + IMethodSymbol[] requestMethods, + IMethodSymbol[] responseMethods) + : IEquatable +{ + public string Name { get; } = name; + public string Namespace { get; } = @namespace; + public string RequestInterfaceName { get; } = requestInterfaceName; + public IMethodSymbol[] RequestMethods { get; } = requestMethods; + public IMethodSymbol[] ResponseMethods { get; } = responseMethods; + + public bool Equals(TransformationResult? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Name == other.Name + && Namespace == other.Namespace + && RequestInterfaceName == other.RequestInterfaceName + && CompareIMethodSymbol(RequestMethods, other.RequestMethods) + && CompareIMethodSymbol(ResponseMethods, other.ResponseMethods); + } + + public override bool Equals(object? obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + return obj.GetType() == GetType() && Equals((TransformationResult)obj); + } + + private static bool CompareIMethodSymbol(ReadOnlySpan x, ReadOnlySpan y) + { + if (x.Length != y.Length) + { + return false; + } + + for (var i = 0; i < x.Length; i++) + { + if (new MethodSymbolComparer().Equals(x[i], y[i]) == false) + { + return false; + } + } + + return true; + } + + public override int GetHashCode() + { + unchecked + { + var hashCode = Name.GetHashCode(); + hashCode = (hashCode * 397) ^ Namespace.GetHashCode(); + hashCode = (hashCode * 397) ^ RequestInterfaceName.GetHashCode(); + hashCode = (hashCode * 397) ^ RequestMethods.GetHashCode(); + hashCode = (hashCode * 397) ^ ResponseMethods.GetHashCode(); + return hashCode; + } + } + + private class MethodSymbolComparer : IEqualityComparer + { + public bool Equals(IMethodSymbol x, IMethodSymbol y) + { + return x.Name == y.Name + && x.Parameters.SequenceEqual(y.Parameters, new ParameterSymbolComparer()); + } + + public int GetHashCode(IMethodSymbol obj) + { + return obj.Name.GetHashCode(); + } + } + + private class ParameterSymbolComparer : IEqualityComparer + { + public bool Equals(IParameterSymbol x, IParameterSymbol y) + { + return x.Type.ToString() == y.Type.ToString() && x.Name == y.Name; + } + + public int GetHashCode(IParameterSymbol obj) + { + return obj.Type.ToString().GetHashCode(); + } + } +} \ No newline at end of file diff --git a/Monopoly.Web.Generators/TypeClientGenerator.cs b/Monopoly.Web.Generators/TypeClientGenerator.cs index e7a3a7b..0e0ab7d 100644 --- a/Monopoly.Web.Generators/TypeClientGenerator.cs +++ b/Monopoly.Web.Generators/TypeClientGenerator.cs @@ -1,5 +1,4 @@ -using System.Collections.Immutable; -using System.Text; +using System.Text; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Text; @@ -67,7 +66,7 @@ public partial class {{nodeInfo.Name}} : {{nodeInfo.RequestInterfaceName}} }); } - private static string GenerateRequests(IEnumerable nodeInfoHubRequestMethods) + private static string GenerateRequests(IEnumerable nodeInfoHubRequestMethods) { var methods = nodeInfoHubRequestMethods.Select(x => { @@ -84,7 +83,7 @@ private static string GenerateRequests(IEnumerable nodeInfo return string.Join("\n", methods); } - private static string GenerateEventRegistration(IEnumerable responseMethods) + private static string GenerateEventRegistration(IEnumerable responseMethods) { var events = responseMethods.Select(x => { @@ -98,7 +97,7 @@ private static string GenerateEventRegistration(IEnumerable return string.Join("\n", events); } - private static string GenerateDelegates(IEnumerable responseMethods) + private static string GenerateDelegates(IEnumerable responseMethods) { var delegates = responseMethods.Select(x => { @@ -111,10 +110,7 @@ private static string GenerateDelegates(IEnumerable respons return string.Join("\n", delegates); } - private static (string Name, string Namespace, string RequestInterfaceName, ImmutableArray - RequestMethods, - ImmutableArray ResponseMethods) - TransformContext(GeneratorAttributeSyntaxContext ctx) + private static TransformationResult TransformContext(GeneratorAttributeSyntaxContext ctx) { var attribute = ctx.Attributes .First(x => x.AttributeClass?.Name == "TypedHubClientAttribute"); @@ -128,63 +124,16 @@ private static (string Name, string Namespace, string RequestInterfaceName, Immu var requestMethods = hubRequestType .GetMembers() .OfType() - .Select(x => new MethodSymbolWrapper(x)) - .ToImmutableArray(); + .ToArray(); var responseMethods = hubResponseType! .GetMembers() .OfType() - .Select(x => new MethodSymbolWrapper(x)) - .ToImmutableArray(); + .ToArray(); - return (ctx.TargetSymbol.Name, ctx.TargetSymbol.ContainingNamespace.ToString(), hubRequestInterfaceName, + return new TransformationResult(ctx.TargetSymbol.Name, ctx.TargetSymbol.ContainingNamespace.ToString(), + hubRequestInterfaceName, requestMethods, responseMethods); } - - private class MethodSymbolWrapper(IMethodSymbol methodSymbol) - { - public string Name => methodSymbol.Name; - public ImmutableArray Parameters => methodSymbol.Parameters; - - public override bool Equals(object? obj) - { - if (obj is MethodSymbolWrapper other) - { - return Name == other.Name - && Parameters.SequenceEqual(other.Parameters, new ParameterSymbolComparer()); - } - - return false; - } - - public override int GetHashCode() - { - var hash = 17; - hash = hash * 23 + SymbolEqualityComparer.Default.GetHashCode(methodSymbol); - - hash = hash * 23 + Name.GetHashCode(); - - return Enumerable.Aggregate( - Parameters, hash, - (current, parameter) => - current * 23 + SymbolEqualityComparer.Default.GetHashCode(parameter)); - } - - private class ParameterSymbolComparer : IEqualityComparer - { - public bool Equals(IParameterSymbol x, IParameterSymbol y) - { - return SymbolEqualityComparer.Default.Equals(x.Type, y.Type) && x.Name == y.Name; - } - - public int GetHashCode(IParameterSymbol obj) - { - var hash = 17; - hash = hash * 23 + (obj.Name.GetHashCode()); - hash = hash * 23 + SymbolEqualityComparer.Default.GetHashCode(obj.Type); - return hash; - } - } - } } \ No newline at end of file