< Summary

Line coverage
0%
Covered lines: 0
Uncovered lines: 44
Coverable lines: 44
Total lines: 171
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 16
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
EndCollectionElement()100%110%
EndDictionaryEntry()100%110%
EndProperty()100%110%
GetNestedJsonTypeInfo()0%220%
InitializePolymorphicReEntry(...)0%660%
InitializePolymorphicReEntry(...)0%220%
ResumePolymorphicReEntry()100%110%
ExitPolymorphicConverter(...)0%220%

File(s)

https://raw.githubusercontent.com/dotnet/runtime/811a7eabb75c42db53440e8ba3f60c07511cfd1f/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/WriteStackFrame.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.Diagnostics;
 6using System.Runtime.InteropServices;
 7using System.Text.Json.Serialization;
 8using System.Text.Json.Serialization.Metadata;
 9
 10namespace System.Text.Json
 11{
 12    [StructLayout(LayoutKind.Auto)]
 13    [DebuggerDisplay("{DebuggerDisplay,nq}")]
 14    internal struct WriteStackFrame
 15    {
 16        /// <summary>
 17        /// The enumerator for resumable collections.
 18        /// </summary>
 19        public IEnumerator? CollectionEnumerator;
 20
 21        /// <summary>
 22        /// The async enumerator for resumable async enumerable collections.
 23        /// </summary>
 24        public object? AsyncEnumerator;
 25
 26        /// <summary>
 27        /// The state of the async enumerator for the current stack frame.
 28        /// </summary>
 29        public AsyncEnumeratorState AsyncEnumeratorState;
 30
 31        /// <summary>
 32        /// The original JsonPropertyInfo that is not changed. It contains all properties.
 33        /// </summary>
 34        /// <remarks>
 35        /// For objects, it is either the actual (real) JsonPropertyInfo or the <see cref="JsonTypeInfo.PropertyInfoForT
 36        /// For collections, it is the <see cref="JsonTypeInfo.PropertyInfoForTypeInfo"/> for the class and current elem
 37        /// </remarks>
 38        public JsonPropertyInfo? JsonPropertyInfo;
 39
 40        /// <summary>
 41        /// Used when processing extension data dictionaries.
 42        /// </summary>
 43        public bool IsWritingExtensionDataProperty;
 44
 45        /// <summary>
 46        /// The class (POCO or IEnumerable) that is being populated.
 47        /// </summary>
 48        public JsonTypeInfo JsonTypeInfo;
 49
 50        /// <summary>
 51        /// Validation state for a class.
 52        /// </summary>
 53        public int OriginalDepth;
 54
 55        // Class-level state for collections.
 56        public bool ProcessedStartToken;
 57        public bool ProcessedEndToken;
 58
 59        /// <summary>
 60        /// Property or Element state.
 61        /// </summary>
 62        public StackFramePropertyState PropertyState;
 63
 64        /// <summary>
 65        /// The enumerator index for resumable collections.
 66        /// </summary>
 67        public int EnumeratorIndex;
 68
 69        // This is used for re-entry cases for exception handling.
 70        public string? JsonPropertyNameAsString;
 71
 72        // Preserve Reference
 73        public MetadataPropertyName MetadataPropertyName;
 74
 75        // Serialization state for the child value serialized by the current frame.
 76        public PolymorphicSerializationState PolymorphicSerializationState;
 77        // Holds the entered polymorphic type info and acts as an LRU cache for element/field serializations.
 78        public JsonTypeInfo? PolymorphicTypeInfo;
 79
 80        // Whether to use custom number handling.
 81        public JsonNumberHandling? NumberHandling;
 82
 83        public bool IsPushedReferenceForCycleDetection;
 84
 85        public void EndCollectionElement()
 086        {
 087            PolymorphicSerializationState = PolymorphicSerializationState.None;
 088        }
 89
 90        public void EndDictionaryEntry()
 091        {
 092            PropertyState = StackFramePropertyState.None;
 093            PolymorphicSerializationState = PolymorphicSerializationState.None;
 094        }
 95
 96        public void EndProperty()
 097        {
 098            JsonPropertyInfo = null!;
 099            JsonPropertyNameAsString = null;
 0100            PropertyState = StackFramePropertyState.None;
 0101            PolymorphicSerializationState = PolymorphicSerializationState.None;
 0102        }
 103
 104        /// <summary>
 105        /// Returns the JsonTypeInfo instance for the nested value we are trying to access.
 106        /// </summary>
 107        public readonly JsonTypeInfo GetNestedJsonTypeInfo()
 0108        {
 0109            return PolymorphicSerializationState is PolymorphicSerializationState.PolymorphicReEntryStarted
 0110                ? PolymorphicTypeInfo!
 0111                : JsonPropertyInfo!.JsonTypeInfo;
 0112        }
 113
 114        /// <summary>
 115        /// Configures the next stack frame for a polymorphic converter.
 116        /// </summary>
 117        public JsonTypeInfo InitializePolymorphicReEntry(Type runtimeType, JsonSerializerOptions options)
 0118        {
 0119            Debug.Assert(PolymorphicSerializationState == PolymorphicSerializationState.None);
 120
 121            // For perf, avoid the dictionary lookup in GetTypeInfoInternal() for every element of a collection
 122            // if the current element is the same type as the previous element.
 0123            if (PolymorphicTypeInfo?.Type != runtimeType)
 0124            {
 125                // To determine the contract for an object value:
 126                // 1. Find the JsonTypeInfo for the runtime type with fallback to the nearest ancestor, if not available
 127                // 2. If the resolved type is deriving from a polymorphic type, use the contract of the polymorphic type
 0128                JsonTypeInfo typeInfo = options.GetTypeInfoInternal(runtimeType, fallBackToNearestAncestorType: true);
 0129                PolymorphicTypeInfo = typeInfo.AncestorPolymorphicType ?? typeInfo;
 0130            }
 131
 0132            PolymorphicSerializationState = PolymorphicSerializationState.PolymorphicReEntryStarted;
 0133            return PolymorphicTypeInfo;
 0134        }
 135
 136        /// <summary>
 137        /// Configures the next stack frame for a polymorphic converter.
 138        /// </summary>
 139        public JsonConverter InitializePolymorphicReEntry(JsonTypeInfo derivedJsonTypeInfo)
 0140        {
 0141            Debug.Assert(PolymorphicSerializationState is PolymorphicSerializationState.None or PolymorphicSerialization
 142
 0143            PolymorphicTypeInfo = derivedJsonTypeInfo;
 0144            PolymorphicSerializationState = PolymorphicSerializationState.PolymorphicReEntryStarted;
 0145            return derivedJsonTypeInfo.Converter;
 0146        }
 147
 148        /// <summary>
 149        /// Configures the next frame for a continuation of a polymorphic converter.
 150        /// </summary>
 151        public JsonConverter ResumePolymorphicReEntry()
 0152        {
 0153            Debug.Assert(PolymorphicSerializationState == PolymorphicSerializationState.PolymorphicReEntrySuspended);
 0154            Debug.Assert(PolymorphicTypeInfo is not null);
 0155            PolymorphicSerializationState = PolymorphicSerializationState.PolymorphicReEntryStarted;
 0156            return PolymorphicTypeInfo.Converter;
 0157        }
 158
 159        /// <summary>
 160        /// Updates frame state after a polymorphic converter has returned.
 161        /// </summary>
 162        public void ExitPolymorphicConverter(bool success)
 0163        {
 0164            PolymorphicSerializationState = success ? PolymorphicSerializationState.None : PolymorphicSerializationState
 0165        }
 166
 167        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
 0168        private readonly string DebuggerDisplay => $"ConverterStrategy.{JsonTypeInfo?.Converter.ConverterStrategy}, {Jso
 169    }
 170}
 171