From 12ac998c270768ffe2b1d541f70120cbed884abd Mon Sep 17 00:00:00 2001 From: Akeit0 <90429982+Akeit0@users.noreply.github.com> Date: Sun, 3 Mar 2024 01:01:51 +0900 Subject: [PATCH] Add : Support AlchemySerialization to generics and inheritance --- .../AlchemySerializeGenerator.cs | 147 ++++++++++++++---- .../Editor/Internal/InspectorHelper.cs | 12 +- .../Generator/Alchemy.SourceGenerator.dll | Bin 17408 -> 18944 bytes .../Assets/Tests/InheritedSerializeTest.cs | 11 ++ .../Tests/InheritedSerializeTest.cs.meta | 11 ++ .../Tests/InheritedSerializeTestBase.cs | 13 ++ .../Tests/InheritedSerializeTestBase.cs.meta | 3 + 7 files changed, 162 insertions(+), 35 deletions(-) create mode 100644 Alchemy/Assets/Tests/InheritedSerializeTest.cs create mode 100644 Alchemy/Assets/Tests/InheritedSerializeTest.cs.meta create mode 100644 Alchemy/Assets/Tests/InheritedSerializeTestBase.cs create mode 100644 Alchemy/Assets/Tests/InheritedSerializeTestBase.cs.meta diff --git a/Alchemy.SourceGenerator/AlchemySerializeGenerator.cs b/Alchemy.SourceGenerator/AlchemySerializeGenerator.cs index 98d9e7f..11a5cc4 100644 --- a/Alchemy.SourceGenerator/AlchemySerializeGenerator.cs +++ b/Alchemy.SourceGenerator/AlchemySerializeGenerator.cs @@ -31,20 +31,21 @@ namespace Alchemy.SourceGenerator if (!IsPartial(typeSyntax)) { - context.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.MustBePartial, typeSyntax.Identifier.GetLocation(), typeSymbol.Name)); + context.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.MustBePartial, + typeSyntax.Identifier.GetLocation(), typeSymbol.Name)); continue; } if (IsNested(typeSyntax)) { - context.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.NestedNotAllow, typeSyntax.Identifier.GetLocation(), typeSymbol.Name)); + context.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.NestedNotAllow, + typeSyntax.Identifier.GetLocation(), typeSymbol.Name)); continue; } var fieldSymbols = new List(); var fields = typeSyntax.Members - .Where(x => x is FieldDeclarationSyntax) - .Select(x => (FieldDeclarationSyntax)x); + .OfType(); foreach (var field in fields) { var model = context.Compilation.GetSemanticModel(field.SyntaxTree); @@ -54,22 +55,24 @@ namespace Alchemy.SourceGenerator var alchemySerializeAttribute = fieldSymbol.GetAttributes() .FirstOrDefault(x => x.AttributeClass.Name is "AlchemySerializeField" - or "AlchemySerializeFieldAttribute" - or "Alchemy.Serialization.AlchemySerializeField" - or "Alchemy.Serialization.AlchemySerializeFieldAttribute"); + or "AlchemySerializeFieldAttribute" + or "Alchemy.Serialization.AlchemySerializeField" + or "Alchemy.Serialization.AlchemySerializeFieldAttribute"); var nonSerializedAttribute = fieldSymbol.GetAttributes() .FirstOrDefault(x => x.AttributeClass.Name is "NonSerialized" - or "NonSerializedAttribute" - or "System.NonSerialized" - or "System.NonSerializedAttribute"); + or "NonSerializedAttribute" + or "System.NonSerialized" + or "System.NonSerializedAttribute"); if (alchemySerializeAttribute != null) { if (nonSerializedAttribute == null) { - context.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.ShouldBeNonSerialized, variable.Identifier.GetLocation(), fieldSymbol.Name)); + context.ReportDiagnostic(Diagnostic.Create( + DiagnosticDescriptors.ShouldBeNonSerialized, variable.Identifier.GetLocation(), + fieldSymbol.Name)); } fieldSymbols.Add(fieldSymbol); @@ -88,16 +91,76 @@ namespace Alchemy.SourceGenerator } catch (Exception ex) { - var diagnosticDescriptor = new DiagnosticDescriptor("AlchemySerializeGeneratorError", "AlchemySerializeGeneratorError", $"Generation failed with:\n {ex}", "AlchemySerializeGeneratorError", DiagnosticSeverity.Error, true); - context.ReportDiagnostic(Diagnostic.Create(diagnosticDescriptor, Location.None, DiagnosticSeverity.Error)); + var diagnosticDescriptor = new DiagnosticDescriptor("AlchemySerializeGeneratorError", + "AlchemySerializeGeneratorError", $"Generation failed with:\n {ex}", + "AlchemySerializeGeneratorError", DiagnosticSeverity.Error, true); + context.ReportDiagnostic(Diagnostic.Create(diagnosticDescriptor, Location.None, + DiagnosticSeverity.Error)); } } + static string ReplaceGenericsToCount( string typeName,int count) + { + if(count == 0) return typeName; + var builder = new StringBuilder(); + bool skip = false; + foreach (var c in typeName) + { + if (c == '<') + { + skip = true; + builder.Append(count); + } + else if (c == '>') + { + skip = false; + } + else if (!skip) + { + builder.Append(c); + } + } + return builder.ToString(); + } static string ProcessClass(INamedTypeSymbol typeSymbol, List fieldSymbols) { var onAfterDeserializeCodeBuilder = new StringBuilder(); var onBeforeSerializeCodeBuilder = new StringBuilder(); var serializationDataCodeBuilder = new StringBuilder(); + bool hasInheritedImplementation = false; + var baseType = typeSymbol.BaseType; + while (baseType != null) + { + if (baseType.GetAttributes().Any(x => x.AttributeClass!.Name + is "AlchemySerialize" + or "AlchemySerializeAttribute" + or "Alchemy.Serialization.AlchemySerialize" + or "Alchemy.Serialization.AlchemySerializeAttribute")) + { + hasInheritedImplementation = true; + break; + } + + baseType = baseType.BaseType; + } + + var genericsCount = 0; + if (typeSymbol.IsGenericType) + { + genericsCount = typeSymbol.TypeParameters.Length; + + } + var typeGenerics = typeSymbol.IsGenericType + ? "<" + string.Join(", ", typeSymbol.TypeParameters.Select(x => x.Name)) + ">" + : ""; + + var alchemySerializationDataName = typeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + .Replace("global::", ""); + alchemySerializationDataName = ReplaceGenericsToCount(alchemySerializationDataName,genericsCount) + "_alchemySerializationData"; + + var inheritedSerializationCallback = hasInheritedImplementation + ? "base.SerializationCallback_AlchemyImpl(isBeforeSerialize);" + : string.Empty; var hasShowSerializationData = typeSymbol.GetAttributes().Any(x => x.AttributeClass.Name is "ShowAlchemySerializationData" @@ -105,18 +168,22 @@ namespace Alchemy.SourceGenerator or "Alchemy.Serialization.ShowAlchemySerializationData" or "Alchemy.Serialization.ShowAlchemySerializationDataAttribute"); - var serializationDataAttibutesCode = hasShowSerializationData ? "[global::Alchemy.Inspector.ReadOnly, global::UnityEngine.TextArea(3, 999), global::UnityEngine.SerializeField]" : "[global::UnityEngine.HideInInspector, global::UnityEngine.SerializeField]"; + var serializationDataAttributesCode = hasShowSerializationData + ? "[global::Alchemy.Inspector.ReadOnly, global::UnityEngine.TextArea(3, 999), global::UnityEngine.SerializeField]" + : "[global::UnityEngine.HideInInspector, global::UnityEngine.SerializeField]"; // target class namespace - var ns = typeSymbol.ContainingNamespace.IsGlobalNamespace ? string.Empty : $"namespace {typeSymbol.ContainingNamespace} {{"; + var ns = typeSymbol.ContainingNamespace.IsGlobalNamespace + ? string.Empty + : $"namespace {typeSymbol.ContainingNamespace} {{"; foreach (var field in fieldSymbols) { var serializeCode = -@$"try + @$"try {{ - alchemySerializationData.{field.Name}.data = global::Alchemy.Serialization.Internal.SerializationHelper.ToJson(this.{field.Name} , alchemySerializationData.UnityObjectReferences); - alchemySerializationData.{field.Name}.isCreated = true; + {alchemySerializationDataName}.{field.Name}.data = global::Alchemy.Serialization.Internal.SerializationHelper.ToJson(this.{field.Name} , {alchemySerializationDataName}.UnityObjectReferences); + {alchemySerializationDataName}.{field.Name}.isCreated = true; }} catch (global::System.Exception ex) {{ @@ -124,11 +191,11 @@ catch (global::System.Exception ex) }}"; var deserializeCode = -@$"try + @$"try {{ - if (alchemySerializationData.{field.Name}.isCreated) + if ({alchemySerializationDataName}.{field.Name}.isCreated) {{ - this.{field.Name} = global::Alchemy.Serialization.Internal.SerializationHelper.FromJson<{field.Type.ToDisplayString()}>(alchemySerializationData.{field.Name}.data, alchemySerializationData.UnityObjectReferences); + this.{field.Name} = global::Alchemy.Serialization.Internal.SerializationHelper.FromJson<{field.Type.ToDisplayString()}>({alchemySerializationDataName}.{field.Name}.data, {alchemySerializationDataName}.UnityObjectReferences); }} }} catch (global::System.Exception ex) @@ -143,23 +210,37 @@ catch (global::System.Exception ex) } return -@$" + @$" // {ns} - partial class {typeSymbol.Name} : global::UnityEngine.ISerializationCallbackReceiver + partial class {typeSymbol.Name}{typeGenerics} : global::UnityEngine.ISerializationCallbackReceiver {{ void global::UnityEngine.ISerializationCallbackReceiver.OnAfterDeserialize() {{ - {onAfterDeserializeCodeBuilder} + SerializationCallback_AlchemyImpl(false); if (this is global::Alchemy.Serialization.IAlchemySerializationCallbackReceiver receiver) receiver.OnAfterDeserialize(); }} void global::UnityEngine.ISerializationCallbackReceiver.OnBeforeSerialize() {{ if (this is global::Alchemy.Serialization.IAlchemySerializationCallbackReceiver receiver) receiver.OnBeforeSerialize(); - alchemySerializationData.UnityObjectReferences.Clear(); - {onBeforeSerializeCodeBuilder} + SerializationCallback_AlchemyImpl(true); + }} + + protected {(hasInheritedImplementation ? "new" : "")} void SerializationCallback_AlchemyImpl(bool isBeforeSerialize = false) + {{ + {inheritedSerializationCallback} + if (isBeforeSerialize) + {{ + {alchemySerializationDataName}.UnityObjectReferences.Clear(); + {onBeforeSerializeCodeBuilder} + + }} + else + {{ + {onAfterDeserializeCodeBuilder} + }} }} [global::System.Serializable] @@ -178,7 +259,7 @@ catch (global::System.Exception ex) }} }} - {serializationDataAttibutesCode} private AlchemySerializationData alchemySerializationData = new(); + {serializationDataAttributesCode} private AlchemySerializationData {alchemySerializationDataName} = new(); }} {(string.IsNullOrEmpty(ns) ? "" : "}")} @@ -209,12 +290,12 @@ catch (global::System.Exception ex) if (syntaxNode is TypeDeclarationSyntax typeDeclarationSyntax) { var hasAttribute = typeDeclarationSyntax.AttributeLists - .SelectMany(x => x.Attributes) - .Any(x => x.Name.ToString() - is "AlchemySerialize" - or "AlchemySerializeAttribute" - or "Alchemy.Serialization.AlchemySerialize" - or "Alchemy.Serialization.AlchemySerializeAttribute"); + .SelectMany(x => x.Attributes) + .Any(x => x.Name.ToString() + is "AlchemySerialize" + or "AlchemySerializeAttribute" + or "Alchemy.Serialization.AlchemySerialize" + or "Alchemy.Serialization.AlchemySerializeAttribute"); if (hasAttribute) { TargetTypes.Add(typeDeclarationSyntax); diff --git a/Alchemy/Assets/Alchemy/Editor/Internal/InspectorHelper.cs b/Alchemy/Assets/Alchemy/Editor/Internal/InspectorHelper.cs index 372f926..600a684 100644 --- a/Alchemy/Assets/Alchemy/Editor/Internal/InspectorHelper.cs +++ b/Alchemy/Assets/Alchemy/Editor/Internal/InspectorHelper.cs @@ -235,13 +235,21 @@ namespace Alchemy.Editor #if ALCHEMY_SUPPORT_SERIALIZATION if (serializedObject.targetObject != null && - serializedObject.targetObject.GetType().HasCustomAttribute() && + memberInfo.DeclaringType.HasCustomAttribute() && memberInfo.HasCustomAttribute()) { var element = default(VisualElement); if (memberInfo is FieldInfo fieldInfo) { - SerializedProperty GetProperty() => findPropertyFunc?.Invoke("alchemySerializationData").FindPropertyRelative(memberInfo.Name); + var declaredType = fieldInfo.DeclaringType; + if (declaredType.IsConstructedGenericType) + { + declaredType = declaredType.GetGenericTypeDefinition(); + } + var dataName = declaredType.FullName.Replace("`","").Replace(".", "_") + "_alchemySerializationData"; + + SerializedProperty GetProperty() => findPropertyFunc?.Invoke(dataName) + .FindPropertyRelative(memberInfo.Name); var p = GetProperty(); if (p != null) diff --git a/Alchemy/Assets/Alchemy/Generator/Alchemy.SourceGenerator.dll b/Alchemy/Assets/Alchemy/Generator/Alchemy.SourceGenerator.dll index e7145a8f73ebaa1d43fdc2ed2bd27be10ede6875..8436b83ba3984d61e878dc008d8879b89ff60eea 100644 GIT binary patch literal 18944 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 delta 6066 zcma)A3v^WFo&SH|y>su(BpEW3_mfFN!jShH5=bBdLcmlYWD!uqBpDzOGB}gCrkKp+ z)CXAX5t?V?op0()e5I>58Fca_kA-N9@U<` zaR1-`{rdj*yLS?PoP~F@eY;ou+mfA!DSCZK`R+JYNwfeABf|W{Myzh!n{X2)Dx4GP zioCYc569jvckGAu?NYLd=&#yXUQ&FRC?52_4Mb~29xoN^*=+k4^TBfCULYP}1-4DV zq`ziyjLo!#fgu3hBF?e=j9<(6xR&GQWT8(yM9)?cG2vW3SFGYjx)r$w6Nu~{2S73O zvMOyo^ONDp9p>#E1tnTPGCibUvXW)fwZNQnnQ zO8oiKvuz%Sfz#$Mkd!@|pVRJ7Ch@SAkTVNxf1#8mxDq@?5{aMpa}?-`_skYAXvrZo z!#iyZ4O3H7sHZ~Wm#$7tor`zcN=uK5?q)iUo>q~o%9S|nxUJc>k6Z@>?`1BGc$!;g;J4-}>ceyTVb zF-~US4o&K0#W>l4E0W{6MY=L)+NOQIr%S!i_0Ebdl6AeaZHgnEErxlrnt%g^*@3?( zeoib%ZlK191+kh=)4v4zMTXNFL9Bru6BDx(%&3jR10$hnb`h$*72-xKW)d@DxtfYi z!%Tp8Ht-nKa-zHL)X@Sy-2np$n+FOrt*F_C)G)KlV1o8vaH;moQ9a;U4jyKM7#=WA zLo{_C!(l)adX4*AA=|qMvJphQ{$Yfv5nKUjVOUB$I7CW{o4Nlsum&My$yc@FT<&R$ zI#0qucCYk`EASb@2ec%Bb_tFG+&Iu-jF`SAa8XLlWPmLae1#s)06p-&6ke3zv6QG< z`VG%VSU&K@nZY=*+MZSc8>gmnv>T;f!~YFgBPz}s0f^LyX9!1Ps;u#LvEQB>N|Pv_ z1C)zHQ1{^YD=CfV9vno5;a?+*T)~6wScfs;dbI9xd6*kvdBDbcQLGJOKqKwZ1|*8! zCslIwT0ovo&A%3I)E?T6z`|6V4;>+J%4QpZ?TV5_rV%(4BNB`NOOtw#l%;WR5fnt^oM5hLJqB1XWenejJ?R%`Be-9(;$ zK>EeyK^&V#SnfcqXVo2=e;tH-ajs|mO}p-Z#J?T@?FvnMmq|>-2qbYjMj(lTOqqoE zO?*|;lX%+|j364e^encspnV|F+rK3!2lYe5djKbBK}S3Fl*&&A;LAE%@c`2R=vvW~ zFuM?szxu?$U=Zen!v~ES^em>tpedfG z8}x>@!D7%x1=AI*Q}8(jKj9lJcKW7v2_9_L%etLB#wEi}eO3v-4QSBssEsWnI3Wks z*39025X6(Z6q6+pW-g1wUx6wHUn%(^wbNU4$?!*wyA^*vlbU@N8Eg}R8T3QT zCOAEzJRIk{VO7W_-@z{H4!R#!2EC{}e`Y$b2gzWSo4D3{{;6fNUDAl~z;-D%O zCQtFlRTBLOX{Y}{Dh93Kk3;9L%266LUGx!oxr=6-kE6u@v2>aSb#R&7m!{Nj(=Vfo z`)rc)l1=(~MfwcUDdl<@S|kHY_%BR`|2+lh0B`q(JT47g*?Tf#TN}yy~9X@EQheKlbkKSYevSi}lg*Tz71-fvh~pXfcW^v>J-iCrYf?@P_#v=|Y}9Tr zasnEJ!>Jv!I0rD1suXNcutmXE1y?J$UO_LQK^aWK)qp8@J1;V`Xq4Wx+>K#tvTg@n zZ1Dr<#vlf+%K9MXvHAQFTF?6Qebmb)^l`d}9kCpw;~~nm9L6k<@aJg{dy)Sb##`BI zl&!*yQ^5Q!l>$$parO-VoNA+ZqBVmpK!7D|i3%{m8ZB$tA@);a1G^3UZEUUL%V6JR zqwFK&A$F&-JbUHbPdd1vB`0ap;X(P_k z3F-!XTEW*9bTi4xCynprf8;vGlIWz-64Ei-q)`uz&`Ek9hp2-sU~R0M1=&6}kN5EJ z^Mm{Y?$Y$IoaO7UL?iN2o94N-x0QkhkJHy2ypkk-Bkx{3M|k1j#ut9%s@A;n1&R9Q z?_iFDQ>TSwWs9knt)nCC9=gDWuRyM4jn;y!OM z*xc3GshG_Tot-sO+8SKt4Gi>p`$S(#sW_aHBR)>qTvOFqO$(OZ=j$FE@JSm<-#Xae zy$Nh-TGd%|le}hfTWSsyyVIJ)TWLA^x~;yz5OJ>Z$-hYLSQBD*-Q!dWdWF$!EgXB|+!{W<=)`S}ZiORe= z;=Wnsg?1XokGV)H?wgY7rOgQLxfZ?<0Tz~1F9k7n0eJV)0ALS}uWRY-5`Ug`)R^0R zyt&)$M^ zr+d1Kc8T)hhs8$EEHUay6{pIwwQ4y3qWEL+-*bvYXGJQrL*tN?PF^gwGI6mulik#G zv9#Q!Olx3zcSV|JN5H45SBjGrcTT&t)T%VTD9)M;RXUU#aj5D%yn`i6WB2-x{*5~DlS8Eo<=-X>oNL_6>5)2-~o)lImKCN9AODwsp2{ra(1O5@c zzPWv}fwD98G9_Z#un5U z9dxd@sT|HQ*N`>hZipu%E*J1q#xP)E8@9@=^++L%y}1& zn8!LYomaHoW4ej$xz^M1XivlAiP1)ltKPW66EnZAT}mOBS!K`0p@_|BR=Y6~>G_0i zatFs2yH?}4M#WY@=UvWGo9g2ZY|Dh1;#8|FVKhMuFWPa39UC6q)VLVx^4X&J5RYQ0 zQ8QfW&S{-k!Z8QP1AE|XQm{oVXvu2XBPUc1ZDhK}u*fYp-OS~~3RSMQ4v8kXBlCeY zQD8)ILhNgKeZ}Uk9$!^$O?`c>x2vvZbN%M}+U`p4+^)@D-@Klx+OB!t?uMRfFaAIm z{pp6cR)5Q(e<#+qiUZ$^`y>28_@f2lsasNwog48Nl_v4hE%^=KdEig$o_guMW#iwg z_(R|9P4x_#6&*pmDk_EsgM-_B6&?M(14Hgr-tO(*ExuqyOJDa^-;SXQk+?W5yTaeK ztzwO@&*u&LD*Al`!2xf7k2la$U0$ga#D>N3)zJ|9Gom4oSo^WgQ|G_&?9n&Zyz#=W zUm%<5>x{(RV|l6k*Biz2i{}_qg*Z?WMHR~xjwSQirpXmc^0nJHQx^_yAHGg&@#RsE zf3-NmyYSqY~V?;BUt2qj|8A7G1!+kT!s>239M6zU)@ps>t6MKb=46 LT>eKkR%!kp2%mza diff --git a/Alchemy/Assets/Tests/InheritedSerializeTest.cs b/Alchemy/Assets/Tests/InheritedSerializeTest.cs new file mode 100644 index 0000000..864437b --- /dev/null +++ b/Alchemy/Assets/Tests/InheritedSerializeTest.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using Alchemy.Serialization; +using UnityEngine; + + +[AlchemySerialize] +public partial class InheritedSerializeTest : InheritedSerializeTestBase +{ + [AlchemySerializeField, NonSerialized] int? nullableInt; +} \ No newline at end of file diff --git a/Alchemy/Assets/Tests/InheritedSerializeTest.cs.meta b/Alchemy/Assets/Tests/InheritedSerializeTest.cs.meta new file mode 100644 index 0000000..e2f03de --- /dev/null +++ b/Alchemy/Assets/Tests/InheritedSerializeTest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 54b828d414a20a74b92a3ec43f78f187 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Alchemy/Assets/Tests/InheritedSerializeTestBase.cs b/Alchemy/Assets/Tests/InheritedSerializeTestBase.cs new file mode 100644 index 0000000..4459c8e --- /dev/null +++ b/Alchemy/Assets/Tests/InheritedSerializeTestBase.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using Alchemy.Serialization; +using UnityEngine; + + +[AlchemySerialize] +public partial class InheritedSerializeTestBase : MonoBehaviour +{ + [AlchemySerializeField, NonSerialized] HashSet set; + +} + diff --git a/Alchemy/Assets/Tests/InheritedSerializeTestBase.cs.meta b/Alchemy/Assets/Tests/InheritedSerializeTestBase.cs.meta new file mode 100644 index 0000000..7427156 --- /dev/null +++ b/Alchemy/Assets/Tests/InheritedSerializeTestBase.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 74b376952c9a4c42a10525c553c6e044 +timeCreated: 1709000968 \ No newline at end of file