diff --git a/extern/CodeAnalysis b/extern/CodeAnalysis index 14898a1..92f540d 160000 --- a/extern/CodeAnalysis +++ b/extern/CodeAnalysis @@ -1 +1 @@ -Subproject commit 14898a19d90f1c7a322cc9b808c9159d73ecfe44 +Subproject commit 92f540d914683760456e8234f4e78cfb5e6923b6 diff --git a/src/Antelcat.ClaimSerialization.Abstractions/Antelcat.ClaimSerialization.Abstractions.csproj b/src/Antelcat.ClaimSerialization.Abstractions/Antelcat.ClaimSerialization.Abstractions.csproj deleted file mode 100644 index 68e3332..0000000 --- a/src/Antelcat.ClaimSerialization.Abstractions/Antelcat.ClaimSerialization.Abstractions.csproj +++ /dev/null @@ -1,41 +0,0 @@ - - - - netstandard2.0;net46; - enable - enable - true - preview - - 1.0.0 - 1.0.0 - 1.0.0 - - Antelcat - Antelcat.ClaimSerialization.Abstractions - Antelcat.ClaimSerialization.Abstractions - Antelcat.ClaimSerialization.Abstractions - true - Copyright Antelcat. All rights reserved - claim;serialization;abstractions; - Abstractions of Antelcat.ClaimSerialization, including interfaces and attributes - - git - MIT - https://github.com/Antelcat/Antelcat.ClaimSerialization.git - https://github.com/Antelcat/Antelcat.ClaimSerialization - - icon.png - README.md - Initial release - - - - - - - icon.png - - - - diff --git a/src/Antelcat.ClaimSerialization.Sample/Antelcat.ClaimSerialization.Sample.csproj b/src/Antelcat.ClaimSerialization.Sample/Antelcat.ClaimSerialization.Sample.csproj index 743762c..ebe0009 100644 --- a/src/Antelcat.ClaimSerialization.Sample/Antelcat.ClaimSerialization.Sample.csproj +++ b/src/Antelcat.ClaimSerialization.Sample/Antelcat.ClaimSerialization.Sample.csproj @@ -7,8 +7,8 @@ - + diff --git a/src/Antelcat.ClaimSerialization.Sample/ClaimSerializableClass.cs b/src/Antelcat.ClaimSerialization.Sample/ClaimSerializableClass.cs index 385437f..daa963b 100644 --- a/src/Antelcat.ClaimSerialization.Sample/ClaimSerializableClass.cs +++ b/src/Antelcat.ClaimSerialization.Sample/ClaimSerializableClass.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.Security.Claims; -using Antelcat.Attributes; +using Antelcat.ClaimSerialization.Attributes; namespace Antelcat.ClaimSerialization.Sample; diff --git a/src/Antelcat.ClaimSerialization.Shared/Attributes/ClaimConverterAttribute.cs b/src/Antelcat.ClaimSerialization.Shared/Attributes/ClaimConverterAttribute.cs index 11f222c..4546244 100644 --- a/src/Antelcat.ClaimSerialization.Shared/Attributes/ClaimConverterAttribute.cs +++ b/src/Antelcat.ClaimSerialization.Shared/Attributes/ClaimConverterAttribute.cs @@ -1,4 +1,4 @@ -namespace Antelcat.Attributes; +namespace Antelcat.ClaimSerialization.Attributes; [AttributeUsage(AttributeTargets.Property)] public class ClaimConverterAttribute(Type converterType) : Attribute; diff --git a/src/Antelcat.ClaimSerialization.Shared/Attributes/ClaimIgnoreAttribute.cs b/src/Antelcat.ClaimSerialization.Shared/Attributes/ClaimIgnoreAttribute.cs index 8d38310..9587f23 100644 --- a/src/Antelcat.ClaimSerialization.Shared/Attributes/ClaimIgnoreAttribute.cs +++ b/src/Antelcat.ClaimSerialization.Shared/Attributes/ClaimIgnoreAttribute.cs @@ -1,4 +1,4 @@ -namespace Antelcat.Attributes; +namespace Antelcat.ClaimSerialization.Attributes; /// /// Properties marked this attribute will not be mapped into claims diff --git a/src/Antelcat.ClaimSerialization.Shared/Attributes/ClaimSerializableAttribute.cs b/src/Antelcat.ClaimSerialization.Shared/Attributes/ClaimSerializableAttribute.cs index 29d28d4..fb6d4cd 100644 --- a/src/Antelcat.ClaimSerialization.Shared/Attributes/ClaimSerializableAttribute.cs +++ b/src/Antelcat.ClaimSerialization.Shared/Attributes/ClaimSerializableAttribute.cs @@ -1,4 +1,4 @@ -namespace Antelcat.Attributes; +namespace Antelcat.ClaimSerialization.Attributes; /// /// Types marked this attribute will auto generate implement methods of diff --git a/src/Antelcat.ClaimSerialization.Shared/Attributes/ClaimTypeAttribute.cs b/src/Antelcat.ClaimSerialization.Shared/Attributes/ClaimTypeAttribute.cs index cab9ba1..150ac70 100644 --- a/src/Antelcat.ClaimSerialization.Shared/Attributes/ClaimTypeAttribute.cs +++ b/src/Antelcat.ClaimSerialization.Shared/Attributes/ClaimTypeAttribute.cs @@ -1,7 +1,7 @@ using System; using System.Security.Claims; -namespace Antelcat.Attributes; +namespace Antelcat.ClaimSerialization.Attributes; /// /// Replace the of the diff --git a/src/Antelcat.ClaimSerialization.Shared/Interfaces/IClaimSerializable.cs b/src/Antelcat.ClaimSerialization.Shared/Interfaces/IClaimSerializable.cs index 36bb2da..4d1be5c 100644 --- a/src/Antelcat.ClaimSerialization.Shared/Interfaces/IClaimSerializable.cs +++ b/src/Antelcat.ClaimSerialization.Shared/Interfaces/IClaimSerializable.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using System.Security.Claims; -namespace Antelcat.Interfaces; +namespace Antelcat.ClaimSerialization.Interfaces; public interface IClaimSerializable { diff --git a/src/Antelcat.ClaimSerialization.SourceGenerators/Generators/ClaimSerializeGenerator.cs b/src/Antelcat.ClaimSerialization.SourceGenerators/Generators/ClaimSerializeGenerator.cs index 773d644..8dbb9a5 100644 --- a/src/Antelcat.ClaimSerialization.SourceGenerators/Generators/ClaimSerializeGenerator.cs +++ b/src/Antelcat.ClaimSerialization.SourceGenerators/Generators/ClaimSerializeGenerator.cs @@ -1,12 +1,11 @@ using System.Collections.Generic; using System.Collections.Immutable; -using System.ComponentModel; -using System.Diagnostics; using System.Linq; using System.Reflection; using System.Security.Claims; using System.Text; -using Antelcat.Attributes; +using Antelcat.ClaimSerialization.Attributes; +using Antelcat.ClaimSerialization.Interfaces; using Feast.CodeAnalysis.Utils; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; @@ -20,14 +19,13 @@ namespace Antelcat.ClaimSerialization.SourceGenerators.Generators; [Generator] public class ClaimSerializeGenerator : IIncrementalGenerator { - private const string Attribute = "Antelcat.Attributes.ClaimSerializableAttribute"; - private const string Claim = "global::System.Security.Claims.Claim"; - private const string IClaimSerializable = $"global::Antelcat.Interfaces.{nameof(IClaimSerializable)}"; - private const string JsonSerializer = "global::System.Text.Json.JsonSerializer"; - private const string IEnumerable = "global::System.Collections.Generic.IEnumerable"; - private const string ICollection = "global::System.Collections.Generic.ICollection"; - private const string Dictionary = "global::System.Collections.Generic.Dictionary"; - private const string List = "global::System.Collections.Generic.List"; + private static readonly string Attribute = $"{typeof(ClaimSerializableAttribute).FullName}"; + private static readonly string IClaimSerializable = $"global::{typeof(IClaimSerializable).FullName}"; + private const string Claim = "global::System.Security.Claims.Claim"; + private const string JsonSerializer = "global::System.Text.Json.JsonSerializer"; + private const string IEnumerable = "global::System.Collections.Generic.IEnumerable"; + + private const string group = nameof(group); private static readonly IEnumerable ParsableTypes = typeof(object) .Assembly @@ -35,13 +33,13 @@ public class ClaimSerializeGenerator : IIncrementalGenerator .Where(x => x.GetMethods(BindingFlags.Public | BindingFlags.Static) .FirstOrDefault(m => { - if( m.Name != nameof(int.Parse))return false; + if (m.Name != nameof(int.Parse)) return false; var param = m.GetParameters(); return param.Length == 1 && param[0].ParameterType == typeof(string); }) != null) .Select(TypeInfo.FromType); - - + + private static string GetClaimValueTypes(ITypeSymbol symbol) { return symbol.SpecialType switch @@ -74,7 +72,7 @@ private static string GeneratePropToClaim( return $"yield return new {Claim}({claimType}, $\"{{{propertyName}}}\", {GetClaimValueTypes(propertyType)});"; } - + var enumerable = (RuntimeTypeInfo)typeof(IEnumerable<>); if (!TypeInfo.FromSymbol(propertyType).IsAssignableTo(enumerable)) return $"yield return new {Claim}({claimType}, {JsonSerializer}.Serialize({propertyName}));"; @@ -91,37 +89,36 @@ private static string GeneratePropToClaim( {{GeneratePropToClaim(claimType, argument, "item")}} } """; - } private static string GenerateClaimToProp( string propName, string argumentName, - ITypeSymbol propertyType,bool inner = false) + ITypeSymbol propertyType, bool inner = false) { - // String 直接使用 if (propertyType.SpecialType == SpecialType.System_String) { - return $"{(!inner ? $"{propName} = " : string.Empty )}{argumentName}"; + return $"{(!inner ? $"{propName} = " : string.Empty)}{argumentName}"; } // 可转换类型 - if (propertyType.IsJsonBool() - || propertyType.IsJsonNumber() + if (propertyType.IsJsonBool() + || propertyType.IsJsonNumber() || propertyType.IsJsonString() || propertyType.TypeKind == TypeKind.Enum || ParsableTypes.Any(x => x.SameAs(TypeInfo.FromSymbol(propertyType)))) { - return $"{(!inner ? $"{propName} = " : string.Empty )}{ - ( propertyType.TypeKind != TypeKind.Enum ? propertyType.GetFullyQualifiedName() : $"global::{typeof(Enum).FullName}" ) + return $"{(!inner ? $"{propName} = " : string.Empty)}{ + (propertyType.TypeKind != TypeKind.Enum ? propertyType.GetFullyQualifiedName() : $"global::{typeof(Enum).FullName}") }.Parse{( - propertyType.TypeKind == TypeKind.Enum ? $"<{propertyType.GetFullyQualifiedName()}>" : string.Empty ) }({argumentName})"; + propertyType.TypeKind == TypeKind.Enum ? $"<{propertyType.GetFullyQualifiedName()}>" : string.Empty)}({argumentName})"; } var enumerable = (RuntimeTypeInfo)typeof(IEnumerable<>); if (!TypeInfo.FromSymbol(propertyType).IsAssignableTo(enumerable)) - return $"{(!inner ? $"{propName} = " : string.Empty )}{JsonSerializer}.Deserialize<{propertyType.GetFullyQualifiedName()}>({argumentName})"; + return + $"{(!inner ? $"{propName} = " : string.Empty)}{JsonSerializer}.Deserialize<{propertyType.GetFullyQualifiedName()}>({argumentName})"; var comp = propertyType .Interfaces .FirstOrDefault(x => @@ -134,7 +131,8 @@ private static string GenerateClaimToProp( _ => ".ToList()" }; - return $"{(!inner ? $"{propName} = " : string.Empty )}pair.Value.Select(x=> {GenerateClaimToProp(propName, "x.Value", argument, true)}){suffix}"; + return + $"{(!inner ? $"{propName} = " : string.Empty)}{group}.Select(x=> {GenerateClaimToProp(propName, "x.Value", argument, true)}){suffix}"; } @@ -178,11 +176,11 @@ private static void GenerateCode(SourceProductionContext context, Compilation co .ToList(); var propToClaims = transform .Where(x => !x.typeSymbol.IsReadOnly) - .Select(p => p.converter == null - ? GeneratePropToClaim(p.claimType, p.typeSymbol.Type, p.propName) + .Select(p => p.converter == null + ? GeneratePropToClaim(p.claimType, p.typeSymbol.Type, p.propName) : $"yield return new {Claim}({p.claimType}, new {p.converter.GetFullyQualifiedName()}().ConvertToString({p.propName}));" ); - + var claimsToProps = transform .Where(x => { @@ -197,12 +195,13 @@ private static void GenerateCode(SourceProductionContext context, Compilation co true ), x.typeSymbol.Locations.First())); } + return !x.typeSymbol.IsWriteOnly; }) .Select(p => $"case {p.claimType} :" + (p.converter == null - ? GenerateClaimToProp(p.propName, "pair.Value.First().Value", p.typeSymbol.Type) - : $"{p.propName} = ({p.typeSymbol.Type.GetFullyQualifiedName()})new {p.converter.GetFullyQualifiedName()}().ConvertFromString(pair.Value.First().Value)") + ? GenerateClaimToProp(p.propName, $"{group}.First().Value", p.typeSymbol.Type) + : $"{p.propName} = ({p.typeSymbol.Type.GetFullyQualifiedName()})new {p.converter.GetFullyQualifiedName()}().ConvertFromString({group}.First().Value)") + "; break;"); var head = TriviaList( @@ -233,19 +232,9 @@ private static void GenerateCode(SourceProductionContext context, Compilation co $$""" public void {{nameof(Interfaces.IClaimSerializable.FromClaims)}}({{IEnumerable}}<{{Claim}}> claims) { - foreach (var pair in claims.Aggregate(new {{Dictionary}}>(), (d, c) => - { - if (!d.TryGetValue(c.Type, out var value)) - { - value = new {{List}}<{{Claim}}>(); - d[c.Type] = value; - } - - value.Add(c); - return d; - })) + foreach (var {{group}} in claims.GroupBy(x => x.Type)) { - switch (pair.Key) + switch ({{group}}.Key) { {{string.Join("\n", claimsToProps).Replace("\n", "\n\t\t\t\t")}} } @@ -260,19 +249,19 @@ private static void GenerateCode(SourceProductionContext context, Compilation co } } - private static bool FilterAttribute(IPropertySymbol symbol,SourceProductionContext context) + private static bool FilterAttribute(IPropertySymbol symbol, SourceProductionContext context) { var attrs = symbol.GetAttributes(); - + if (!attrs.Any(a => TypeInfo .FromSymbol(a.AttributeClass!) .SameAs(typeof(ClaimIgnoreAttribute)))) return true; foreach (var info in attrs.Select(attr => - TypeInfo.FromSymbol(attr.AttributeClass!)) - .Where(info => - info.SameAs(typeof(ClaimTypeAttribute)) + TypeInfo.FromSymbol(attr.AttributeClass!)) + .Where(info => + info.SameAs(typeof(ClaimTypeAttribute)) || info.SameAs(typeof(ClaimConverterAttribute)))) { context.ReportDiagnostic(Diagnostic.Create(new DiagnosticDescriptor( @@ -285,7 +274,7 @@ private static bool FilterAttribute(IPropertySymbol symbol,SourceProductionConte ), symbol.Locations.First(), info.Name, nameof(ClaimIgnoreAttribute))); return false; } - + return false; } @@ -302,7 +291,7 @@ private static (string claimType, IPropertySymbol typeSymbol, string propName, I } INamedTypeSymbol? converter = null; - var convertAttr = attrs.FirstOrDefault(x=> + var convertAttr = attrs.FirstOrDefault(x => x.AttributeClass.GetFullyQualifiedName() == $"global::{typeof(ClaimConverterAttribute).FullName}"); if (convertAttr is { ConstructorArguments.Length: 1 }) { @@ -316,7 +305,7 @@ private static (string claimType, IPropertySymbol typeSymbol, string propName, I nameof(ClaimSerializableAttribute), DiagnosticSeverity.Error, true - ), symbol.Locations.First(),converter.Name)); + ), symbol.Locations.First(), converter.Name)); converter = null; } } diff --git a/src/Antelcat.ClaimSerialization.Tests/ClaimSerializationGeneratorTests.cs b/src/Antelcat.ClaimSerialization.Tests/ClaimSerializationGeneratorTests.cs index 1c6c0a3..99de593 100644 --- a/src/Antelcat.ClaimSerialization.Tests/ClaimSerializationGeneratorTests.cs +++ b/src/Antelcat.ClaimSerialization.Tests/ClaimSerializationGeneratorTests.cs @@ -1,10 +1,7 @@ using System; -using System.ComponentModel; -using System.Diagnostics; using System.IO; using System.Linq; -using System.Text.Json; -using Antelcat.Attributes; +using Antelcat.ClaimSerialization.Attributes; using Antelcat.ClaimSerialization.SourceGenerators.Generators; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; diff --git a/src/Antelcat.ClaimSerialization.sln b/src/Antelcat.ClaimSerialization.sln index a4e3557..97b43ac 100644 --- a/src/Antelcat.ClaimSerialization.sln +++ b/src/Antelcat.ClaimSerialization.sln @@ -15,8 +15,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Feast.CodeAnalysis.SourceGe EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Antelcat.ClaimSerialization.Shared", "Antelcat.ClaimSerialization.Shared\Antelcat.ClaimSerialization.Shared.shproj", "{A5E305BF-C775-48F9-8A19-8B4D84F90983}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Antelcat.ClaimSerialization.Abstractions", "Antelcat.ClaimSerialization.Abstractions\Antelcat.ClaimSerialization.Abstractions.csproj", "{1B45914A-8727-462D-A8CF-D60EC3659579}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Antelcat.ClaimSerialization", "Antelcat.ClaimSerialization\Antelcat.ClaimSerialization.csproj", "{3A766E62-AC05-4F91-ADE7-8356C750EF52}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__", "__", "{E2C896D1-7BBD-417A-8574-2F684E0CC15A}" @@ -47,10 +45,6 @@ Global {7184E740-24E8-4DB5-8484-A81B55DF4BB7}.Debug|Any CPU.Build.0 = Debug|Any CPU {7184E740-24E8-4DB5-8484-A81B55DF4BB7}.Release|Any CPU.ActiveCfg = Release|Any CPU {7184E740-24E8-4DB5-8484-A81B55DF4BB7}.Release|Any CPU.Build.0 = Release|Any CPU - {1B45914A-8727-462D-A8CF-D60EC3659579}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1B45914A-8727-462D-A8CF-D60EC3659579}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1B45914A-8727-462D-A8CF-D60EC3659579}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1B45914A-8727-462D-A8CF-D60EC3659579}.Release|Any CPU.Build.0 = Release|Any CPU {3A766E62-AC05-4F91-ADE7-8356C750EF52}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3A766E62-AC05-4F91-ADE7-8356C750EF52}.Debug|Any CPU.Build.0 = Debug|Any CPU {3A766E62-AC05-4F91-ADE7-8356C750EF52}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/src/Antelcat.ClaimSerialization/Antelcat.ClaimSerialization.csproj b/src/Antelcat.ClaimSerialization/Antelcat.ClaimSerialization.csproj index 89ff5c7..ad12f63 100644 --- a/src/Antelcat.ClaimSerialization/Antelcat.ClaimSerialization.csproj +++ b/src/Antelcat.ClaimSerialization/Antelcat.ClaimSerialization.csproj @@ -7,16 +7,16 @@ true preview - 1.0.0 - 1.0.0 - 1.0.0 + 1.1.1 + 1.1.1 + 1.1.1 Antelcat Antelcat.ClaimSerialization Antelcat.ClaimSerialization Antelcat.ClaimSerialization true - Initial release + Merge abstraction into one package and refactor namespace Copyright Antelcat. All rights reserved claim;serialization;auto;generate; Auto generate serialization implements to/from Claim @@ -30,10 +30,6 @@ README.md - - - - @@ -43,5 +39,6 @@ +