Skip to content

Commit 1b8d324

Browse files
committed
Add support for serializing Dictionary<TKey,TValue[]> and List<T[]>
1 parent 75f4010 commit 1b8d324

File tree

4 files changed

+76
-8
lines changed

4 files changed

+76
-8
lines changed

YamlDotNet.Analyzers.StaticGenerator/ClassSyntaxReceiver.cs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -94,30 +94,40 @@ private void AddSerializableClass(INamedTypeSymbol? classSymbol)
9494

9595
if (member is IPropertySymbol propertySymbol)
9696
{
97-
classObject.PropertySymbols.Add(propertySymbol);
98-
CheckForSupportedGeneric(propertySymbol.Type);
97+
if (!classObject.PropertySymbols.ContainsName(propertySymbol))
98+
{
99+
classObject.PropertySymbols.Add(propertySymbol);
100+
CheckForSupportedGeneric(propertySymbol.Type);
101+
}
99102
}
100103
else if (member is IFieldSymbol fieldSymbol)
101104
{
102-
classObject.FieldSymbols.Add(fieldSymbol);
103-
CheckForSupportedGeneric(fieldSymbol.Type);
105+
if (!classObject.FieldSymbols.ContainsName(fieldSymbol))
106+
{
107+
classObject.FieldSymbols.Add(fieldSymbol);
108+
CheckForSupportedGeneric(fieldSymbol.Type);
109+
}
104110
}
105111
else if (member is IMethodSymbol methodSymbol)
106112
{
107113
var methodAttributes = methodSymbol.GetAttributes();
108-
if (methodAttributes.Any(x => x.AttributeClass!.ToDisplayString() == "YamlDotNet.Serialization.Callbacks.OnDeserializedAttribute"))
114+
if (methodAttributes.Any(x => x.AttributeClass!.ToDisplayString() == "YamlDotNet.Serialization.Callbacks.OnDeserializedAttribute")
115+
&& !classObject.OnDeserializedMethods.ContainsName(methodSymbol))
109116
{
110117
classObject.OnDeserializedMethods.Add(methodSymbol);
111118
}
112-
if (methodAttributes.Any(x => x.AttributeClass!.ToDisplayString() == "YamlDotNet.Serialization.Callbacks.OnDeserializingAttribute"))
119+
if (methodAttributes.Any(x => x.AttributeClass!.ToDisplayString() == "YamlDotNet.Serialization.Callbacks.OnDeserializingAttribute")
120+
&& !classObject.OnDeserializingMethods.ContainsName(methodSymbol))
113121
{
114122
classObject.OnDeserializingMethods.Add(methodSymbol);
115123
}
116-
if (methodAttributes.Any(x => x.AttributeClass!.ToDisplayString() == "YamlDotNet.Serialization.Callbacks.OnSerializedAttribute"))
124+
if (methodAttributes.Any(x => x.AttributeClass!.ToDisplayString() == "YamlDotNet.Serialization.Callbacks.OnSerializedAttribute")
125+
&& !classObject.OnSerializedMethods.ContainsName(methodSymbol))
117126
{
118127
classObject.OnSerializedMethods.Add(methodSymbol);
119128
}
120-
if (methodAttributes.Any(x => x.AttributeClass!.ToDisplayString() == "YamlDotNet.Serialization.Callbacks.OnSerializingAttribute"))
129+
if (methodAttributes.Any(x => x.AttributeClass!.ToDisplayString() == "YamlDotNet.Serialization.Callbacks.OnSerializingAttribute")
130+
&& !classObject.OnSerializingMethods.ContainsName(methodSymbol))
121131
{
122132
classObject.OnSerializingMethods.Add(methodSymbol);
123133
}
@@ -146,10 +156,12 @@ private void CheckForSupportedGeneric(ITypeSymbol type)
146156
else if (typeName.StartsWith("System.Collections.Generic.Dictionary"))
147157
{
148158
Classes.Add(sanitizedTypeName, new ClassObject(sanitizedTypeName, (INamedTypeSymbol)type, true));
159+
CheckForSupportedGeneric(((INamedTypeSymbol)type).TypeArguments[1]);
149160
}
150161
else if (typeName.StartsWith("System.Collections.Generic.List"))
151162
{
152163
Classes.Add(sanitizedTypeName, new ClassObject(sanitizedTypeName, (INamedTypeSymbol)type, isList: true));
164+
CheckForSupportedGeneric(((INamedTypeSymbol)type).TypeArguments[0]);
153165
}
154166
}
155167
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// This file is part of YamlDotNet - A .NET library for YAML.
2+
// Copyright (c) Antoine Aubry and contributors
3+
//
4+
// Permission is hereby granted, free of charge, to any person obtaining a copy of
5+
// this software and associated documentation files (the "Software"), to deal in
6+
// the Software without restriction, including without limitation the rights to
7+
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8+
// of the Software, and to permit persons to whom the Software is furnished to do
9+
// so, subject to the following conditions:
10+
//
11+
// The above copyright notice and this permission notice shall be included in all
12+
// copies or substantial portions of the Software.
13+
//
14+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
// SOFTWARE.
21+
22+
using System.Collections.Generic;
23+
using System.Linq;
24+
using Microsoft.CodeAnalysis;
25+
26+
namespace YamlDotNet.Analyzers.StaticGenerator
27+
{
28+
static class SymbolCollectionExtensions
29+
{
30+
public static bool ContainsName<T>(this IEnumerable<T> enumerable, T symbol)
31+
where T : ISymbol
32+
{
33+
return enumerable.Any(t => t.Name == symbol.Name);
34+
}
35+
}
36+
}

