void CollectArray(IArrayTypeSymbol array) { var elemType = array.ElementType; CollectCore(elemType); var info = new GenericSerializationInfo { FullName = array.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat), }; if (array.IsSZArray) { info.FormatterName = $"global::Utf8Json.Formatters.ArrayFormatter<{elemType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}>"; } else if (array.Rank == 2) { info.FormatterName = $"global::Utf8Json.Formatters.TwoDimentionalArrayFormatter<{elemType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}>"; } else if (array.Rank == 3) { info.FormatterName = $"global::Utf8Json.Formatters.ThreeDimentionalArrayFormatter<{elemType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}>"; } else if (array.Rank == 4) { info.FormatterName = $"global::Utf8Json.Formatters.FourDimentionalArrayFormatter<{elemType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}>"; } else { throw new InvalidOperationException("does not supports array dimention, " + info.FullName); } collectedGenericInfo.Add(info); return; }
void CollectGeneric(INamedTypeSymbol type) { var genericType = type.ConstructUnboundGenericType(); var genericTypeString = genericType.ToDisplayString(); var fullName = type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); // special case if (fullName == "global::System.ArraySegment<byte>" || fullName == "global::System.ArraySegment<byte>?") { return; } // nullable if (genericTypeString == "T?") { CollectCore(type.TypeArguments[0]); if (!embeddedTypes.Contains(type.TypeArguments[0].ToString())) { var info = new GenericSerializationInfo { FormatterName = $"global::Utf8Json.Formatters.NullableFormatter<{type.TypeArguments[0].ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}>", FullName = type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat), }; collectedGenericInfo.Add(info); } return; } // collection if (knownGenericTypes.TryGetValue(genericTypeString, out var formatter)) { foreach (var item in type.TypeArguments) { CollectCore(item); } var typeArgs = string.Join(", ", type.TypeArguments.Select(x => x.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat))); var f = formatter.Replace("TREPLACE", typeArgs); var info = new GenericSerializationInfo { FormatterName = f, FullName = type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat), }; collectedGenericInfo.Add(info); if (genericTypeString == "System.Linq.ILookup<,>") { formatter = knownGenericTypes["System.Linq.IGrouping<,>"]; f = formatter.Replace("TREPLACE", typeArgs); var groupingInfo = new GenericSerializationInfo { FormatterName = f, FullName = $"global::System.Linq.IGrouping<{typeArgs}>", }; collectedGenericInfo.Add(groupingInfo); formatter = knownGenericTypes["System.Collections.Generic.IEnumerable<>"]; typeArgs = type.TypeArguments[1].ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); f = formatter.Replace("TREPLACE", typeArgs); var enumerableInfo = new GenericSerializationInfo { FormatterName = f, FullName = $"global::System.Collections.Generic.IEnumerable<{typeArgs}>", }; collectedGenericInfo.Add(enumerableInfo); } } }