< Summary

Information
Line coverage
66%
Covered lines: 36
Uncovered lines: 18
Coverable lines: 54
Total lines: 106
Line coverage: 66.6%
Branch coverage
50%
Covered branches: 10
Total branches: 20
Branch coverage: 50%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor(...)100%11100%
CanConvert(...)100%11100%
CreateConverter(...)50%202060.86%

File(s)

C:\h\w\B31A098C\w\BB5A0A33\e\runtime-utils\Runner\runtime\src\libraries\System.Text.Json\src\System\Text\Json\Serialization\Converters\Object\ObjectConverterFactory.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.Collections;
 5using System.Collections.Generic;
 6using System.Diagnostics;
 7using System.Diagnostics.CodeAnalysis;
 8using System.Reflection;
 9using System.Text.Json.Reflection;
 10using System.Text.Json.Serialization.Metadata;
 11
 12namespace System.Text.Json.Serialization.Converters
 13{
 14    /// <summary>
 15    /// Converter factory for all object-based types (non-enumerable and non-primitive).
 16    /// </summary>
 17    [RequiresDynamicCode(JsonSerializer.SerializationRequiresDynamicCodeMessage)]
 18    internal sealed class ObjectConverterFactory : JsonConverterFactory
 19    {
 20        // Need to toggle this behavior when generating converters for F# struct records.
 21        private readonly bool _useDefaultConstructorInUnannotatedStructs;
 22
 23        [RequiresUnreferencedCode(JsonSerializer.SerializationUnreferencedCodeMessage)]
 124        public ObjectConverterFactory(bool useDefaultConstructorInUnannotatedStructs = true)
 125        {
 126            _useDefaultConstructorInUnannotatedStructs = useDefaultConstructorInUnannotatedStructs;
 127        }
 28
 29        public override bool CanConvert(Type typeToConvert)
 259830        {
 31            // This is the last built-in factory converter, so if the IEnumerableConverterFactory doesn't
 32            // support it, then it is not IEnumerable.
 259833            Debug.Assert(!typeof(IEnumerable).IsAssignableFrom(typeToConvert));
 259834            return true;
 259835        }
 36
 37        [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode",
 38            Justification = "The ctor is marked RequiresUnreferencedCode.")]
 39        [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2067:UnrecognizedReflectionPattern",
 40            Justification = "The ctor is marked RequiresUnreferencedCode.")]
 41        public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
 129942        {
 43            JsonConverter converter;
 44            Type converterType;
 45
 129946            bool useDefaultConstructorInUnannotatedStructs = _useDefaultConstructorInUnannotatedStructs && !typeToConver
 129947            if (!typeToConvert.TryGetDeserializationConstructor(useDefaultConstructorInUnannotatedStructs, out Construct
 048            {
 049                ThrowHelper.ThrowInvalidOperationException_SerializationDuplicateTypeAttribute<JsonConstructorAttribute>
 50            }
 51
 129952            ParameterInfo[]? parameters = constructor?.GetParameters();
 53
 129954            if (constructor == null || typeToConvert.IsAbstract || parameters!.Length == 0)
 55055            {
 55056                converterType = typeof(ObjectDefaultConverter<>).MakeGenericType(typeToConvert);
 55057            }
 58            else
 74959            {
 74960                int parameterCount = parameters.Length;
 61
 1123562                foreach (ParameterInfo parameter in parameters)
 449463                {
 64                    // Every argument must be of supported type.
 449465                    JsonTypeInfo.ValidateType(parameter.ParameterType);
 449466                }
 67
 74968                if (parameterCount <= JsonConstants.UnboxedParameterCountThreshold)
 069                {
 070                    Type placeHolderType = JsonTypeInfo.ObjectType;
 071                    Type[] typeArguments = new Type[JsonConstants.UnboxedParameterCountThreshold + 1];
 72
 073                    typeArguments[0] = typeToConvert;
 074                    for (int i = 0; i < JsonConstants.UnboxedParameterCountThreshold; i++)
 075                    {
 076                        if (i < parameterCount)
 077                        {
 078                            typeArguments[i + 1] = parameters[i].ParameterType;
 079                        }
 80                        else
 081                        {
 82                            // Use placeholder arguments if there are less args than the threshold.
 083                            typeArguments[i + 1] = placeHolderType;
 084                        }
 085                    }
 86
 087                    converterType = typeof(SmallObjectWithParameterizedConstructorConverter<,,,,>).MakeGenericType(typeA
 088                }
 89                else
 74990                {
 74991                    converterType = typeof(LargeObjectWithParameterizedConstructorConverterWithReflection<>).MakeGeneric
 74992                }
 74993            }
 94
 129995            converter = (JsonConverter)Activator.CreateInstance(
 129996                    converterType,
 129997                    BindingFlags.Instance | BindingFlags.Public,
 129998                    binder: null,
 129999                    args: null,
 1299100                    culture: null)!;
 101
 1299102            converter.ConstructorInfo = constructor!;
 1299103            return converter;
 1299104        }
 105    }
 106}