YamlDotNet.Analyzers.StaticGenerator/SymbolExtensions.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ static string GetGenericTypes(IReadOnlyList<ITypeSymbol> typeArguments)
121121
case ITypeParameterSymbol typeParameterSymbol:
122122
output.Add(typeParameterSymbol.Name + typeParameterSymbol.GetNullable());
123123
break;
124+
case IArrayTypeSymbol arrayTypeSymbol:
125+
output.Add(GetFullName(arrayTypeSymbol.ElementType) + "[]");
126+
break;
124127
default:
125128
throw new NotSupportedException($"Cannot generate type name from type argument {argument.GetType().FullName}");
126129
}

YamlDotNet.Core7AoTCompileTest/Program.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,13 @@
6161
MyDictionary:
6262
x: y
6363
a: b
64+
MyDictionaryOfArrays:
65+
a:
66+
- a
67+
- b
68+
b:
69+
- c
70+
- d
6471
MyList:
6572
- a
6673
- b
@@ -117,6 +124,15 @@
117124
}
118125
}
119126

127+
Console.WriteLine("MyDictionaryOfArrays == null: <{0}>", x.MyDictionaryOfArrays == null);
128+
if (x.MyDictionaryOfArrays != null)
129+
{
130+
foreach (var kvp in x.MyDictionaryOfArrays)
131+
{
132+
Console.WriteLine("MyDictionaryOfArrays[{0}] = <{1}>", kvp.Key, string.Join(',', kvp.Value));
133+
}
134+
}
135+
120136
Console.WriteLine("MyList == null: <{0}>", x.MyList == null);
121137
if (x.MyList != null)
122138
{
@@ -191,6 +207,7 @@ public class PrimitiveTypes
191207
public Inner[]? InnerArray { get; set; }
192208
public MyArray? MyArray { get; set; }
193209
public Dictionary<string, string>? MyDictionary { get; set; }
210+
public Dictionary<string, string[]>? MyDictionaryOfArrays { get; set; }
194211
public List<string>? MyList { get; set; }
195212
public Inherited Inherited { get; set; }
196213
public ExternalModel External { get; set; }

0 commit comments

Comments
 (0)