< Summary

Information
Line coverage
0%
Covered lines: 0
Uncovered lines: 66
Coverable lines: 66
Total lines: 144
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 61
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(...)0%440%
GetValue()0%440%
TryGetValue(...)0%440%
.cctor()100%110%
DetermineValueKind(...)0%660%
DetermineValueKindForType(...)0%43430%

File(s)

C:\h\w\B31A098C\w\BB5A0A33\e\runtime-utils\Runner\runtime\src\libraries\System.Text.Json\src\System\Text\Json\Nodes\JsonValueOfT.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;
 6
 7namespace System.Text.Json.Nodes
 8{
 9    [DebuggerDisplay("{ToJsonString(),nq}")]
 10    [DebuggerTypeProxy(typeof(JsonValue<>.DebugView))]
 11    internal abstract class JsonValue<TValue> : JsonValue
 12    {
 13        internal readonly TValue Value; // keep as a field for direct access to avoid copies
 14
 015        protected JsonValue(TValue value, JsonNodeOptions? options) : base(options)
 016        {
 017            Debug.Assert(value != null);
 018            Debug.Assert(value is not JsonElement or JsonElement { ValueKind: not JsonValueKind.Null });
 019            Debug.Assert(value is not JsonNode);
 020            Value = value;
 021        }
 22
 23        public override T GetValue<T>()
 024        {
 25            // If no conversion is needed, just return the raw value.
 026            if (Value is T returnValue)
 027            {
 028                return returnValue;
 29            }
 30
 31            // Currently we do not support other conversions.
 32            // Generics (and also boxing) do not support standard cast operators say from 'long' to 'int',
 33            //  so attempting to cast here would throw InvalidCastException.
 034            ThrowHelper.ThrowInvalidOperationException_NodeUnableToConvert(typeof(TValue), typeof(T));
 35            return default!;
 036        }
 37
 38        public override bool TryGetValue<T>([NotNullWhen(true)] out T value)
 039        {
 40            // If no conversion is needed, just return the raw value.
 041            if (Value is T returnValue)
 042            {
 043                value = returnValue;
 044                return true;
 45            }
 46
 47            // Currently we do not support other conversions.
 48            // Generics (and also boxing) do not support standard cast operators say from 'long' to 'int',
 49            //  so attempting to cast here would throw InvalidCastException.
 050            value = default!;
 051            return false;
 052        }
 53
 54        /// <summary>
 55        /// Whether <typeparamref name="TValue"/> is a built-in type that admits primitive JsonValue representation.
 56        /// </summary>
 057        internal static bool TypeIsSupportedPrimitive => s_valueKind.HasValue;
 058        private static readonly JsonValueKind? s_valueKind = DetermineValueKindForType(typeof(TValue));
 59
 60        /// <summary>
 61        /// Determines the JsonValueKind for the value of a built-in type.
 62        /// </summary>
 63        private protected static JsonValueKind DetermineValueKind(TValue value)
 064        {
 065            Debug.Assert(s_valueKind is not null, "Should only be invoked for types that are supported primitives.");
 66
 067            if (value is bool boolean)
 068            {
 69                // Boolean requires special handling since kind varies by value.
 070                return boolean ? JsonValueKind.True : JsonValueKind.False;
 71            }
 72
 073            return s_valueKind.Value;
 074        }
 75
 76        /// <summary>
 77        /// Precomputes the JsonValueKind for a given built-in type where possible.
 78        /// </summary>
 79        private static JsonValueKind? DetermineValueKindForType(Type type)
 080        {
 081            if (type.IsEnum)
 082            {
 083                return null; // Can vary depending on converter configuration and value.
 84            }
 85
 086            if (Nullable.GetUnderlyingType(type) is Type underlyingType)
 087            {
 88                // Because JsonNode excludes null values, we can identify with the value kind of the underlying type.
 089                return DetermineValueKindForType(underlyingType);
 90            }
 91
 092            if (type == typeof(DateTime) || type == typeof(DateTimeOffset) || type == typeof(TimeSpan) ||
 093#if NET
 094                type == typeof(DateOnly) || type == typeof(TimeOnly) ||
 095#endif
 096                type == typeof(Guid) || type == typeof(Uri) || type == typeof(Version))
 097            {
 098                return JsonValueKind.String;
 99            }
 100
 101#if NET
 0102            if (type == typeof(Half) || type == typeof(UInt128) || type == typeof(Int128))
 0103            {
 0104                return JsonValueKind.Number;
 105            }
 106#endif
 0107            return Type.GetTypeCode(type) switch
 0108            {
 0109                TypeCode.Boolean => JsonValueKind.Undefined, // Can vary dependending on value.
 0110                TypeCode.SByte => JsonValueKind.Number,
 0111                TypeCode.Byte => JsonValueKind.Number,
 0112                TypeCode.Int16 => JsonValueKind.Number,
 0113                TypeCode.UInt16 => JsonValueKind.Number,
 0114                TypeCode.Int32 => JsonValueKind.Number,
 0115                TypeCode.UInt32 => JsonValueKind.Number,
 0116                TypeCode.Int64 => JsonValueKind.Number,
 0117                TypeCode.UInt64 => JsonValueKind.Number,
 0118                TypeCode.Single => JsonValueKind.Number,
 0119                TypeCode.Double => JsonValueKind.Number,
 0120                TypeCode.Decimal => JsonValueKind.Number,
 0121                TypeCode.String => JsonValueKind.String,
 0122                TypeCode.Char => JsonValueKind.String,
 0123                _ => null,
 0124            };
 0125        }
 126
 127        [ExcludeFromCodeCoverage] // Justification = "Design-time"
 128        [DebuggerDisplay("{Json,nq}")]
 129        private sealed class DebugView
 130        {
 131            [DebuggerBrowsable(DebuggerBrowsableState.Never)]
 132            public JsonValue<TValue> _node;
 133
 134            public DebugView(JsonValue<TValue> node)
 135            {
 136                _node = node;
 137            }
 138
 139            public string Json => _node.ToJsonString();
 140            public string Path => _node.GetPath();
 141            public TValue? Value => _node.Value;
 142        }
 143    }
 144}