< Summary

Line coverage
0%
Covered lines: 0
Uncovered lines: 50
Coverable lines: 50
Total lines: 107
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 20
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor()100%110%
CanConvert(...)0%220%
CreateConverter(...)0%10100%
CreateFSharpUnionConverter(...)0%880%

File(s)

https://raw.githubusercontent.com/dotnet/runtime/811a7eabb75c42db53440e8ba3f60c07511cfd1f/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/FSharp/FSharpTypeConverterFactory.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System.Diagnostics;
 5using System.Diagnostics.CodeAnalysis;
 6using System.Reflection;
 7using System.Text.Json.Serialization.Metadata;
 8using FSharpKind = System.Text.Json.Serialization.Metadata.FSharpCoreReflectionProxy.FSharpKind;
 9
 10namespace System.Text.Json.Serialization.Converters
 11{
 12    [RequiresDynamicCode(FSharpCoreReflectionProxy.FSharpCoreUnreferencedCodeMessage)]
 13    internal sealed class FSharpTypeConverterFactory : JsonConverterFactory
 14    {
 15        [RequiresUnreferencedCode(FSharpCoreReflectionProxy.FSharpCoreUnreferencedCodeMessage)]
 016        public FSharpTypeConverterFactory() { }
 17
 18        private ObjectConverterFactory? _recordConverterFactory;
 19
 20        [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode",
 21            Justification = "The ctor is marked RequiresUnreferencedCode.")]
 22        public override bool CanConvert(Type typeToConvert) =>
 023            FSharpCoreReflectionProxy.IsFSharpType(typeToConvert) &&
 024                FSharpCoreReflectionProxy.Instance.DetectFSharpKind(typeToConvert) is not FSharpKind.Unrecognized;
 25
 26        [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode",
 27            Justification = "The ctor is marked RequiresUnreferencedCode.")]
 28        [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2055:MakeGenericType",
 29            Justification = "The ctor is marked RequiresUnreferencedCode.")]
 30        public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
 031        {
 032            Debug.Assert(CanConvert(typeToConvert));
 33
 34            Type elementType;
 35            Type converterFactoryType;
 036            object?[]? constructorArguments = null;
 37
 038            switch (FSharpCoreReflectionProxy.Instance.DetectFSharpKind(typeToConvert))
 39            {
 40                case FSharpKind.Option:
 041                    elementType = typeToConvert.GetGenericArguments()[0];
 042                    converterFactoryType = typeof(FSharpOptionConverter<,>).MakeGenericType(typeToConvert, elementType);
 043                    constructorArguments = new object[] { options.GetConverterInternal(elementType) };
 044                    break;
 45                case FSharpKind.ValueOption:
 046                    elementType = typeToConvert.GetGenericArguments()[0];
 047                    converterFactoryType = typeof(FSharpValueOptionConverter<,>).MakeGenericType(typeToConvert, elementT
 048                    constructorArguments = new object[] { options.GetConverterInternal(elementType) };
 049                    break;
 50                case FSharpKind.List:
 051                    elementType = typeToConvert.GetGenericArguments()[0];
 052                    converterFactoryType = typeof(FSharpListConverter<,>).MakeGenericType(typeToConvert, elementType);
 053                    break;
 54                case FSharpKind.Set:
 055                    elementType = typeToConvert.GetGenericArguments()[0];
 056                    converterFactoryType = typeof(FSharpSetConverter<,>).MakeGenericType(typeToConvert, elementType);
 057                    break;
 58                case FSharpKind.Map:
 059                    Type[] genericArgs = typeToConvert.GetGenericArguments();
 060                    Type keyType = genericArgs[0];
 061                    Type valueType = genericArgs[1];
 062                    converterFactoryType = typeof(FSharpMapConverter<,,>).MakeGenericType(typeToConvert, keyType, valueT
 063                    break;
 64                case FSharpKind.Record:
 65                    // Use a modified object converter factory that picks the right constructor for struct record deseri
 066                    ObjectConverterFactory objectFactory = _recordConverterFactory ??= new ObjectConverterFactory(useDef
 067                    Debug.Assert(objectFactory.CanConvert(typeToConvert));
 068                    return objectFactory.CreateConverter(typeToConvert, options);
 69                case FSharpKind.Union:
 070                    return CreateFSharpUnionConverter(typeToConvert, options);
 71                default:
 072                    Debug.Fail("Unrecognized F# type.");
 73                    throw new Exception();
 74            }
 75
 076            return (JsonConverter)Activator.CreateInstance(converterFactoryType, constructorArguments)!;
 077        }
 78
 79        [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode",
 80            Justification = "The ctor is marked RequiresUnreferencedCode.")]
 81        private static JsonConverter CreateFSharpUnionConverter(Type typeToConvert, JsonSerializerOptions options)
 082        {
 083            FSharpCoreReflectionProxy proxy = FSharpCoreReflectionProxy.Instance;
 084            FSharpCoreReflectionProxy.FSharpUnionCaseInfo[] caseInfos = proxy.GetUnionCaseInfos(typeToConvert);
 085            Func<object, int> tagReader = proxy.CreateUnionTagReader(typeToConvert);
 86
 87            // Read [JsonPolymorphic] for TypeDiscriminatorPropertyName customization.
 088            string typeDiscriminatorPropertyName = typeToConvert
 089                .GetCustomAttribute<JsonPolymorphicAttribute>(inherit: false)?.TypeDiscriminatorPropertyName
 090                ?? JsonSerializer.TypePropertyName;
 91
 92            // Validate the discriminator property name doesn't conflict with reserved metadata properties ($id, $ref, $
 093            if (!typeDiscriminatorPropertyName.Equals(JsonSerializer.TypePropertyName, StringComparison.Ordinal))
 094            {
 095                byte[] utf8EncodedName = System.Text.Encoding.UTF8.GetBytes(typeDiscriminatorPropertyName);
 096                if ((JsonSerializer.GetMetadataPropertyName(utf8EncodedName, resolver: null) & ~MetadataPropertyName.Typ
 097                {
 098                    ThrowHelper.ThrowInvalidOperationException_InvalidCustomTypeDiscriminatorPropertyName();
 99                }
 0100            }
 101
 0102            Type converterType = typeof(FSharpUnionConverter<>).MakeGenericType(typeToConvert);
 0103            return (JsonConverter)Activator.CreateInstance(converterType, new object[] { caseInfos, tagReader, options, 
 0104        }
 105    }
 106}
 107