diff --git a/src/libraries/System.Text.Json/ref/System.Text.Json.cs b/src/libraries/System.Text.Json/ref/System.Text.Json.cs index c960513e9ab3bc..62c5cb51a342c8 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -36,17 +36,18 @@ public JsonArray(System.Collections.Generic.IEnumerable values) { } public JsonArray(System.Collections.Generic.IEnumerable values) { } public int Count { get { throw null; } } public bool IsReadOnly { get { throw null; } } + [System.Diagnostics.CodeAnalysis.AllowNullAttribute] public System.Text.Json.JsonNode this[int idx] { get { throw null; } set { } } public override System.Text.Json.JsonValueKind ValueKind { get { throw null; } } - public void Add(System.Text.Json.JsonNode value) { } + public void Add(System.Text.Json.JsonNode? value) { } public void Clear() { } public override System.Text.Json.JsonNode Clone() { throw null; } - public bool Contains(System.Text.Json.JsonNode value) { throw null; } + public bool Contains(System.Text.Json.JsonNode? value) { throw null; } public System.Text.Json.JsonArrayEnumerator GetEnumerator() { throw null; } - public int IndexOf(System.Text.Json.JsonNode item) { throw null; } - public void Insert(int index, System.Text.Json.JsonNode item) { } - public int LastIndexOf(System.Text.Json.JsonNode item) { throw null; } - public bool Remove(System.Text.Json.JsonNode item) { throw null; } + public int IndexOf(System.Text.Json.JsonNode? item) { throw null; } + public void Insert(int index, System.Text.Json.JsonNode? item) { } + public int LastIndexOf(System.Text.Json.JsonNode? item) { throw null; } + public bool Remove(System.Text.Json.JsonNode? item) { throw null; } public int RemoveAll(System.Predicate match) { throw null; } public void RemoveAt(int index) { } void System.Collections.Generic.ICollection.CopyTo(System.Text.Json.JsonNode[] array, int arrayIndex) { } @@ -64,18 +65,21 @@ public void Dispose() { } public bool MoveNext() { throw null; } void System.Collections.IEnumerator.Reset() { } } - public sealed partial class JsonBoolean : System.Text.Json.JsonNode, System.IEquatable + public sealed partial class JsonBoolean : System.Text.Json.JsonNode, +#nullable disable // to enable use with both T and T? for reference types due to IEquatable being invariant + System.IEquatable +#nullable restore { public JsonBoolean() { } public JsonBoolean(bool value) { } public bool Value { get { throw null; } set { } } public override System.Text.Json.JsonValueKind ValueKind { get { throw null; } } public override System.Text.Json.JsonNode Clone() { throw null; } - public override bool Equals(object obj) { throw null; } - public bool Equals(System.Text.Json.JsonBoolean other) { throw null; } + public override bool Equals(object? obj) { throw null; } + public bool Equals(System.Text.Json.JsonBoolean? other) { throw null; } public override int GetHashCode() { throw null; } - public static bool operator ==(System.Text.Json.JsonBoolean left, System.Text.Json.JsonBoolean right) { throw null; } - public static bool operator !=(System.Text.Json.JsonBoolean left, System.Text.Json.JsonBoolean right) { throw null; } + public static bool operator ==(System.Text.Json.JsonBoolean? left, System.Text.Json.JsonBoolean? right) { throw null; } + public static bool operator !=(System.Text.Json.JsonBoolean? left, System.Text.Json.JsonBoolean? right) { throw null; } public override string ToString() { throw null; } } public enum JsonCommentHandling : byte @@ -96,7 +100,7 @@ public void Dispose() { } public static System.Text.Json.JsonDocument Parse(string json, System.Text.Json.JsonDocumentOptions options = default(System.Text.Json.JsonDocumentOptions)) { throw null; } public static System.Threading.Tasks.Task ParseAsync(System.IO.Stream utf8Json, System.Text.Json.JsonDocumentOptions options = default(System.Text.Json.JsonDocumentOptions), System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static System.Text.Json.JsonDocument ParseValue(ref System.Text.Json.Utf8JsonReader reader) { throw null; } - public static bool TryParseValue(ref System.Text.Json.Utf8JsonReader reader, out System.Text.Json.JsonDocument document) { throw null; } + public static bool TryParseValue(ref System.Text.Json.Utf8JsonReader reader, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Text.Json.JsonDocument? document) { throw null; } public void WriteTo(System.Text.Json.Utf8JsonWriter writer) { } } public partial struct JsonDocumentOptions @@ -144,7 +148,7 @@ public readonly partial struct JsonElement public ulong GetUInt64() { throw null; } public override string ToString() { throw null; } public bool TryGetByte(out byte value) { throw null; } - public bool TryGetBytesFromBase64(out byte[] value) { throw null; } + public bool TryGetBytesFromBase64([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out byte[]? value) { throw null; } public bool TryGetDateTime(out System.DateTime value) { throw null; } public bool TryGetDateTimeOffset(out System.DateTimeOffset value) { throw null; } public bool TryGetDecimal(out decimal value) { throw null; } @@ -167,7 +171,7 @@ public readonly partial struct JsonElement public bool TryGetUInt64(out ulong value) { throw null; } public bool ValueEquals(System.ReadOnlySpan utf8Text) { throw null; } public bool ValueEquals(System.ReadOnlySpan text) { throw null; } - public bool ValueEquals(string text) { throw null; } + public bool ValueEquals(string? text) { throw null; } public void WriteTo(System.Text.Json.Utf8JsonWriter writer) { } public partial struct ArrayEnumerator : System.Collections.Generic.IEnumerable, System.Collections.Generic.IEnumerator, System.Collections.IEnumerable, System.Collections.IEnumerator, System.IDisposable { @@ -201,10 +205,10 @@ public void Reset() { } private readonly object _dummy; private readonly int _dummyPrimitive; public System.ReadOnlySpan EncodedUtf8Bytes { get { throw null; } } - public static System.Text.Json.JsonEncodedText Encode(System.ReadOnlySpan utf8Value, System.Text.Encodings.Web.JavaScriptEncoder encoder = null) { throw null; } - public static System.Text.Json.JsonEncodedText Encode(System.ReadOnlySpan value, System.Text.Encodings.Web.JavaScriptEncoder encoder = null) { throw null; } - public static System.Text.Json.JsonEncodedText Encode(string value, System.Text.Encodings.Web.JavaScriptEncoder encoder = null) { throw null; } - public override bool Equals(object obj) { throw null; } + public static System.Text.Json.JsonEncodedText Encode(System.ReadOnlySpan utf8Value, System.Text.Encodings.Web.JavaScriptEncoder? encoder = null) { throw null; } + public static System.Text.Json.JsonEncodedText Encode(System.ReadOnlySpan value, System.Text.Encodings.Web.JavaScriptEncoder? encoder = null) { throw null; } + public static System.Text.Json.JsonEncodedText Encode(string value, System.Text.Encodings.Web.JavaScriptEncoder? encoder = null) { throw null; } + public override bool Equals(object? obj) { throw null; } public bool Equals(System.Text.Json.JsonEncodedText other) { throw null; } public override int GetHashCode() { throw null; } public override string ToString() { throw null; } @@ -213,21 +217,22 @@ public partial class JsonException : System.Exception { public JsonException() { } protected JsonException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public JsonException(string message) { } - public JsonException(string message, System.Exception innerException) { } - public JsonException(string message, string path, long? lineNumber, long? bytePositionInLine) { } - public JsonException(string message, string path, long? lineNumber, long? bytePositionInLine, System.Exception innerException) { } + public JsonException(string? message) { } + public JsonException(string? message, System.Exception? innerException) { } + public JsonException(string? message, string? path, long? lineNumber, long? bytePositionInLine) { } + public JsonException(string? message, string? path, long? lineNumber, long? bytePositionInLine, System.Exception? innerException) { } public long? BytePositionInLine { get { throw null; } } public long? LineNumber { get { throw null; } } public override string Message { get { throw null; } } - public string Path { get { throw null; } } + public string? Path { get { throw null; } } public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } } public abstract partial class JsonNamingPolicy { protected JsonNamingPolicy() { } public static System.Text.Json.JsonNamingPolicy CamelCase { get { throw null; } } - public abstract string ConvertName(string name); + [return: System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute("name")] + public abstract string? ConvertName(string? name); } public abstract partial class JsonNode { @@ -250,7 +255,7 @@ internal JsonNode() { } [System.CLSCompliantAttribute(false)] public static implicit operator System.Text.Json.JsonNode (sbyte value) { throw null; } public static implicit operator System.Text.Json.JsonNode (float value) { throw null; } - public static implicit operator System.Text.Json.JsonNode (string value) { throw null; } + public static implicit operator System.Text.Json.JsonNode (string? value) { throw null; } [System.CLSCompliantAttribute(false)] public static implicit operator System.Text.Json.JsonNode (ushort value) { throw null; } [System.CLSCompliantAttribute(false)] @@ -259,7 +264,7 @@ internal JsonNode() { } public static implicit operator System.Text.Json.JsonNode (ulong value) { throw null; } public static System.Text.Json.JsonNode Parse(string json, System.Text.Json.JsonNodeOptions options = default(System.Text.Json.JsonNodeOptions)) { throw null; } public string ToJsonString() { throw null; } - public static bool TryGetNode(System.Text.Json.JsonElement jsonElement, out System.Text.Json.JsonNode jsonNode) { throw null; } + public static bool TryGetNode(System.Text.Json.JsonElement jsonElement, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Text.Json.JsonNode? jsonNode) { throw null; } public void WriteTo(System.Text.Json.Utf8JsonWriter writer) { } } public partial struct JsonNodeOptions @@ -270,19 +275,25 @@ public partial struct JsonNodeOptions public System.Text.Json.DuplicatePropertyNameHandlingStrategy DuplicatePropertyNameHandling { readonly get { throw null; } set { } } public int MaxDepth { readonly get { throw null; } set { } } } - public sealed partial class JsonNull : System.Text.Json.JsonNode, System.IEquatable + public sealed partial class JsonNull : System.Text.Json.JsonNode, +#nullable disable // to enable use with both T and T? for reference types due to IEquatable being invariant + System.IEquatable +#nullable restore { public JsonNull() { } public override System.Text.Json.JsonValueKind ValueKind { get { throw null; } } public override System.Text.Json.JsonNode Clone() { throw null; } - public override bool Equals(object obj) { throw null; } - public bool Equals(System.Text.Json.JsonNull other) { throw null; } + public override bool Equals(object? obj) { throw null; } + public bool Equals(System.Text.Json.JsonNull? other) { throw null; } public override int GetHashCode() { throw null; } - public static bool operator ==(System.Text.Json.JsonNull left, System.Text.Json.JsonNull right) { throw null; } - public static bool operator !=(System.Text.Json.JsonNull left, System.Text.Json.JsonNull right) { throw null; } + public static bool operator ==(System.Text.Json.JsonNull? left, System.Text.Json.JsonNull? right) { throw null; } + public static bool operator !=(System.Text.Json.JsonNull? left, System.Text.Json.JsonNull? right) { throw null; } public override string ToString() { throw null; } } - public sealed partial class JsonNumber : System.Text.Json.JsonNode, System.IEquatable + public sealed partial class JsonNumber : System.Text.Json.JsonNode, +#nullable disable // to enable use with both T and T? for reference types due to IEquatable being invariant + System.IEquatable +#nullable restore { public JsonNumber() { } public JsonNumber(byte value) { } @@ -303,8 +314,8 @@ public JsonNumber(uint value) { } public JsonNumber(ulong value) { } public override System.Text.Json.JsonValueKind ValueKind { get { throw null; } } public override System.Text.Json.JsonNode Clone() { throw null; } - public override bool Equals(object obj) { throw null; } - public bool Equals(System.Text.Json.JsonNumber other) { throw null; } + public override bool Equals(object? obj) { throw null; } + public bool Equals(System.Text.Json.JsonNumber? other) { throw null; } public byte GetByte() { throw null; } public decimal GetDecimal() { throw null; } public double GetDouble() { throw null; } @@ -321,8 +332,8 @@ public JsonNumber(ulong value) { } public uint GetUInt32() { throw null; } [System.CLSCompliantAttribute(false)] public ulong GetUInt64() { throw null; } - public static bool operator ==(System.Text.Json.JsonNumber left, System.Text.Json.JsonNumber right) { throw null; } - public static bool operator !=(System.Text.Json.JsonNumber left, System.Text.Json.JsonNumber right) { throw null; } + public static bool operator ==(System.Text.Json.JsonNumber? left, System.Text.Json.JsonNumber? right) { throw null; } + public static bool operator !=(System.Text.Json.JsonNumber? left, System.Text.Json.JsonNumber? right) { throw null; } public void SetByte(byte value) { } public void SetDecimal(decimal value) { } public void SetDouble(double value) { } @@ -359,12 +370,13 @@ public void SetUInt64(ulong value) { } public sealed partial class JsonObject : System.Text.Json.JsonNode, System.Collections.Generic.IEnumerable>, System.Collections.IEnumerable { public JsonObject() { } - public JsonObject(System.Collections.Generic.IEnumerable> jsonProperties) { } + public JsonObject(System.Collections.Generic.IEnumerable> jsonProperties) { } + [System.Diagnostics.CodeAnalysis.AllowNullAttribute] public System.Text.Json.JsonNode this[string propertyName] { get { throw null; } set { } } public override System.Text.Json.JsonValueKind ValueKind { get { throw null; } } - public void Add(System.Collections.Generic.KeyValuePair jsonProperty) { } - public void Add(string propertyName, System.Text.Json.JsonNode propertyValue) { } - public void AddRange(System.Collections.Generic.IEnumerable> jsonProperties) { } + public void Add(System.Collections.Generic.KeyValuePair jsonProperty) { } + public void Add(string propertyName, System.Text.Json.JsonNode? propertyValue) { } + public void AddRange(System.Collections.Generic.IEnumerable> jsonProperties) { } public override System.Text.Json.JsonNode Clone() { throw null; } public bool ContainsProperty(string propertyName) { throw null; } public bool ContainsProperty(string propertyName, System.StringComparison stringComparison) { throw null; } @@ -379,14 +391,14 @@ public void AddRange(System.Collections.Generic.IEnumerable GetPropertyValues() { throw null; } public bool Remove(string propertyName) { throw null; } public bool Remove(string propertyName, System.StringComparison stringComparison) { throw null; } - System.Collections.Generic.IEnumerator> System.Collections.Generic.IEnumerable>.GetEnumerator() { throw null; } + System.Collections.Generic.IEnumerator> System.Collections.Generic.IEnumerable>.GetEnumerator() { throw null; } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } - public bool TryGetJsonArrayPropertyValue(string propertyName, System.StringComparison stringComparison, out System.Text.Json.JsonArray jsonArray) { throw null; } - public bool TryGetJsonArrayPropertyValue(string propertyName, out System.Text.Json.JsonArray jsonArray) { throw null; } - public bool TryGetJsonObjectPropertyValue(string propertyName, System.StringComparison stringComparison, out System.Text.Json.JsonObject jsonObject) { throw null; } - public bool TryGetJsonObjectPropertyValue(string propertyName, out System.Text.Json.JsonObject jsonObject) { throw null; } - public bool TryGetPropertyValue(string propertyName, System.StringComparison stringComparison, out System.Text.Json.JsonNode jsonNode) { throw null; } - public bool TryGetPropertyValue(string propertyName, out System.Text.Json.JsonNode jsonNode) { throw null; } + public bool TryGetJsonArrayPropertyValue(string propertyName, System.StringComparison stringComparison, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Text.Json.JsonArray? jsonArray) { throw null; } + public bool TryGetJsonArrayPropertyValue(string propertyName, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Text.Json.JsonArray? jsonArray) { throw null; } + public bool TryGetJsonObjectPropertyValue(string propertyName, System.StringComparison stringComparison, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Text.Json.JsonObject? jsonObject) { throw null; } + public bool TryGetJsonObjectPropertyValue(string propertyName, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Text.Json.JsonObject? jsonObject) { throw null; } + public bool TryGetPropertyValue(string propertyName, System.StringComparison stringComparison, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Text.Json.JsonNode? jsonNode) { throw null; } + public bool TryGetPropertyValue(string propertyName, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Text.Json.JsonNode? jsonNode) { throw null; } } public partial struct JsonObjectEnumerator : System.Collections.Generic.IEnumerator>, System.Collections.IEnumerator, System.IDisposable { @@ -427,22 +439,22 @@ public partial struct JsonReaderState } public static partial class JsonSerializer { - public static object Deserialize(System.ReadOnlySpan utf8Json, System.Type returnType, System.Text.Json.JsonSerializerOptions options = null) { throw null; } - public static object Deserialize(string json, System.Type returnType, System.Text.Json.JsonSerializerOptions options = null) { throw null; } - public static object Deserialize(ref System.Text.Json.Utf8JsonReader reader, System.Type returnType, System.Text.Json.JsonSerializerOptions options = null) { throw null; } - public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream utf8Json, System.Type returnType, System.Text.Json.JsonSerializerOptions options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream utf8Json, System.Text.Json.JsonSerializerOptions options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public static TValue Deserialize(System.ReadOnlySpan utf8Json, System.Text.Json.JsonSerializerOptions options = null) { throw null; } - public static TValue Deserialize(string json, System.Text.Json.JsonSerializerOptions options = null) { throw null; } - public static TValue Deserialize(ref System.Text.Json.Utf8JsonReader reader, System.Text.Json.JsonSerializerOptions options = null) { throw null; } - public static string Serialize(object value, System.Type inputType, System.Text.Json.JsonSerializerOptions options = null) { throw null; } - public static void Serialize(System.Text.Json.Utf8JsonWriter writer, object value, System.Type inputType, System.Text.Json.JsonSerializerOptions options = null) { } - public static System.Threading.Tasks.Task SerializeAsync(System.IO.Stream utf8Json, object value, System.Type inputType, System.Text.Json.JsonSerializerOptions options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public static System.Threading.Tasks.Task SerializeAsync(System.IO.Stream utf8Json, TValue value, System.Text.Json.JsonSerializerOptions options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public static byte[] SerializeToUtf8Bytes(object value, System.Type inputType, System.Text.Json.JsonSerializerOptions options = null) { throw null; } - public static byte[] SerializeToUtf8Bytes(TValue value, System.Text.Json.JsonSerializerOptions options = null) { throw null; } - public static void Serialize(System.Text.Json.Utf8JsonWriter writer, TValue value, System.Text.Json.JsonSerializerOptions options = null) { } - public static string Serialize(TValue value, System.Text.Json.JsonSerializerOptions options = null) { throw null; } + public static object? Deserialize(System.ReadOnlySpan utf8Json, System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static object? Deserialize(string json, System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static object? Deserialize(ref System.Text.Json.Utf8JsonReader reader, System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream utf8Json, System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream utf8Json, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static TValue Deserialize(System.ReadOnlySpan utf8Json, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static TValue Deserialize(string json, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static TValue Deserialize(ref System.Text.Json.Utf8JsonReader reader, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static string Serialize(object? value, System.Type? inputType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static void Serialize(System.Text.Json.Utf8JsonWriter writer, object? value, System.Type? inputType, System.Text.Json.JsonSerializerOptions? options = null) { } + public static System.Threading.Tasks.Task SerializeAsync(System.IO.Stream utf8Json, object? value, System.Type? inputType, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static System.Threading.Tasks.Task SerializeAsync(System.IO.Stream utf8Json, TValue value, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static byte[] SerializeToUtf8Bytes(object? value, System.Type? inputType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static byte[] SerializeToUtf8Bytes(TValue value, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static void Serialize(System.Text.Json.Utf8JsonWriter writer, TValue value, System.Text.Json.JsonSerializerOptions? options = null) { } + public static string Serialize(TValue value, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } } public sealed partial class JsonSerializerOptions { @@ -450,18 +462,21 @@ public JsonSerializerOptions() { } public bool AllowTrailingCommas { get { throw null; } set { } } public System.Collections.Generic.IList Converters { get { throw null; } } public int DefaultBufferSize { get { throw null; } set { } } - public System.Text.Json.JsonNamingPolicy DictionaryKeyPolicy { get { throw null; } set { } } - public System.Text.Encodings.Web.JavaScriptEncoder Encoder { get { throw null; } set { } } + public System.Text.Json.JsonNamingPolicy? DictionaryKeyPolicy { get { throw null; } set { } } + public System.Text.Encodings.Web.JavaScriptEncoder? Encoder { get { throw null; } set { } } public bool IgnoreNullValues { get { throw null; } set { } } public bool IgnoreReadOnlyProperties { get { throw null; } set { } } public int MaxDepth { get { throw null; } set { } } public bool PropertyNameCaseInsensitive { get { throw null; } set { } } - public System.Text.Json.JsonNamingPolicy PropertyNamingPolicy { get { throw null; } set { } } + public System.Text.Json.JsonNamingPolicy? PropertyNamingPolicy { get { throw null; } set { } } public System.Text.Json.JsonCommentHandling ReadCommentHandling { get { throw null; } set { } } public bool WriteIndented { get { throw null; } set { } } - public System.Text.Json.Serialization.JsonConverter GetConverter(System.Type typeToConvert) { throw null; } + public System.Text.Json.Serialization.JsonConverter? GetConverter(System.Type typeToConvert) { throw null; } } - public sealed partial class JsonString : System.Text.Json.JsonNode, System.IEquatable + public sealed partial class JsonString : System.Text.Json.JsonNode, +#nullable disable // to enable use with both T and T? for reference types due to IEquatable being invariant + System.IEquatable +#nullable restore { public JsonString() { } public JsonString(System.DateTime value) { } @@ -472,14 +487,14 @@ public JsonString(string value) { } public string Value { get { throw null; } set { } } public override System.Text.Json.JsonValueKind ValueKind { get { throw null; } } public override System.Text.Json.JsonNode Clone() { throw null; } - public override bool Equals(object obj) { throw null; } - public bool Equals(System.Text.Json.JsonString other) { throw null; } + public override bool Equals(object? obj) { throw null; } + public bool Equals(System.Text.Json.JsonString? other) { throw null; } public System.DateTime GetDateTime() { throw null; } public System.DateTimeOffset GetDateTimeOffset() { throw null; } public System.Guid GetGuid() { throw null; } public override int GetHashCode() { throw null; } - public static bool operator ==(System.Text.Json.JsonString left, System.Text.Json.JsonString right) { throw null; } - public static bool operator !=(System.Text.Json.JsonString left, System.Text.Json.JsonString right) { throw null; } + public static bool operator ==(System.Text.Json.JsonString? left, System.Text.Json.JsonString? right) { throw null; } + public static bool operator !=(System.Text.Json.JsonString? left, System.Text.Json.JsonString? right) { throw null; } public override string ToString() { throw null; } public bool TryGetDateTime(out System.DateTime value) { throw null; } public bool TryGetDateTimeOffset(out System.DateTimeOffset value) { throw null; } @@ -515,7 +530,7 @@ public partial struct JsonWriterOptions { private object _dummy; private int _dummyPrimitive; - public System.Text.Encodings.Web.JavaScriptEncoder Encoder { readonly get { throw null; } set { } } + public System.Text.Encodings.Web.JavaScriptEncoder? Encoder { readonly get { throw null; } set { } } public bool Indented { get { throw null; } set { } } public bool SkipValidation { get { throw null; } set { } } } @@ -552,7 +567,7 @@ public ref partial struct Utf8JsonReader [System.CLSCompliantAttribute(false)] public sbyte GetSByte() { throw null; } public float GetSingle() { throw null; } - public string GetString() { throw null; } + public string? GetString() { throw null; } [System.CLSCompliantAttribute(false)] public ushort GetUInt16() { throw null; } [System.CLSCompliantAttribute(false)] @@ -562,7 +577,7 @@ public ref partial struct Utf8JsonReader public bool Read() { throw null; } public void Skip() { } public bool TryGetByte(out byte value) { throw null; } - public bool TryGetBytesFromBase64(out byte[] value) { throw null; } + public bool TryGetBytesFromBase64([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out byte[]? value) { throw null; } public bool TryGetDateTime(out System.DateTime value) { throw null; } public bool TryGetDateTimeOffset(out System.DateTimeOffset value) { throw null; } public bool TryGetDecimal(out decimal value) { throw null; } @@ -583,7 +598,7 @@ public void Skip() { } public bool TrySkip() { throw null; } public bool ValueTextEquals(System.ReadOnlySpan utf8Text) { throw null; } public bool ValueTextEquals(System.ReadOnlySpan text) { throw null; } - public bool ValueTextEquals(string text) { throw null; } + public bool ValueTextEquals(string? text) { throw null; } } public sealed partial class Utf8JsonWriter : System.IAsyncDisposable, System.IDisposable { @@ -684,35 +699,35 @@ public void WriteString(System.ReadOnlySpan utf8PropertyName, System.DateT public void WriteString(System.ReadOnlySpan utf8PropertyName, System.Guid value) { } public void WriteString(System.ReadOnlySpan utf8PropertyName, System.ReadOnlySpan utf8Value) { } public void WriteString(System.ReadOnlySpan utf8PropertyName, System.ReadOnlySpan value) { } - public void WriteString(System.ReadOnlySpan utf8PropertyName, string value) { } + public void WriteString(System.ReadOnlySpan utf8PropertyName, string? value) { } public void WriteString(System.ReadOnlySpan utf8PropertyName, System.Text.Json.JsonEncodedText value) { } public void WriteString(System.ReadOnlySpan propertyName, System.DateTime value) { } public void WriteString(System.ReadOnlySpan propertyName, System.DateTimeOffset value) { } public void WriteString(System.ReadOnlySpan propertyName, System.Guid value) { } public void WriteString(System.ReadOnlySpan propertyName, System.ReadOnlySpan utf8Value) { } public void WriteString(System.ReadOnlySpan propertyName, System.ReadOnlySpan value) { } - public void WriteString(System.ReadOnlySpan propertyName, string value) { } + public void WriteString(System.ReadOnlySpan propertyName, string? value) { } public void WriteString(System.ReadOnlySpan propertyName, System.Text.Json.JsonEncodedText value) { } public void WriteString(string propertyName, System.DateTime value) { } public void WriteString(string propertyName, System.DateTimeOffset value) { } public void WriteString(string propertyName, System.Guid value) { } public void WriteString(string propertyName, System.ReadOnlySpan utf8Value) { } public void WriteString(string propertyName, System.ReadOnlySpan value) { } - public void WriteString(string propertyName, string value) { } + public void WriteString(string propertyName, string? value) { } public void WriteString(string propertyName, System.Text.Json.JsonEncodedText value) { } public void WriteString(System.Text.Json.JsonEncodedText propertyName, System.DateTime value) { } public void WriteString(System.Text.Json.JsonEncodedText propertyName, System.DateTimeOffset value) { } public void WriteString(System.Text.Json.JsonEncodedText propertyName, System.Guid value) { } public void WriteString(System.Text.Json.JsonEncodedText propertyName, System.ReadOnlySpan utf8Value) { } public void WriteString(System.Text.Json.JsonEncodedText propertyName, System.ReadOnlySpan value) { } - public void WriteString(System.Text.Json.JsonEncodedText propertyName, string value) { } + public void WriteString(System.Text.Json.JsonEncodedText propertyName, string? value) { } public void WriteString(System.Text.Json.JsonEncodedText propertyName, System.Text.Json.JsonEncodedText value) { } public void WriteStringValue(System.DateTime value) { } public void WriteStringValue(System.DateTimeOffset value) { } public void WriteStringValue(System.Guid value) { } public void WriteStringValue(System.ReadOnlySpan utf8Value) { } public void WriteStringValue(System.ReadOnlySpan value) { } - public void WriteStringValue(string value) { } + public void WriteStringValue(string? value) { } public void WriteStringValue(System.Text.Json.JsonEncodedText value) { } } } @@ -732,20 +747,20 @@ public partial class JsonConverterAttribute : System.Text.Json.Serialization.Jso { protected JsonConverterAttribute() { } public JsonConverterAttribute(System.Type converterType) { } - public System.Type ConverterType { get { throw null; } } - public virtual System.Text.Json.Serialization.JsonConverter CreateConverter(System.Type typeToConvert) { throw null; } + public System.Type? ConverterType { get { throw null; } } + public virtual System.Text.Json.Serialization.JsonConverter? CreateConverter(System.Type typeToConvert) { throw null; } } public abstract partial class JsonConverterFactory : System.Text.Json.Serialization.JsonConverter { protected JsonConverterFactory() { } - public abstract System.Text.Json.Serialization.JsonConverter CreateConverter(System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options); + public abstract System.Text.Json.Serialization.JsonConverter? CreateConverter(System.Type typeToConvert, System.Text.Json.JsonSerializerOptions? options); } public abstract partial class JsonConverter : System.Text.Json.Serialization.JsonConverter { protected internal JsonConverter() { } public override bool CanConvert(System.Type typeToConvert) { throw null; } - public abstract T Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options); - public abstract void Write(System.Text.Json.Utf8JsonWriter writer, T value, System.Text.Json.JsonSerializerOptions options); + public abstract T Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions? options); + public abstract void Write(System.Text.Json.Utf8JsonWriter writer, T value, System.Text.Json.JsonSerializerOptions? options); } [System.AttributeUsageAttribute(System.AttributeTargets.Property, AllowMultiple=false)] public sealed partial class JsonExtensionDataAttribute : System.Text.Json.Serialization.JsonAttribute @@ -766,8 +781,8 @@ public JsonPropertyNameAttribute(string name) { } public sealed partial class JsonStringEnumConverter : System.Text.Json.Serialization.JsonConverterFactory { public JsonStringEnumConverter() { } - public JsonStringEnumConverter(System.Text.Json.JsonNamingPolicy namingPolicy = null, bool allowIntegerValues = true) { } + public JsonStringEnumConverter(System.Text.Json.JsonNamingPolicy? namingPolicy = null, bool allowIntegerValues = true) { } public override bool CanConvert(System.Type typeToConvert) { throw null; } - public override System.Text.Json.Serialization.JsonConverter CreateConverter(System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options) { throw null; } + public override System.Text.Json.Serialization.JsonConverter? CreateConverter(System.Type typeToConvert, System.Text.Json.JsonSerializerOptions? options) { throw null; } } } diff --git a/src/libraries/System.Text.Json/ref/System.Text.Json.csproj b/src/libraries/System.Text.Json/ref/System.Text.Json.csproj index fd1251a63fd0c6..054a55b2b3df3a 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.csproj +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.csproj @@ -1,6 +1,7 @@  net461-Debug;net461-Release;netcoreapp-Debug;netcoreapp-Release;netfx-Debug;netfx-Release;netstandard2.0-Debug;netstandard2.0-Release + enable diff --git a/src/libraries/System.Text.Json/src/System.Text.Json.csproj b/src/libraries/System.Text.Json/src/System.Text.Json.csproj index 19bd1b0e31371e..10126f849d4c81 100644 --- a/src/libraries/System.Text.Json/src/System.Text.Json.csproj +++ b/src/libraries/System.Text.Json/src/System.Text.Json.csproj @@ -10,6 +10,8 @@ + $(NoWarn);nullable + enable diff --git a/src/libraries/System.Text.Json/src/System/Collections/Generic/StackExtensions.netstandard.cs b/src/libraries/System.Text.Json/src/System/Collections/Generic/StackExtensions.netstandard.cs index f53c2ab258e649..695037bfcb3bb7 100644 --- a/src/libraries/System.Text.Json/src/System/Collections/Generic/StackExtensions.netstandard.cs +++ b/src/libraries/System.Text.Json/src/System/Collections/Generic/StackExtensions.netstandard.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; namespace System.Collections.Generic @@ -10,7 +11,7 @@ namespace System.Collections.Generic /// Polyfills for . internal static class StackExtensions { - public static bool TryPeek(this Stack stack, out T result) + public static bool TryPeek(this Stack stack, [MaybeNullWhen(false)] out T result) { if (stack.Count > 0) { @@ -18,11 +19,11 @@ public static bool TryPeek(this Stack stack, out T result) return true; } - result = default; + result = default!; return false; } - public static bool TryPop(this Stack stack, out T result) + public static bool TryPop(this Stack stack, [MaybeNullWhen(false)] out T result) { if (stack.Count > 0) { @@ -30,7 +31,7 @@ public static bool TryPop(this Stack stack, out T result) return true; } - result = default; + result = default!; return false; } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/BitStack.cs b/src/libraries/System.Text.Json/src/System/Text/Json/BitStack.cs index f27cf67905cbb6..65c04df9efbb2c 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/BitStack.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/BitStack.cs @@ -5,6 +5,7 @@ using System.Diagnostics; using System.Runtime.CompilerServices; +#nullable enable namespace System.Text.Json { internal struct BitStack @@ -15,7 +16,7 @@ internal struct BitStack private const int DefaultInitialArraySize = 2; - private int[] _array; + private int[]? _array; // This ulong container represents a tiny stack to track the state during nested transitions. // The first bit represents the state of the current depth (1 == object, 0 == array). @@ -135,6 +136,7 @@ private bool PopFromArray() private void DoubleArray(int minSize) { + Debug.Assert(_array != null); Debug.Assert(_array.Length < int.MaxValue / 2, $"Array too large - arrayLength: {_array.Length}"); Debug.Assert(minSize >= 0 && minSize >= _array.Length); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.MetadataDb.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.MetadataDb.cs index 8ee7b182bfe862..06015e0282f4b7 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.MetadataDb.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.MetadataDb.cs @@ -149,7 +149,7 @@ internal MetadataDb(MetadataDb source, bool useArrayPools) public void Dispose() { - byte[] data = Interlocked.Exchange(ref _data, null); + byte[]? data = Interlocked.Exchange(ref _data, null!); if (data == null) { return; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.Parse.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.Parse.cs index 76c221224c20aa..ce83286fe49c3f 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.Parse.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.Parse.cs @@ -4,6 +4,7 @@ using System.Buffers; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Threading; using System.Threading.Tasks; @@ -127,7 +128,7 @@ public static JsonDocument Parse(Stream utf8Json, JsonDocumentOptions options = { // Holds document content, clear it before returning it. drained.AsSpan().Clear(); - ArrayPool.Shared.Return(drained.Array); + ArrayPool.Shared.Return(drained.Array!); throw; } } @@ -176,7 +177,7 @@ private static async Task ParseAsyncCore( { // Holds document content, clear it before returning it. drained.AsSpan().Clear(); - ArrayPool.Shared.Return(drained.Array); + ArrayPool.Shared.Return(drained.Array!); throw; } } @@ -284,7 +285,7 @@ public static JsonDocument Parse(string json, JsonDocumentOptions options = defa /// /// A value could not be read from the reader. /// - public static bool TryParseValue(ref Utf8JsonReader reader, out JsonDocument document) + public static bool TryParseValue(ref Utf8JsonReader reader, [NotNullWhen(true)] out JsonDocument? document) { return TryParseValue(ref reader, out document, shouldThrow: false); } @@ -326,12 +327,12 @@ public static bool TryParseValue(ref Utf8JsonReader reader, out JsonDocument doc /// public static JsonDocument ParseValue(ref Utf8JsonReader reader) { - bool ret = TryParseValue(ref reader, out JsonDocument document, shouldThrow: true); + bool ret = TryParseValue(ref reader, out JsonDocument? document, shouldThrow: true); Debug.Assert(ret, "TryParseValue returned false with shouldThrow: true."); - return document; + return document!; } - private static bool TryParseValue(ref Utf8JsonReader reader, out JsonDocument document, bool shouldThrow) + private static bool TryParseValue(ref Utf8JsonReader reader, [NotNullWhen(true)] out JsonDocument? document, bool shouldThrow) { JsonReaderState state = reader.CurrentState; CheckSupportedOptions(state.Options, nameof(reader)); @@ -551,7 +552,7 @@ private static bool TryParseValue(ref Utf8JsonReader reader, out JsonDocument do private static JsonDocument Parse( ReadOnlyMemory utf8Json, JsonReaderOptions readerOptions, - byte[] extraRentedBytes) + byte[]? extraRentedBytes) { ReadOnlySpan utf8JsonSpan = utf8Json.Span; var database = new MetadataDb(utf8Json.Length); @@ -577,7 +578,7 @@ private static JsonDocument Parse( private static ArraySegment ReadToEnd(Stream stream) { int written = 0; - byte[] rented = null; + byte[]? rented = null; ReadOnlySpan utf8Bom = JsonConstants.Utf8Bom; @@ -659,7 +660,7 @@ private static async CancellationToken cancellationToken) { int written = 0; - byte[] rented = null; + byte[]? rented = null; try { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.StackRowStack.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.StackRowStack.cs index a01b783ab491a2..edcff2c8613a47 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.StackRowStack.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.StackRowStack.cs @@ -23,8 +23,8 @@ internal StackRowStack(int initialSize) public void Dispose() { - byte[] toReturn = _rentedBuffer; - _rentedBuffer = null; + byte[]? toReturn = _rentedBuffer; + _rentedBuffer = null!; _topOfStack = 0; if (toReturn != null) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.TryGetProperty.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.TryGetProperty.cs index 1f77e457cf0fe8..b301f0aeaea1af 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.TryGetProperty.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.TryGetProperty.cs @@ -180,7 +180,7 @@ private bool TryGetNamedPropertyValue( { int remaining = currentPropertyName.Length - idx; int written = 0; - byte[] rented = null; + byte[]? rented = null; try { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.cs index 865f38420edfaf..2de33a948c7596 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.cs @@ -9,6 +9,7 @@ using System.Runtime.InteropServices; using System.Runtime.CompilerServices; using System.Threading; +using System.Diagnostics.CodeAnalysis; namespace System.Text.Json { @@ -25,8 +26,8 @@ public sealed partial class JsonDocument : IDisposable { private ReadOnlyMemory _utf8Json; private MetadataDb _parsedData; - private byte[] _extraRentedBytes; - private (int, string) _lastIndexAndString = (-1, null); + private byte[]? _extraRentedBytes; + private (int, string?) _lastIndexAndString = (-1, null); internal bool IsDisposable { get; } @@ -38,7 +39,7 @@ public sealed partial class JsonDocument : IDisposable private JsonDocument( ReadOnlyMemory utf8Json, MetadataDb parsedData, - byte[] extraRentedBytes, + byte[]? extraRentedBytes, bool isDisposable = true) { Debug.Assert(!utf8Json.IsEmpty); @@ -67,7 +68,7 @@ public void Dispose() // When "extra rented bytes exist" they contain the document, // and thus need to be cleared before being returned. - byte[] extraRentedBytes = Interlocked.Exchange(ref _extraRentedBytes, null); + byte[]? extraRentedBytes = Interlocked.Exchange(ref _extraRentedBytes, null); if (extraRentedBytes != null) { @@ -243,11 +244,11 @@ private ReadOnlyMemory GetPropertyRawValue(int valueIndex) return _utf8Json.Slice(start, end - start); } - internal string GetString(int index, JsonTokenType expectedType) + internal string? GetString(int index, JsonTokenType expectedType) { CheckNotDisposed(); - (int lastIdx, string lastString) = _lastIndexAndString; + (int lastIdx, string? lastString) = _lastIndexAndString; if (lastIdx == index) { @@ -288,14 +289,14 @@ internal bool TextEquals(int index, ReadOnlySpan otherText, bool isPropert int matchIndex = isPropertyName ? index - DbRow.Size : index; - (int lastIdx, string lastString) = _lastIndexAndString; + (int lastIdx, string? lastString) = _lastIndexAndString; if (lastIdx == matchIndex) { return otherText.SequenceEqual(lastString.AsSpan()); } - byte[] otherUtf8TextArray = null; + byte[]? otherUtf8TextArray = null; int length = checked(otherText.Length * JsonConstants.MaxExpansionFactorWhileTranscoding); Span otherUtf8Text = length <= JsonConstants.StackallocThreshold ? @@ -371,10 +372,10 @@ internal bool TextEquals(int index, ReadOnlySpan otherUtf8Text, bool isPro internal string GetNameOfPropertyValue(int index) { // The property name is one row before the property value - return GetString(index - DbRow.Size, JsonTokenType.PropertyName); + return GetString(index - DbRow.Size, JsonTokenType.PropertyName)!; } - internal bool TryGetValue(int index, out byte[] value) + internal bool TryGetValue(int index, [NotNullWhen(true)] out byte[]? value) { CheckNotDisposed(); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonElement.ArrayEnumerator.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonElement.ArrayEnumerator.cs index 3469e9b0e2e339..f2ead3bcebb62f 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonElement.ArrayEnumerator.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonElement.ArrayEnumerator.cs @@ -33,6 +33,7 @@ internal ArrayEnumerator(JsonElement target) } else { + Debug.Assert(target._parent != null); var jsonArray = (JsonArray)target._parent; _endIdxOrVersion = jsonArray._version; } @@ -58,7 +59,7 @@ public JsonElement Current return jsonArray[_curIdx].AsJsonElement(); } - var document = (JsonDocument)_target._parent; + var document = (JsonDocument?)_target._parent; return new JsonElement(document, _curIdx); } } @@ -128,6 +129,7 @@ public bool MoveNext() } else { + Debug.Assert(_target._parent != null); var document = (JsonDocument)_target._parent; _curIdx = document.GetEndIndex(_curIdx, includeEndElement: true); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonElement.ObjectEnumerator.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonElement.ObjectEnumerator.cs index 0035340d555dc6..04d118fa7e193c 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonElement.ObjectEnumerator.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonElement.ObjectEnumerator.cs @@ -19,7 +19,7 @@ public struct ObjectEnumerator : IEnumerable, IEnumerator propertyName, out JsonElement valu return document.TryGetNamedPropertyValue(_idx, propertyName, out value); } - var jsonNode = (JsonNode)_parent; + var jsonNode = (JsonNode)_parent!; if (jsonNode is JsonObject jsonObject) { - if (jsonObject.TryGetPropertyValue(propertyName.ToString(), out JsonNode nodeValue)) + if (jsonObject.TryGetPropertyValue(propertyName.ToString(), out JsonNode? nodeValue)) { value = nodeValue.AsJsonElement(); return true; @@ -379,11 +381,11 @@ public bool TryGetProperty(ReadOnlySpan utf8PropertyName, out JsonElement return document.TryGetNamedPropertyValue(_idx, utf8PropertyName, out value); } - var jsonNode = (JsonNode)_parent; + var jsonNode = (JsonNode)_parent!; if (jsonNode is JsonObject jsonObject) { - if (jsonObject.TryGetPropertyValue(JsonHelpers.Utf8GetString(utf8PropertyName), out JsonNode nodeValue)) + if (jsonObject.TryGetPropertyValue(JsonHelpers.Utf8GetString(utf8PropertyName), out JsonNode? nodeValue)) { value = nodeValue.AsJsonElement(); return true; @@ -424,7 +426,7 @@ public bool GetBoolean() throw ThrowHelper.GetJsonElementWrongTypeException(nameof(Boolean), type); } - var jsonNode = (JsonNode)_parent; + var jsonNode = (JsonNode)_parent!; if (_parent is JsonBoolean jsonBoolean) { @@ -454,10 +456,10 @@ public string GetString() if (_parent is JsonDocument document) { - return document.GetString(_idx, JsonTokenType.String); + return document.GetString(_idx, JsonTokenType.String)!; } - var jsonNode = (JsonNode)_parent; + var jsonNode = (JsonNode)_parent!; if (jsonNode is JsonString jsonString) { @@ -484,7 +486,7 @@ public string GetString() /// /// The parent has been disposed. /// - public bool TryGetBytesFromBase64(out byte[] value) + public bool TryGetBytesFromBase64([NotNullWhen(true)] out byte[]? value) { CheckValidInstance(); @@ -493,7 +495,7 @@ public bool TryGetBytesFromBase64(out byte[] value) return document.TryGetValue(_idx, out value); } - var jsonNode = (JsonNode)_parent; + var jsonNode = (JsonNode)_parent!; if (jsonNode is JsonString jsonString) { @@ -522,7 +524,7 @@ public bool TryGetBytesFromBase64(out byte[] value) /// public byte[] GetBytesFromBase64() { - if (TryGetBytesFromBase64(out byte[] value)) + if (TryGetBytesFromBase64(out byte[]? value)) { return value; } @@ -557,7 +559,7 @@ public bool TryGetSByte(out sbyte value) return document.TryGetValue(_idx, out value); } - var jsonNode = (JsonNode)_parent; + var jsonNode = (JsonNode)_parent!; if (jsonNode is JsonNumber jsonNumber) { @@ -617,7 +619,7 @@ public bool TryGetByte(out byte value) return document.TryGetValue(_idx, out value); } - var jsonNode = (JsonNode)_parent; + var jsonNode = (JsonNode)_parent!; if (jsonNode is JsonNumber jsonNumber) { @@ -679,7 +681,7 @@ public bool TryGetInt16(out short value) return document.TryGetValue(_idx, out value); } - var jsonNode = (JsonNode)_parent; + var jsonNode = (JsonNode)_parent!; if (_parent is JsonNumber jsonNumber) { @@ -739,7 +741,7 @@ public bool TryGetUInt16(out ushort value) return document.TryGetValue(_idx, out value); } - var jsonNode = (JsonNode)_parent; + var jsonNode = (JsonNode)_parent!; if (_parent is JsonNumber jsonNumber) { @@ -802,7 +804,7 @@ public bool TryGetInt32(out int value) return document.TryGetValue(_idx, out value); } - var jsonNode = (JsonNode)_parent; + var jsonNode = (JsonNode)_parent!; if (jsonNode is JsonNumber jsonNumber) { @@ -862,7 +864,7 @@ public bool TryGetUInt32(out uint value) return document.TryGetValue(_idx, out value); } - var jsonNode = (JsonNode)_parent; + var jsonNode = (JsonNode)_parent!; if (jsonNode is JsonNumber jsonNumber) { @@ -925,7 +927,7 @@ public bool TryGetInt64(out long value) return document.TryGetValue(_idx, out value); } - var jsonNode = (JsonNode)_parent; + var jsonNode = (JsonNode)_parent!; if (jsonNode is JsonNumber jsonNumber) { @@ -988,7 +990,7 @@ public bool TryGetUInt64(out ulong value) return document.TryGetValue(_idx, out value); } - var jsonNode = (JsonNode)_parent; + var jsonNode = (JsonNode)_parent!; if (jsonNode is JsonNumber jsonNumber) { @@ -1060,7 +1062,7 @@ public bool TryGetDouble(out double value) return document.TryGetValue(_idx, out value); } - var jsonNode = (JsonNode)_parent; + var jsonNode = (JsonNode)_parent!; if (_parent is JsonNumber jsonNumber) { @@ -1139,7 +1141,7 @@ public bool TryGetSingle(out float value) return document.TryGetValue(_idx, out value); } - var jsonNode = (JsonNode)_parent; + var jsonNode = (JsonNode)_parent!; if (jsonNode is JsonNumber jsonNumber) { @@ -1210,7 +1212,7 @@ public bool TryGetDecimal(out decimal value) return document.TryGetValue(_idx, out value); } - var jsonNode = (JsonNode)_parent; + var jsonNode = (JsonNode)_parent!; if (jsonNode is JsonNumber jsonNumber) { @@ -1273,7 +1275,7 @@ public bool TryGetDateTime(out DateTime value) return document.TryGetValue(_idx, out value); } - var jsonNode = (JsonNode)_parent; + var jsonNode = (JsonNode)_parent!; if (jsonNode is JsonString jsonString) { @@ -1336,7 +1338,7 @@ public bool TryGetDateTimeOffset(out DateTimeOffset value) return document.TryGetValue(_idx, out value); } - var jsonNode = (JsonNode)_parent; + var jsonNode = (JsonNode)_parent!; if (jsonNode is JsonString jsonString) { @@ -1399,7 +1401,7 @@ public bool TryGetGuid(out Guid value) return document.TryGetValue(_idx, out value); } - var jsonNode = (JsonNode)_parent; + var jsonNode = (JsonNode)_parent!; if (jsonNode is JsonString jsonString) { @@ -1440,7 +1442,7 @@ internal string GetPropertyName() { CheckValidInstance(); - var document = (JsonDocument)_parent; + var document = (JsonDocument)_parent!; return document.GetNameOfPropertyValue(_idx); } @@ -1465,7 +1467,7 @@ public string GetRawText() return document.GetRawValueAsString(_idx); } - var jsonNode = (JsonNode)_parent; + var jsonNode = (JsonNode)_parent!; return jsonNode.ToJsonString(); } @@ -1473,7 +1475,7 @@ internal string GetPropertyRawText() { CheckValidInstance(); - var document = (JsonDocument)_parent; + var document = (JsonDocument)_parent!; return document.GetPropertyRawValueAsString(_idx); } @@ -1492,7 +1494,7 @@ internal string GetPropertyRawText() /// This method is functionally equal to doing an ordinal comparison of and /// the result of calling , but avoids creating the string instance. /// - public bool ValueEquals(string text) + public bool ValueEquals(string? text) { // CheckValidInstance is done in the helper @@ -1565,7 +1567,7 @@ internal bool TextEqualsHelper(ReadOnlySpan utf8Text, bool isPropertyName) { CheckValidInstance(); - var document = (JsonDocument)_parent; + var document = (JsonDocument)_parent!; return document.TextEquals(_idx, utf8Text, isPropertyName); } @@ -1573,7 +1575,7 @@ internal bool TextEqualsHelper(ReadOnlySpan text, bool isPropertyName) { CheckValidInstance(); - var document = (JsonDocument)_parent; + var document = (JsonDocument)_parent!; return document.TextEquals(_idx, text, isPropertyName); } @@ -1605,7 +1607,7 @@ public void WriteTo(Utf8JsonWriter writer) } else { - var jsonNode = (JsonNode)_parent; + var jsonNode = (JsonNode)_parent!; jsonNode.WriteTo(writer); } } @@ -1787,7 +1789,7 @@ public JsonElement Clone() return document.CloneElement(_idx); } - var jsonNode = (JsonNode)_parent; + var jsonNode = (JsonNode)_parent!; return jsonNode.Clone().AsJsonElement(); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonProperty.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonProperty.cs index ac6265df3444ff..36595a8abb0406 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonProperty.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonProperty.cs @@ -17,9 +17,9 @@ public readonly struct JsonProperty /// The value of this property. /// public JsonElement Value { get; } - private string _name { get; } + private string? _name { get; } - internal JsonProperty(JsonElement value, string name = null) + internal JsonProperty(JsonElement value, string? name = null) { Value = value; _name = name; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/JsonEncodedText.cs b/src/libraries/System.Text.Json/src/System/Text/Json/JsonEncodedText.cs index 0fb5c89afeb276..2993fac38ab548 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/JsonEncodedText.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/JsonEncodedText.cs @@ -43,7 +43,7 @@ private JsonEncodedText(byte[] utf8Value) /// /// Thrown when the specified value is too large or if it contains invalid UTF-16 characters. /// - public static JsonEncodedText Encode(string value, JavaScriptEncoder encoder = null) + public static JsonEncodedText Encode(string value, JavaScriptEncoder? encoder = null) { if (value == null) throw new ArgumentNullException(nameof(value)); @@ -59,7 +59,7 @@ public static JsonEncodedText Encode(string value, JavaScriptEncoder encoder = n /// /// Thrown when the specified value is too large or if it contains invalid UTF-16 characters. /// - public static JsonEncodedText Encode(ReadOnlySpan value, JavaScriptEncoder encoder = null) + public static JsonEncodedText Encode(ReadOnlySpan value, JavaScriptEncoder? encoder = null) { if (value.Length == 0) { @@ -69,7 +69,7 @@ public static JsonEncodedText Encode(ReadOnlySpan value, JavaScriptEncoder return TranscodeAndEncode(value, encoder); } - private static JsonEncodedText TranscodeAndEncode(ReadOnlySpan value, JavaScriptEncoder encoder) + private static JsonEncodedText TranscodeAndEncode(ReadOnlySpan value, JavaScriptEncoder? encoder) { JsonWriterHelper.ValidateValue(value); @@ -100,7 +100,7 @@ private static JsonEncodedText TranscodeAndEncode(ReadOnlySpan value, Java /// /// Thrown when the specified value is too large or if it contains invalid UTF-8 bytes. /// - public static JsonEncodedText Encode(ReadOnlySpan utf8Value, JavaScriptEncoder encoder = null) + public static JsonEncodedText Encode(ReadOnlySpan utf8Value, JavaScriptEncoder? encoder = null) { if (utf8Value.Length == 0) { @@ -111,7 +111,7 @@ public static JsonEncodedText Encode(ReadOnlySpan utf8Value, JavaScriptEnc return EncodeHelper(utf8Value, encoder); } - private static JsonEncodedText EncodeHelper(ReadOnlySpan utf8Value, JavaScriptEncoder encoder) + private static JsonEncodedText EncodeHelper(ReadOnlySpan utf8Value, JavaScriptEncoder? encoder) { int idx = JsonWriterHelper.NeedsEscaping(utf8Value, encoder); @@ -125,12 +125,12 @@ private static JsonEncodedText EncodeHelper(ReadOnlySpan utf8Value, JavaSc } } - private static byte[] GetEscapedString(ReadOnlySpan utf8Value, int firstEscapeIndexVal, JavaScriptEncoder encoder) + private static byte[] GetEscapedString(ReadOnlySpan utf8Value, int firstEscapeIndexVal, JavaScriptEncoder? encoder) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8Value.Length); Debug.Assert(firstEscapeIndexVal >= 0 && firstEscapeIndexVal < utf8Value.Length); - byte[] valueArray = null; + byte[]? valueArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(utf8Value.Length, firstEscapeIndexVal); @@ -174,7 +174,7 @@ public bool Equals(JsonEncodedText other) /// /// If is null, the method returns false. /// - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (obj is JsonEncodedText encodedText) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/JsonException.cs b/src/libraries/System.Text.Json/src/System/Text/Json/JsonException.cs index 901f5a548cca8a..b4e511dd773bba 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/JsonException.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/JsonException.cs @@ -14,7 +14,7 @@ namespace System.Text.Json public class JsonException : Exception { // Allow the message to mutate to avoid re-throwing and losing the StackTrace to an inner exception. - private string _message; + internal string? _message; /// /// Creates a new exception object to relay error information to the user. @@ -27,7 +27,7 @@ public class JsonException : Exception /// /// Note that the counts the number of bytes (i.e. UTF-8 code units) and not characters or scalars. /// - public JsonException(string message, string path, long? lineNumber, long? bytePositionInLine, Exception innerException) : base(message, innerException) + public JsonException(string? message, string? path, long? lineNumber, long? bytePositionInLine, Exception? innerException) : base(message, innerException) { _message = message; LineNumber = lineNumber; @@ -45,7 +45,7 @@ public JsonException(string message, string path, long? lineNumber, long? bytePo /// /// Note that the counts the number of bytes (i.e. UTF-8 code units) and not characters or scalars. /// - public JsonException(string message, string path, long? lineNumber, long? bytePositionInLine) : base(message) + public JsonException(string? message, string? path, long? lineNumber, long? bytePositionInLine) : base(message) { _message = message; LineNumber = lineNumber; @@ -58,7 +58,7 @@ public JsonException(string message, string path, long? lineNumber, long? bytePo /// /// The context specific error message. /// The exception that caused the current exception. - public JsonException(string message, Exception innerException) : base(message, innerException) + public JsonException(string? message, Exception? innerException) : base(message, innerException) { _message = message; } @@ -67,7 +67,7 @@ public JsonException(string message, Exception innerException) : base(message, i /// Creates a new exception object to relay error information to the user. /// /// The context specific error message. - public JsonException(string message) : base(message) + public JsonException(string? message) : base(message) { _message = message; } @@ -125,7 +125,7 @@ public override void GetObjectData(SerializationInfo info, StreamingContext cont /// /// The path within the JSON where the exception was encountered. /// - public string Path { get; internal set; } + public string? Path { get; internal set; } /// /// Gets a message that describes the current exception. @@ -134,11 +134,11 @@ public override string Message { get { - return _message; + return _message ?? base.Message; } } - internal void SetMessage(string message) + internal void SetMessage(string? message) { _message = message; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/JsonHelpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/JsonHelpers.cs index 4c9f1260945750..e9fbe8fc2b9db7 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/JsonHelpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/JsonHelpers.cs @@ -81,7 +81,7 @@ internal static string Utf8GetString(ReadOnlySpan bytes) /// /// Emulates Dictionary.TryAdd on netstandard. /// - internal static bool TryAdd(Dictionary dictionary, TKey key, TValue value) + internal static bool TryAdd(Dictionary dictionary, TKey key, TValue value) where TKey : notnull { #if NETSTANDARD2_0 || NETFRAMEWORK if (!dictionary.ContainsKey(key)) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonArray.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonArray.cs index 17b8ed14d75d32..5f8f7aa2128dd1 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonArray.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonArray.cs @@ -4,6 +4,7 @@ using System.Collections; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace System.Text.Json { @@ -208,6 +209,7 @@ public JsonArray(IEnumerable values) : this() /// Index is less than 0. /// /// Null value is allowed and will be converted to the instance. + [AllowNull] public JsonNode this[int idx] { get => _list[idx]; @@ -223,7 +225,7 @@ public JsonNode this[int idx] /// /// The value to add. /// Null value is allowed and will be converted to the instance. - public void Add(JsonNode value) + public void Add(JsonNode? value) { _list.Add(value ?? JsonNull.Instance); _version++; @@ -235,7 +237,7 @@ public void Add(JsonNode value) /// The zero-based index at which should be inserted. /// The item to add. /// Null value is allowed and will be converted to the instance. - public void Insert(int index, JsonNode item) + public void Insert(int index, JsonNode? item) { _list.Insert(index, item ?? JsonNull.Instance); _version++; @@ -250,7 +252,7 @@ public void Insert(int index, JsonNode item) /// otherwise. /// /// Null value is allowed and will be converted to the instance. - public bool Contains(JsonNode value) => _list.Contains(value ?? JsonNull.Instance); + public bool Contains(JsonNode? value) => _list.Contains(value ?? JsonNull.Instance); /// /// Gets the number of elements contained in the collection. @@ -268,7 +270,7 @@ public void Insert(int index, JsonNode item) /// Item to find. /// The zero-based starting index of the search. 0 (zero) is valid in an empty collection. /// Null value is allowed and will be converted to the instance. - public int IndexOf(JsonNode item) => _list.IndexOf(item ?? JsonNull.Instance); + public int IndexOf(JsonNode? item) => _list.IndexOf(item ?? JsonNull.Instance); /// /// Returns the zero-based index of the last occurrence of a specified item in the collection. @@ -276,7 +278,7 @@ public void Insert(int index, JsonNode item) /// Item to find. /// The zero-based starting index of the search. 0 (zero) is valid in an empty collection. /// Null value is allowed and will be converted to the instance. - public int LastIndexOf(JsonNode item) => _list.LastIndexOf(item ?? JsonNull.Instance); + public int LastIndexOf(JsonNode? item) => _list.LastIndexOf(item ?? JsonNull.Instance); /// /// Removes all elements from the JSON array. @@ -298,7 +300,7 @@ public void Clear() /// otherwise. /// /// Null value is allowed and will be converted to the instance. - public bool Remove(JsonNode item) + public bool Remove(JsonNode? item) { _version++; return _list.Remove(item ?? JsonNull.Instance); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs index d98e1d401d73c7..8f36a690b04a85 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs @@ -7,7 +7,10 @@ namespace System.Text.Json /// /// Represents a mutable boolean JSON value. /// - public sealed class JsonBoolean : JsonNode, IEquatable + public sealed class JsonBoolean : JsonNode, +#nullable disable // to enable use with both T and T? for reference types due to IEquatable being invariant + IEquatable +#nullable restore { /// /// Initializes a new instance of the class representing the value . @@ -38,7 +41,7 @@ public sealed class JsonBoolean : JsonNode, IEquatable /// if the boolean value of this instance matches , /// otherwise. /// - public override bool Equals(object obj) => obj is JsonBoolean jsonBoolean && Equals(jsonBoolean); + public override bool Equals(object? obj) => obj is JsonBoolean jsonBoolean && Equals(jsonBoolean); /// /// Calculates a hash code of this instance. @@ -54,7 +57,7 @@ public sealed class JsonBoolean : JsonNode, IEquatable /// if the boolean value of this instance matches , /// otherwise. /// - public bool Equals(JsonBoolean other) => !(other is null) && Value == other.Value; + public bool Equals(JsonBoolean? other) => !(other is null) && Value == other.Value; /// /// Compares values of two JSON booleans. @@ -65,7 +68,7 @@ public sealed class JsonBoolean : JsonNode, IEquatable /// if values of instances match, /// otherwise. /// - public static bool operator ==(JsonBoolean left, JsonBoolean right) + public static bool operator ==(JsonBoolean? left, JsonBoolean? right) { // Test "right" first to allow branch elimination when inlined for null checks (== null) // so it can become a simple test @@ -87,7 +90,7 @@ public sealed class JsonBoolean : JsonNode, IEquatable /// if values of instances do not match, /// otherwise. /// - public static bool operator !=(JsonBoolean left, JsonBoolean right) => !(left == right); + public static bool operator !=(JsonBoolean? left, JsonBoolean? right) => !(left == right); /// /// Creates a new JSON boolean that is a copy of the current instance. diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonNode.RecursionStackFrame.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonNode.RecursionStackFrame.cs index ba0eaba7a0e0f3..55f9aac8b0feb9 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonNode.RecursionStackFrame.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonNode.RecursionStackFrame.cs @@ -11,18 +11,18 @@ public abstract partial class JsonNode { private readonly struct RecursionStackFrame { - public string PropertyName { get; } - public JsonNode PropertyValue { get; } + public string? PropertyName { get; } + public JsonNode? PropertyValue { get; } public JsonValueKind ValueKind { get; } // to retrieve ValueKind when PropertyValue is null - public RecursionStackFrame(string propertyName, JsonNode propertyValue, JsonValueKind valueKind) + public RecursionStackFrame(string? propertyName, JsonNode? propertyValue, JsonValueKind valueKind) { PropertyName = propertyName; PropertyValue = propertyValue; ValueKind = valueKind; } - public RecursionStackFrame(string propertyName, JsonNode propertyValue) : this(propertyName, propertyValue, propertyValue.ValueKind) + public RecursionStackFrame(string? propertyName, JsonNode propertyValue) : this(propertyName, propertyValue, propertyValue.ValueKind) { } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonNode.Traversal.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonNode.Traversal.cs index 5bbfc7938136f9..9f904a3c840688 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonNode.Traversal.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonNode.Traversal.cs @@ -30,13 +30,13 @@ public static JsonNode DeepCopy(JsonElement jsonElement) // Iterative DFS: - var currentNodes = new Stack>(); // objects/arrays currently being created - var recursionStack = new Stack>(); // null JsonElement represents end of current object/array - JsonNode toReturn = null; + var currentNodes = new Stack>(); // objects/arrays currently being created + var recursionStack = new Stack>(); // null JsonElement represents end of current object/array + JsonNode? toReturn = null; - recursionStack.Push(new KeyValuePair(null, jsonElement)); + recursionStack.Push(new KeyValuePair(null, jsonElement)); - while (recursionStack.TryPop(out KeyValuePair currentPair)) + while (recursionStack.TryPop(out KeyValuePair currentPair)) { JsonElement? currentJsonElement = currentPair.Value; @@ -44,7 +44,7 @@ public static JsonNode DeepCopy(JsonElement jsonElement) { // Current object/array is finished and can be added to its parent: - KeyValuePair nodePair = currentNodes.Pop(); + KeyValuePair nodePair = currentNodes.Pop(); Debug.Assert(nodePair.Value is JsonArray || nodePair.Value is JsonObject); @@ -59,51 +59,51 @@ public static JsonNode DeepCopy(JsonElement jsonElement) var jsonObject = new JsonObject(); // Add jsonObject to current nodes: - currentNodes.Push(new KeyValuePair(currentPair.Key, jsonObject)); + currentNodes.Push(new KeyValuePair(currentPair.Key, jsonObject)); // Add end of object marker: - recursionStack.Push(new KeyValuePair(null, null)); + recursionStack.Push(new KeyValuePair(null, null)); // Add properties to recursion stack. Reverse enumerate to keep properties order: foreach (JsonProperty property in currentJsonElement.Value.EnumerateObject().Reverse()) { - recursionStack.Push(new KeyValuePair(property.Name, property.Value)); + recursionStack.Push(new KeyValuePair(property.Name, property.Value)); } break; case JsonValueKind.Array: var jsonArray = new JsonArray(); // Add jsonArray to current nodes: - currentNodes.Push(new KeyValuePair(currentPair.Key, jsonArray)); + currentNodes.Push(new KeyValuePair(currentPair.Key, jsonArray)); // Add end of array marker: - recursionStack.Push(new KeyValuePair(null, null)); + recursionStack.Push(new KeyValuePair(null, null)); // Add elements to recursion stack. Reverse enumerate to keep items order: foreach (JsonElement element in currentJsonElement.Value.EnumerateArray().Reverse()) { - recursionStack.Push(new KeyValuePair(null, element)); + recursionStack.Push(new KeyValuePair(null, element)); } break; case JsonValueKind.Number: var jsonNumber = new JsonNumber(currentJsonElement.Value.GetRawText()); - AddToParent(new KeyValuePair(currentPair.Key, jsonNumber), ref currentNodes, ref toReturn); + AddToParent(new KeyValuePair(currentPair.Key, jsonNumber), ref currentNodes, ref toReturn); break; case JsonValueKind.String: var jsonString = new JsonString(currentJsonElement.Value.GetString()); - AddToParent(new KeyValuePair(currentPair.Key, jsonString), ref currentNodes, ref toReturn); + AddToParent(new KeyValuePair(currentPair.Key, jsonString), ref currentNodes, ref toReturn); break; case JsonValueKind.True: var jsonBooleanTrue = new JsonBoolean(true); - AddToParent(new KeyValuePair(currentPair.Key, jsonBooleanTrue), ref currentNodes, ref toReturn); + AddToParent(new KeyValuePair(currentPair.Key, jsonBooleanTrue), ref currentNodes, ref toReturn); break; case JsonValueKind.False: var jsonBooleanFalse = new JsonBoolean(false); - AddToParent(new KeyValuePair(currentPair.Key, jsonBooleanFalse), ref currentNodes, ref toReturn); + AddToParent(new KeyValuePair(currentPair.Key, jsonBooleanFalse), ref currentNodes, ref toReturn); break; case JsonValueKind.Null: var jsonNull = JsonNull.Instance; - AddToParent(new KeyValuePair(currentPair.Key, jsonNull), ref currentNodes, ref toReturn); + AddToParent(new KeyValuePair(currentPair.Key, jsonNull), ref currentNodes, ref toReturn); break; default: Debug.Assert(jsonElement.ValueKind == JsonValueKind.Undefined, "No handler for JsonValueKind.{jsonElement.ValueKind}"); @@ -126,17 +126,17 @@ public static JsonNode Parse(string json, JsonNodeOptions options = default) { Utf8JsonReader reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json), options.GetReaderOptions()); - var currentNodes = new Stack>(); // nodes currently being created - JsonNode toReturn = null; + var currentNodes = new Stack>(); // nodes currently being created + JsonNode? toReturn = null; while (reader.Read()) { JsonTokenType tokenType = reader.TokenType; - currentNodes.TryPeek(out KeyValuePair currentPair); + currentNodes.TryPeek(out KeyValuePair currentPair); void AddNewPair(JsonNode jsonNode, bool keepInCurrentNodes = false) { - KeyValuePair newProperty; + KeyValuePair newProperty; if (currentPair.Value == null) { @@ -147,18 +147,18 @@ void AddNewPair(JsonNode jsonNode, bool keepInCurrentNodes = false) { // Create as property, keep name, replace null with new JsonNode: currentNodes.Pop(); - newProperty = new KeyValuePair(currentPair.Key, jsonNode); + newProperty = new KeyValuePair(currentPair.Key, jsonNode); } else { // Add first JsonNode: - newProperty = new KeyValuePair(null, jsonNode); + newProperty = new KeyValuePair(null, jsonNode); } } else { // Create as value: - newProperty = new KeyValuePair(null, jsonNode); + newProperty = new KeyValuePair(null, jsonNode); } if (keepInCurrentNodes) @@ -195,13 +195,13 @@ void AddNewPair(JsonNode jsonNode, bool keepInCurrentNodes = false) AddToParent(currentPair, ref currentNodes, ref toReturn, options.DuplicatePropertyNameHandling); break; case JsonTokenType.PropertyName: - currentNodes.Push(new KeyValuePair(reader.GetString(), null)); + currentNodes.Push(new KeyValuePair(reader.GetString(), null)); break; case JsonTokenType.Number: AddNewPair(new JsonNumber(JsonHelpers.Utf8GetString(reader.ValueSpan))); break; case JsonTokenType.String: - AddNewPair(new JsonString(reader.GetString())); + AddNewPair(new JsonString(reader.GetString()!)); break; case JsonTokenType.True: AddNewPair(new JsonBoolean(true)); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonNode.TraversalHelpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonNode.TraversalHelpers.cs index 90f8f55a6271c0..7e52a73ddaa12e 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonNode.TraversalHelpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonNode.TraversalHelpers.cs @@ -13,12 +13,12 @@ namespace System.Text.Json public abstract partial class JsonNode { private static void AddToParent( - KeyValuePair nodePair, - ref Stack> currentNodes, - ref JsonNode toReturn, + KeyValuePair nodePair, + ref Stack> currentNodes, + ref JsonNode? toReturn, DuplicatePropertyNameHandlingStrategy duplicatePropertyNameHandling = DuplicatePropertyNameHandlingStrategy.Replace) { - if (currentNodes.TryPeek(out KeyValuePair parentPair)) + if (currentNodes.TryPeek(out KeyValuePair parentPair)) { // Parent needs to be JsonObject or JsonArray Debug.Assert(parentPair.Value is JsonObject || parentPair.Value is JsonArray); @@ -42,7 +42,7 @@ private static void AddToParent( } else { - jsonObject.Add(nodePair); + jsonObject.Add(nodePair!); } } else if (parentPair.Value is JsonArray jsonArray) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonNode.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonNode.cs index 3d2a50d1467982..b3c632f14ffc7d 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonNode.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonNode.cs @@ -2,6 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; + namespace System.Text.Json { /// @@ -33,7 +36,15 @@ private protected JsonNode() { } /// /// Provided was not built from . /// - public static JsonNode GetNode(JsonElement jsonElement) => !jsonElement.IsImmutable ? (JsonNode)jsonElement._parent : throw new ArgumentException(SR.NotNodeJsonElementParent); + public static JsonNode GetNode(JsonElement jsonElement) + { + if (jsonElement.IsImmutable) + { + throw new ArgumentException(SR.NotNodeJsonElementParent); + } + Debug.Assert(jsonElement._parent != null); + return (JsonNode)jsonElement._parent; + } /// /// Gets the represented by the . @@ -46,10 +57,11 @@ private protected JsonNode() { } /// if the operation succeded; /// otherwise, /// - public static bool TryGetNode(JsonElement jsonElement, out JsonNode jsonNode) + public static bool TryGetNode(JsonElement jsonElement, [NotNullWhen(true)] out JsonNode? jsonNode) { if (!jsonElement.IsImmutable) { + Debug.Assert(jsonElement._parent != null); jsonNode = (JsonNode)jsonElement._parent; return true; } @@ -71,7 +83,7 @@ public static bool TryGetNode(JsonElement jsonElement, out JsonNode jsonNode) /// /// Null value is accepted and will be interpreted as . /// - public static implicit operator JsonNode(string value) + public static implicit operator JsonNode(string? value) { if (value == null) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonNull.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonNull.cs index 472051a4a5ef66..efa4fd0d978824 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonNull.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonNull.cs @@ -7,7 +7,10 @@ namespace System.Text.Json /// /// Represents the null JSON value. /// - public sealed class JsonNull : JsonNode, IEquatable + public sealed class JsonNull : JsonNode, +#nullable disable // to enable use with both T and T? for reference types due to IEquatable being invariant + IEquatable +#nullable restore { /// /// Initializes a new instance of the class representing the value . @@ -30,7 +33,7 @@ public JsonNull() { } /// if the is , /// otherwise. /// - public override bool Equals(object obj) => obj is JsonNull; + public override bool Equals(object? obj) => obj is JsonNull; /// /// Calculates a hash code of this instance. @@ -43,7 +46,7 @@ public JsonNull() { } /// /// The JSON null to compare against. /// - public bool Equals(JsonNull other) => true; + public bool Equals(JsonNull? other) => true; /// /// Compares values of two JSON nulls. @@ -51,7 +54,7 @@ public JsonNull() { } /// The JSON null to compare. /// The JSON null to compare. /// - public static bool operator ==(JsonNull left, JsonNull right) => true; + public static bool operator ==(JsonNull? left, JsonNull? right) => true; /// /// Compares values of two JSON nulls. @@ -59,7 +62,7 @@ public JsonNull() { } /// The JSON null to compare. /// The JSON null to compare. /// - public static bool operator !=(JsonNull left, JsonNull right) => false; + public static bool operator !=(JsonNull? left, JsonNull? right) => false; /// /// Creates a new JSON null that is a copy of the current instance. diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonNumber.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonNumber.cs index 2935e252c399e6..1faad281db52f0 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonNumber.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonNumber.cs @@ -9,9 +9,12 @@ namespace System.Text.Json /// /// Represents a mutable numeric JSON value. /// - public sealed class JsonNumber : JsonNode, IEquatable + public sealed class JsonNumber : JsonNode, +#nullable disable // to enable use with both T and T? for reference types due to IEquatable being invariant + IEquatable +#nullable restore { - private string _value; + private string _value = null!; /// /// Initializes a new instance of the class representing the value 0. @@ -557,7 +560,7 @@ public void SetDouble(double value) /// if the value of this instance matches exactly (is equal and has the same format), /// otherwise. /// - public override bool Equals(object obj) => obj is JsonNumber jsonNumber && Equals(jsonNumber); + public override bool Equals(object? obj) => obj is JsonNumber jsonNumber && Equals(jsonNumber); /// /// Calculates a hash code of this instance. @@ -573,7 +576,7 @@ public void SetDouble(double value) /// if the value of this instance matches exactly (is equal and has the same format), /// otherwise. /// - public bool Equals(JsonNumber other) => !(other is null) && _value == other._value; + public bool Equals(JsonNumber? other) => !(other is null) && _value == other._value; /// /// Compares values of two JSON numbers. @@ -584,7 +587,7 @@ public void SetDouble(double value) /// if values of instances match exactly (are equal and have the same format), /// otherwise. /// - public static bool operator ==(JsonNumber left, JsonNumber right) + public static bool operator ==(JsonNumber? left, JsonNumber? right) { // Test "right" first to allow branch elimination when inlined for null checks (== null) // so it can become a simple test @@ -606,7 +609,7 @@ public void SetDouble(double value) /// if values of instances do not match exactly (are not equal or have different format), /// otherwise. /// - public static bool operator !=(JsonNumber left, JsonNumber right) => !(left == right); + public static bool operator !=(JsonNumber? left, JsonNumber? right) => !(left == right); /// /// Creates a new JSON number that is a copy of the current instance. diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonObject.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonObject.cs index fbc9531d4695b8..4b1a336ed51c5c 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonObject.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonObject.cs @@ -4,6 +4,7 @@ using System.Collections; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace System.Text.Json { @@ -13,8 +14,8 @@ namespace System.Text.Json public sealed class JsonObject : JsonNode, IEnumerable> { internal readonly Dictionary _dictionary; - internal JsonObjectProperty _first; - internal JsonObjectProperty _last; + internal JsonObjectProperty? _first; + internal JsonObjectProperty? _last; internal int _version; /// @@ -29,7 +30,7 @@ public JsonObject() /// Initializes a new instance of the class representing provided set of JSON properties. /// /// >Properties to represent as a JSON object. - public JsonObject(IEnumerable> jsonProperties) + public JsonObject(IEnumerable> jsonProperties) : this() => AddRange(jsonProperties); @@ -40,6 +41,7 @@ public JsonObject(IEnumerable> jsonProperties) /// /// Provided property name is null. /// + [AllowNull] public JsonNode this[string propertyName] { get => propertyName != null ? GetPropertyValue(propertyName) : throw new ArgumentNullException(nameof(propertyName)); @@ -70,7 +72,7 @@ public JsonNode this[string propertyName] /// /// Property name to add already exists. /// - public void Add(KeyValuePair jsonProperty) => Add(jsonProperty.Key, jsonProperty.Value); + public void Add(KeyValuePair jsonProperty) => Add(jsonProperty.Key, jsonProperty.Value); /// /// Adds the specified property to the JSON object. @@ -84,7 +86,7 @@ public JsonNode this[string propertyName] /// Property name to add already exists. /// /// Null value is allowed and will be converted to the instance. - public void Add(string propertyName, JsonNode propertyValue) + public void Add(string propertyName, JsonNode? propertyValue) { if (propertyName == null) { @@ -127,9 +129,9 @@ public void Add(string propertyName, JsonNode propertyValue) /// /// Some of the property names are null. /// - public void AddRange(IEnumerable> jsonProperties) + public void AddRange(IEnumerable> jsonProperties) { - foreach (KeyValuePair property in jsonProperties) + foreach (KeyValuePair property in jsonProperties) { Add(property); } @@ -154,7 +156,7 @@ public bool Remove(string propertyName) } #if BUILDING_INBOX_LIBRARY - if (_dictionary.Remove(propertyName, out JsonObjectProperty value)) + if (_dictionary.Remove(propertyName, out JsonObjectProperty? value)) { AdjustLinkedListPointers(value); _version++; @@ -202,7 +204,7 @@ public bool Remove(string propertyName, StringComparison stringComparison) throw new ArgumentNullException(nameof(propertyName)); } - JsonObjectProperty _current = _first; + JsonObjectProperty? _current = _first; while (_current != null && !string.Equals(_current.Name, propertyName, stringComparison)) { @@ -298,7 +300,7 @@ public bool ContainsProperty(string propertyName, StringComparison stringCompari /// public JsonNode GetPropertyValue(string propertyName) { - if (!TryGetPropertyValue(propertyName, out JsonNode jsonNode)) + if (!TryGetPropertyValue(propertyName, out JsonNode? jsonNode)) { throw new KeyNotFoundException(SR.Format(SR.PropertyNotFound, propertyName)); } @@ -320,7 +322,7 @@ public JsonNode GetPropertyValue(string propertyName) /// public JsonNode GetPropertyValue(string propertyName, StringComparison stringComparison) { - if (!TryGetPropertyValue(propertyName, stringComparison, out JsonNode jsonNode)) + if (!TryGetPropertyValue(propertyName, stringComparison, out JsonNode? jsonNode)) { throw new KeyNotFoundException(SR.Format(SR.PropertyNotFound, propertyName)); } @@ -340,9 +342,9 @@ public JsonNode GetPropertyValue(string propertyName, StringComparison stringCom /// /// When this method returns , the value of is meaningless. /// - public bool TryGetPropertyValue(string propertyName, out JsonNode jsonNode) + public bool TryGetPropertyValue(string propertyName, [NotNullWhen(true)] out JsonNode? jsonNode) { - if (_dictionary.TryGetValue(propertyName, out JsonObjectProperty jsonObjectProperty)) + if (_dictionary.TryGetValue(propertyName, out JsonObjectProperty? jsonObjectProperty)) { jsonNode = jsonObjectProperty.Value; return true; @@ -368,7 +370,7 @@ public bool TryGetPropertyValue(string propertyName, out JsonNode jsonNode) /// /// If is set to , calling this method is equivalent to calling . /// - public bool TryGetPropertyValue(string propertyName, StringComparison stringComparison, out JsonNode jsonNode) + public bool TryGetPropertyValue(string propertyName, StringComparison stringComparison, [NotNullWhen(true)] out JsonNode? jsonNode) { if (stringComparison == StringComparison.Ordinal) { @@ -443,9 +445,9 @@ public JsonObject GetJsonObjectPropertyValue(string propertyName, StringComparis /// if JSON object property with specified name was found; /// otherwise, /// - public bool TryGetJsonObjectPropertyValue(string propertyName, out JsonObject jsonObject) + public bool TryGetJsonObjectPropertyValue(string propertyName, [NotNullWhen(true)] out JsonObject? jsonObject) { - if (TryGetPropertyValue(propertyName, out JsonNode jsonNode)) + if (TryGetPropertyValue(propertyName, out JsonNode? jsonNode)) { jsonObject = jsonNode as JsonObject; return jsonObject != null; @@ -468,9 +470,9 @@ public bool TryGetJsonObjectPropertyValue(string propertyName, out JsonObject js /// /// If is set to , calling this method is equivalent to calling . /// - public bool TryGetJsonObjectPropertyValue(string propertyName, StringComparison stringComparison, out JsonObject jsonObject) + public bool TryGetJsonObjectPropertyValue(string propertyName, StringComparison stringComparison, [NotNullWhen(true)] out JsonObject? jsonObject) { - if (TryGetPropertyValue(propertyName, stringComparison, out JsonNode jsonNode)) + if (TryGetPropertyValue(propertyName, stringComparison, out JsonNode? jsonNode)) { jsonObject = jsonNode as JsonObject; return jsonObject != null; @@ -535,9 +537,9 @@ public JsonArray GetJsonArrayPropertyValue(string propertyName, StringComparison /// if JSON array property with specified name was found; /// otherwise, /// - public bool TryGetJsonArrayPropertyValue(string propertyName, out JsonArray jsonArray) + public bool TryGetJsonArrayPropertyValue(string propertyName, [NotNullWhen(true)] out JsonArray? jsonArray) { - if (TryGetPropertyValue(propertyName, out JsonNode jsonNode)) + if (TryGetPropertyValue(propertyName, out JsonNode? jsonNode)) { jsonArray = jsonNode as JsonArray; return jsonArray != null; @@ -560,9 +562,9 @@ public bool TryGetJsonArrayPropertyValue(string propertyName, out JsonArray json /// /// If is set to , calling this method is equivalent to calling . /// - public bool TryGetJsonArrayPropertyValue(string propertyName, StringComparison stringComparison, out JsonArray jsonArray) + public bool TryGetJsonArrayPropertyValue(string propertyName, StringComparison stringComparison, [NotNullWhen(true)] out JsonArray? jsonArray) { - if (TryGetPropertyValue(propertyName, stringComparison, out JsonNode jsonNode)) + if (TryGetPropertyValue(propertyName, stringComparison, out JsonNode? jsonNode)) { jsonArray = jsonNode as JsonArray; return jsonArray != null; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonObjectEnumerator.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonObjectEnumerator.cs index 856c3bedfd3872..4d520703275023 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonObjectEnumerator.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonObjectEnumerator.cs @@ -8,8 +8,8 @@ namespace System.Text.Json /// public struct JsonObjectEnumerator : IEnumerator> { - private JsonObjectProperty _first; - private JsonObjectProperty _current; + private JsonObjectProperty? _first; + private JsonObjectProperty? _current; /// /// Initializes a new instance of the class supporting an interation over provided JSON object. diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonObjectProperty.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonObjectProperty.cs index 7e40518373a52f..ad48415377ffb1 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonObjectProperty.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonObjectProperty.cs @@ -8,10 +8,10 @@ internal class JsonObjectProperty { internal string Name { get; } internal JsonNode Value { get; set; } - internal JsonObjectProperty Prev { get; set; } - internal JsonObjectProperty Next { get; set; } + internal JsonObjectProperty? Prev { get; set; } + internal JsonObjectProperty? Next { get; set; } - public JsonObjectProperty(string name, JsonNode value, JsonObjectProperty prev, JsonObjectProperty next) + public JsonObjectProperty(string name, JsonNode value, JsonObjectProperty? prev, JsonObjectProperty? next) { Name = name; Value = value; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonString.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonString.cs index a896a829b779a9..fe841698278faa 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonString.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonString.cs @@ -5,15 +5,19 @@ using System.Globalization; using System.Buffers; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Text.Json { /// /// Represents a mutable text JSON value. /// - public sealed class JsonString : JsonNode, IEquatable + public sealed class JsonString : JsonNode, +#nullable disable // to enable use with both T and T? for reference types due to IEquatable being invariant + IEquatable +#nullable restore { - private string _value; + private string _value = null!; /// /// Initializes a new instance of the class representing the empty value. @@ -149,7 +153,7 @@ public string Value /// if the text value of this instance matches , /// otherwise. /// - public override bool Equals(object obj) => obj is JsonString jsonString && Equals(jsonString); + public override bool Equals(object? obj) => obj is JsonString jsonString && Equals(jsonString); /// /// Calculates a hash code of this instance. @@ -165,7 +169,7 @@ public string Value /// if the text value of this instance matches , /// otherwise. /// - public bool Equals(JsonString other) => !(other is null) && Value == other.Value; + public bool Equals(JsonString? other) => !(other is null) && Value == other.Value; /// /// Compares values of two JSON strings. @@ -176,7 +180,7 @@ public string Value /// if values of instances match, /// otherwise. /// - public static bool operator ==(JsonString left, JsonString right) + public static bool operator ==(JsonString? left, JsonString? right) { // Test "right" first to allow branch elimination when inlined for null checks (== null) // so it can become a simple test @@ -198,7 +202,7 @@ public string Value /// if values of instances do not match, /// otherwise. /// - public static bool operator !=(JsonString left, JsonString right) => !(left == right); + public static bool operator !=(JsonString? left, JsonString? right) => !(left == right); /// /// Creates a new JSON string that is a copy of the current instance. @@ -222,7 +226,7 @@ public string Value /// /// if text was converted successfully; othwerwise returns . /// - internal bool TryGetBytesFromBase64(out byte[] value) + internal bool TryGetBytesFromBase64([NotNullWhen(true)] out byte[]? value) { Debug.Assert(_value != null); @@ -238,7 +242,7 @@ internal bool TryGetBytesFromBase64(out byte[] value) // be /4 * 3 - padding. To be on the safe side, keep padding and slice later int bufferSize = _value.Length / 4 * 3; - byte[] arrayToReturnToPool = null; + byte[]? arrayToReturnToPool = null; Span buffer = bufferSize <= JsonConstants.StackallocThreshold ? stackalloc byte[JsonConstants.StackallocThreshold] : arrayToReturnToPool = ArrayPool.Shared.Rent(bufferSize); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderHelper.Unescaping.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderHelper.Unescaping.cs index fa4502b62329c7..bed38869cffc81 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderHelper.Unescaping.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderHelper.Unescaping.cs @@ -5,14 +5,15 @@ using System.Buffers; using System.Buffers.Text; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Text.Json { internal static partial class JsonReaderHelper { - public static bool TryGetUnescapedBase64Bytes(ReadOnlySpan utf8Source, int idx, out byte[] bytes) + public static bool TryGetUnescapedBase64Bytes(ReadOnlySpan utf8Source, int idx, [NotNullWhen(true)] out byte[]? bytes) { - byte[] unescapedArray = null; + byte[]? unescapedArray = null; Span utf8Unescaped = utf8Source.Length <= JsonConstants.StackallocThreshold ? stackalloc byte[utf8Source.Length] : @@ -41,7 +42,7 @@ public static bool TryGetUnescapedBase64Bytes(ReadOnlySpan utf8Source, int // TODO: Similar to escaping, replace the unescaping logic with publicly shipping APIs from https://github.com/dotnet/corefx/issues/33509 public static string GetUnescapedString(ReadOnlySpan utf8Source, int idx) { - byte[] unescapedArray = null; + byte[]? unescapedArray = null; Span utf8Unescaped = utf8Source.Length <= JsonConstants.StackallocThreshold ? stackalloc byte[utf8Source.Length] : @@ -68,7 +69,7 @@ public static bool UnescapeAndCompare(ReadOnlySpan utf8Source, ReadOnlySpa { Debug.Assert(utf8Source.Length >= other.Length && utf8Source.Length / JsonConstants.MaxExpansionFactorWhileEscaping <= other.Length); - byte[] unescapedArray = null; + byte[]? unescapedArray = null; Span utf8Unescaped = utf8Source.Length <= JsonConstants.StackallocThreshold ? stackalloc byte[utf8Source.Length] : @@ -96,8 +97,8 @@ public static bool UnescapeAndCompare(ReadOnlySequence utf8Source, ReadOnl Debug.Assert(!utf8Source.IsSingleSegment); Debug.Assert(utf8Source.Length >= other.Length && utf8Source.Length / JsonConstants.MaxExpansionFactorWhileEscaping <= other.Length); - byte[] escapedArray = null; - byte[] unescapedArray = null; + byte[]? escapedArray = null; + byte[]? unescapedArray = null; int length = checked((int)utf8Source.Length); @@ -132,7 +133,7 @@ public static bool UnescapeAndCompare(ReadOnlySequence utf8Source, ReadOnl return result; } - public static bool TryDecodeBase64InPlace(Span utf8Unescaped, out byte[] bytes) + public static bool TryDecodeBase64InPlace(Span utf8Unescaped, [NotNullWhen(true)] out byte[]? bytes) { OperationStatus status = Base64.DecodeFromUtf8InPlace(utf8Unescaped, out int bytesWritten); if (status != OperationStatus.Done) @@ -144,9 +145,9 @@ public static bool TryDecodeBase64InPlace(Span utf8Unescaped, out byte[] b return true; } - public static bool TryDecodeBase64(ReadOnlySpan utf8Unescaped, out byte[] bytes) + public static bool TryDecodeBase64(ReadOnlySpan utf8Unescaped, [NotNullWhen(true)] out byte[]? bytes) { - byte[] pooledArray = null; + byte[]? pooledArray = null; Span byteSpan = utf8Unescaped.Length <= JsonConstants.StackallocThreshold ? stackalloc byte[utf8Unescaped.Length] : diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.TryGet.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.TryGet.cs index 66e9701b5ab6fc..642d4a6db5f1bf 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.TryGet.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.TryGet.cs @@ -5,6 +5,7 @@ using System.Buffers; using System.Buffers.Text; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Text.Json { @@ -23,7 +24,7 @@ public ref partial struct Utf8JsonReader /// /// It will also throw when the JSON string contains invalid UTF-8 bytes, or invalid UTF-16 surrogates. /// - public string GetString() + public string? GetString() { if (TokenType == JsonTokenType.Null) { @@ -106,7 +107,7 @@ public bool GetBoolean() /// public byte[] GetBytesFromBase64() { - if (!TryGetBytesFromBase64(out byte[] value)) + if (!TryGetBytesFromBase64(out byte[]? value)) { throw ThrowHelper.GetFormatException(DataType.Base64String); } @@ -457,7 +458,7 @@ public Guid GetGuid() /// Thrown if trying to get the value of a JSON token that is not a . /// /// - public bool TryGetBytesFromBase64(out byte[] value) + public bool TryGetBytesFromBase64([NotNullWhen(true)] out byte[]? value) { if (TokenType != JsonTokenType.String) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.cs index cd1fe9bc2ddf97..517a5641c20051 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.cs @@ -458,7 +458,7 @@ public bool ValueTextEquals(ReadOnlySpan utf8Text) /// if required. The look up text is matched as is, without any modifications to it. /// /// - public bool ValueTextEquals(string text) + public bool ValueTextEquals(string? text) { return ValueTextEquals(text.AsSpan()); } @@ -511,7 +511,7 @@ public bool ValueTextEquals(ReadOnlySpan text) return false; } - byte[] otherUtf8TextArray = null; + byte[]? otherUtf8TextArray = null; Span otherUtf8Text; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultArrayConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultArrayConverter.cs index 529d5428ef68c2..a7e4602c1fb9af 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultArrayConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultArrayConverter.cs @@ -19,7 +19,7 @@ public override IEnumerable CreateFromList(ref ReadStack state, IList sourceList array = Array.CreateInstance(probe.GetType(), sourceList.Count); int i = 0; - foreach (IList child in sourceList) + foreach (IList? child in sourceList) { if (child is Array childArray) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultImmutableDictionaryConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultImmutableDictionaryConverter.cs index 57893d373d026d..b43a636e21f768 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultImmutableDictionaryConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultImmutableDictionaryConverter.cs @@ -28,11 +28,10 @@ public static void RegisterImmutableDictionary(Type immutableCollectionType, Typ } // Get the constructing type. - Type constructingType = underlyingType.Assembly.GetType(constructingTypeName); + Type constructingType = underlyingType.Assembly.GetType(constructingTypeName)!; // Create a delegate which will point to the CreateRange method. - ImmutableCollectionCreator createRangeDelegate; - createRangeDelegate = options.MemberAccessorStrategy.ImmutableDictionaryCreateRange(constructingType, immutableCollectionType, elementType); + ImmutableCollectionCreator? createRangeDelegate = options.MemberAccessorStrategy.ImmutableDictionaryCreateRange(constructingType, immutableCollectionType, elementType); // Cache the delegate options.TryAddCreateRangeDelegate(delegateKey, createRangeDelegate); @@ -58,9 +57,9 @@ public static bool IsImmutableDictionary(Type type) public override object CreateFromDictionary(ref ReadStack state, IDictionary sourceDictionary, JsonSerializerOptions options) { - Type immutableCollectionType = state.Current.JsonPropertyInfo.RuntimePropertyType; + Type immutableCollectionType = state.Current.JsonPropertyInfo!.RuntimePropertyType; - JsonClassInfo elementClassInfo = state.Current.JsonPropertyInfo.ElementClassInfo; + JsonClassInfo elementClassInfo = state.Current.JsonPropertyInfo.ElementClassInfo!; Type elementType = elementClassInfo.Type; string delegateKey = DefaultImmutableEnumerableConverter.GetDelegateKey(immutableCollectionType, elementType, out _, out _); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultImmutableEnumerableConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultImmutableEnumerableConverter.cs index 2ae8b2e3b9b8d9..fbf50b081a16c7 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultImmutableEnumerableConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultImmutableEnumerableConverter.cs @@ -92,11 +92,10 @@ public static void RegisterImmutableCollection(Type immutableCollectionType, Typ } // Get the constructing type. - Type constructingType = underlyingType.Assembly.GetType(constructingTypeName); + Type constructingType = underlyingType.Assembly.GetType(constructingTypeName)!; // Create a delegate which will point to the CreateRange method. - ImmutableCollectionCreator createRangeDelegate; - createRangeDelegate = options.MemberAccessorStrategy.ImmutableCollectionCreateRange(constructingType, immutableCollectionType, elementType); + ImmutableCollectionCreator? createRangeDelegate = options.MemberAccessorStrategy.ImmutableCollectionCreateRange(constructingType, immutableCollectionType, elementType); // Cache the delegate options.TryAddCreateRangeDelegate(delegateKey, createRangeDelegate); @@ -129,9 +128,9 @@ public static bool IsImmutableEnumerable(Type type) public override IEnumerable CreateFromList(ref ReadStack state, IList sourceList, JsonSerializerOptions options) { - Type immutableCollectionType = state.Current.JsonPropertyInfo.RuntimePropertyType; + Type immutableCollectionType = state.Current.JsonPropertyInfo!.RuntimePropertyType; - JsonClassInfo elementClassInfo = state.Current.JsonPropertyInfo.ElementClassInfo; + JsonClassInfo elementClassInfo = state.Current.JsonPropertyInfo.ElementClassInfo!; Type elementType = elementClassInfo.Type; string delegateKey = GetDelegateKey(immutableCollectionType, elementType, out _, out _); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonConverterEnum.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonConverterEnum.cs index d8e7aad387db98..2e7c0c63721c06 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonConverterEnum.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonConverterEnum.cs @@ -21,14 +21,14 @@ public override bool CanConvert(Type type) [PreserveDependency( ".ctor(System.Text.Json.Serialization.Converters.EnumConverterOptions)", "System.Text.Json.Serialization.Converters.JsonConverterEnum`1")] - public override JsonConverter CreateConverter(Type type, JsonSerializerOptions options) + public override JsonConverter CreateConverter(Type type, JsonSerializerOptions? options) { JsonConverter converter = (JsonConverter)Activator.CreateInstance( typeof(JsonConverterEnum<>).MakeGenericType(type), BindingFlags.Instance | BindingFlags.Public, binder: null, new object[] { EnumConverterOptions.AllowNumbers }, - culture: null); + culture: null)!; return converter; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonKeyValuePairConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonKeyValuePairConverter.cs index 8fa37cbfb586f3..1678c8ab844e59 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonKeyValuePairConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonKeyValuePairConverter.cs @@ -20,7 +20,7 @@ public override bool CanConvert(Type typeToConvert) } [PreserveDependency(".ctor()", "System.Text.Json.Serialization.Converters.JsonKeyValuePairConverter`2")] - public override JsonConverter CreateConverter(Type type, JsonSerializerOptions options) + public override JsonConverter CreateConverter(Type type, JsonSerializerOptions? options) { Type keyType = type.GetGenericArguments()[0]; Type valueType = type.GetGenericArguments()[1]; @@ -30,7 +30,7 @@ public override JsonConverter CreateConverter(Type type, JsonSerializerOptions o BindingFlags.Instance | BindingFlags.Public, binder: null, args: null, - culture: null); + culture: null)!; return converter; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterBoolean.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterBoolean.cs index 755f4a209e61df..0b2fd7705f02d5 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterBoolean.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterBoolean.cs @@ -6,12 +6,12 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class JsonConverterBoolean : JsonConverter { - public override bool Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override bool Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions? options) { return reader.GetBoolean(); } - public override void Write(Utf8JsonWriter writer, bool value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, bool value, JsonSerializerOptions? options) { writer.WriteBooleanValue(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterByte.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterByte.cs index b668fe41c237a4..8dc76d281e2924 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterByte.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterByte.cs @@ -6,12 +6,12 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class JsonConverterByte : JsonConverter { - public override byte Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override byte Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions? options) { return reader.GetByte(); } - public override void Write(Utf8JsonWriter writer, byte value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, byte value, JsonSerializerOptions? options) { writer.WriteNumberValue(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterByteArray.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterByteArray.cs index df478133610050..300eb8ebc3fc5c 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterByteArray.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterByteArray.cs @@ -6,12 +6,12 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class JsonConverterByteArray : JsonConverter { - public override byte[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override byte[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions? options) { return reader.GetBytesFromBase64(); } - public override void Write(Utf8JsonWriter writer, byte[] value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, byte[] value, JsonSerializerOptions? options) { writer.WriteBase64StringValue(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterChar.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterChar.cs index a7e7995f280e4d..101b145ba38ee3 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterChar.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterChar.cs @@ -8,12 +8,12 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class JsonConverterChar : JsonConverter { - public override char Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override char Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions? options) { - return reader.GetString()[0]; + return reader.GetString()![0]; } - public override void Write(Utf8JsonWriter writer, char value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, char value, JsonSerializerOptions? options) { writer.WriteStringValue( #if BUILDING_INBOX_LIBRARY diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterDateTime.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterDateTime.cs index cdd837f1ab8e6d..e3dafdf5f9c743 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterDateTime.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterDateTime.cs @@ -6,12 +6,12 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class JsonConverterDateTime : JsonConverter { - public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions? options) { return reader.GetDateTime(); } - public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions? options) { writer.WriteStringValue(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterDateTimeOffset.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterDateTimeOffset.cs index 268c164e907d11..785eb41ccf26bc 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterDateTimeOffset.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterDateTimeOffset.cs @@ -6,12 +6,12 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class JsonConverterDateTimeOffset : JsonConverter { - public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions? options) { return reader.GetDateTimeOffset(); } - public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions? options) { writer.WriteStringValue(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterDecimal.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterDecimal.cs index f951e39211e7fd..72cc177596aedc 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterDecimal.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterDecimal.cs @@ -6,12 +6,12 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class JsonConverterDecimal : JsonConverter { - public override decimal Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override decimal Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions? options) { return reader.GetDecimal(); } - public override void Write(Utf8JsonWriter writer, decimal value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, decimal value, JsonSerializerOptions? options) { writer.WriteNumberValue(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterDouble.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterDouble.cs index c53708d81e2cba..d74d65e5ee8e2c 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterDouble.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterDouble.cs @@ -6,12 +6,12 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class JsonConverterDouble : JsonConverter { - public override double Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override double Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions? options) { return reader.GetDouble(); } - public override void Write(Utf8JsonWriter writer, double value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, double value, JsonSerializerOptions? options) { writer.WriteNumberValue(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterEnum.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterEnum.cs index d7ab4e19c2e7a2..e9750db3c1420d 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterEnum.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterEnum.cs @@ -14,11 +14,11 @@ internal class JsonConverterEnum : JsonConverter private static readonly TypeCode s_enumTypeCode = Type.GetTypeCode(typeof(T)); // Odd type codes are conveniently signed types (for enum backing types). - private static readonly string s_negativeSign = ((int)s_enumTypeCode % 2) == 0 ? null : NumberFormatInfo.CurrentInfo.NegativeSign; + private static readonly string? s_negativeSign = ((int)s_enumTypeCode % 2) == 0 ? null : NumberFormatInfo.CurrentInfo.NegativeSign; private readonly EnumConverterOptions _converterOptions; private readonly JsonNamingPolicy _namingPolicy; - private readonly ConcurrentDictionary _nameCache; + private readonly ConcurrentDictionary? _nameCache; public override bool CanConvert(Type type) { @@ -30,7 +30,7 @@ public JsonConverterEnum(EnumConverterOptions options) { } - public JsonConverterEnum(EnumConverterOptions options, JsonNamingPolicy namingPolicy) + public JsonConverterEnum(EnumConverterOptions options, JsonNamingPolicy? namingPolicy) { _converterOptions = options; if (namingPolicy != null) @@ -44,7 +44,7 @@ public JsonConverterEnum(EnumConverterOptions options, JsonNamingPolicy namingPo _namingPolicy = namingPolicy; } - public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions? options) { JsonTokenType token = reader.TokenType; @@ -57,7 +57,7 @@ public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerial } // Try parsing case sensitive first - string enumString = reader.GetString(); + string? enumString = reader.GetString(); if (!Enum.TryParse(enumString, out T value) && !Enum.TryParse(enumString, ignoreCase: true, out value)) { @@ -152,13 +152,13 @@ private static bool IsValidIdentifier(string value) (s_negativeSign == null || !value.StartsWith(s_negativeSign))); } - public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions? options) { // If strings are allowed, attempt to write it out as a string value if (_converterOptions.HasFlag(EnumConverterOptions.AllowStrings)) { string original = value.ToString(); - if (_nameCache != null && _nameCache.TryGetValue(original, out string transformed)) + if (_nameCache != null && _nameCache.TryGetValue(original, out string? transformed)) { writer.WriteStringValue(transformed); return; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterGuid.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterGuid.cs index 379fcc33beba94..563d29b8b84fe5 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterGuid.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterGuid.cs @@ -6,12 +6,12 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class JsonConverterGuid : JsonConverter { - public override Guid Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override Guid Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions? options) { return reader.GetGuid(); } - public override void Write(Utf8JsonWriter writer, Guid value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, Guid value, JsonSerializerOptions? options) { writer.WriteStringValue(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterInt16.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterInt16.cs index 39d844feed31c0..a3587209a92f42 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterInt16.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterInt16.cs @@ -6,12 +6,12 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class JsonConverterInt16 : JsonConverter { - public override short Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override short Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions? options) { return reader.GetInt16(); } - public override void Write(Utf8JsonWriter writer, short value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, short value, JsonSerializerOptions? options) { writer.WriteNumberValue(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterInt32.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterInt32.cs index fb4e28de1bba97..72ee7bd349ffa0 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterInt32.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterInt32.cs @@ -6,12 +6,12 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class JsonConverterInt32 : JsonConverter { - public override int Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override int Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions? options) { return reader.GetInt32(); } - public override void Write(Utf8JsonWriter writer, int value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, int value, JsonSerializerOptions? options) { writer.WriteNumberValue(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterInt64.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterInt64.cs index 6f82397be872ed..96f14678487070 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterInt64.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterInt64.cs @@ -6,12 +6,12 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class JsonConverterInt64 : JsonConverter { - public override long Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override long Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions? options) { return reader.GetInt64(); } - public override void Write(Utf8JsonWriter writer, long value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, long value, JsonSerializerOptions? options) { writer.WriteNumberValue(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterJsonElement.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterJsonElement.cs index b8a4da3efca796..d7c933c97eab29 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterJsonElement.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterJsonElement.cs @@ -6,7 +6,7 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class JsonConverterJsonElement : JsonConverter { - public override JsonElement Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override JsonElement Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions? options) { using (JsonDocument document = JsonDocument.ParseValue(ref reader)) { @@ -14,7 +14,7 @@ public override JsonElement Read(ref Utf8JsonReader reader, Type typeToConvert, } } - public override void Write(Utf8JsonWriter writer, JsonElement value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, JsonElement value, JsonSerializerOptions? options) { value.WriteTo(writer); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterKeyValuePair.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterKeyValuePair.cs index ff9fe09bfa61b0..c148c0fcbcf072 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterKeyValuePair.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterKeyValuePair.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -17,17 +18,17 @@ internal sealed class JsonKeyValuePairConverter : JsonConverter Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override KeyValuePair Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions? options) { if (reader.TokenType != JsonTokenType.StartObject) { ThrowHelper.ThrowJsonException(); } - TKey k = default; + TKey k = default!; bool keySet = false; - TValue v = default; + TValue v = default!; bool valueSet = false; // Get the first property. @@ -37,7 +38,7 @@ public override KeyValuePair Read(ref Utf8JsonReader reader, Type ThrowHelper.ThrowJsonException(); } - string propertyName = reader.GetString(); + string? propertyName = reader.GetString(); if (propertyName == KeyName) { k = ReadProperty(ref reader, typeToConvert, options); @@ -91,7 +92,7 @@ public override KeyValuePair Read(ref Utf8JsonReader reader, Type return new KeyValuePair(k, v); } - private T ReadProperty(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + private T ReadProperty(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions? options) { T k; @@ -110,7 +111,7 @@ private T ReadProperty(ref Utf8JsonReader reader, Type typeToConvert, JsonSer return k; } - private void WriteProperty(Utf8JsonWriter writer, T value, JsonEncodedText name, JsonSerializerOptions options) + private void WriteProperty(Utf8JsonWriter writer, T value, JsonEncodedText name, JsonSerializerOptions? options) { Type typeToConvert = typeof(T); @@ -128,7 +129,7 @@ private void WriteProperty(Utf8JsonWriter writer, T value, JsonEncodedText na } } - public override void Write(Utf8JsonWriter writer, KeyValuePair value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, KeyValuePair value, JsonSerializerOptions? options) { writer.WriteStartObject(); WriteProperty(writer, value.Key, _keyName, options); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterObject.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterObject.cs index 27a361ebae7824..e180ca3e70b9d3 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterObject.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterObject.cs @@ -6,7 +6,7 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class JsonConverterObject : JsonConverter { - public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions? options) { using (JsonDocument document = JsonDocument.ParseValue(ref reader)) { @@ -14,7 +14,7 @@ public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonS } } - public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions? options) { throw new InvalidOperationException(); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterSByte.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterSByte.cs index 239dbbd44f83d5..22a76d1d0abd56 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterSByte.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterSByte.cs @@ -6,12 +6,12 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class JsonConverterSByte : JsonConverter { - public override sbyte Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override sbyte Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions? options) { return reader.GetSByte(); } - public override void Write(Utf8JsonWriter writer, sbyte value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, sbyte value, JsonSerializerOptions? options) { writer.WriteNumberValue(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterSingle.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterSingle.cs index ba5a3a16965753..5646da702219c5 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterSingle.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterSingle.cs @@ -6,12 +6,12 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class JsonConverterSingle : JsonConverter { - public override float Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override float Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions? options) { return reader.GetSingle(); } - public override void Write(Utf8JsonWriter writer, float value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, float value, JsonSerializerOptions? options) { writer.WriteNumberValue(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterString.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterString.cs index e3a9b705ed9c24..2aaf3c10c8755b 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterString.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterString.cs @@ -4,14 +4,14 @@ namespace System.Text.Json.Serialization.Converters { - internal sealed class JsonConverterString : JsonConverter + internal sealed class JsonConverterString : JsonConverter { - public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override string? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions? options) { return reader.GetString(); } - public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, string? value, JsonSerializerOptions? options) { writer.WriteStringValue(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterUInt16.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterUInt16.cs index 4939aff78b288c..2940f2ea906d18 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterUInt16.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterUInt16.cs @@ -6,12 +6,12 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class JsonConverterUInt16 : JsonConverter { - public override ushort Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override ushort Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions? options) { return reader.GetUInt16(); } - public override void Write(Utf8JsonWriter writer, ushort value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, ushort value, JsonSerializerOptions? options) { writer.WriteNumberValue(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterUInt32.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterUInt32.cs index c9edf4f77889f5..86a0a8ac5772eb 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterUInt32.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterUInt32.cs @@ -6,12 +6,12 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class JsonConverterUInt32 : JsonConverter { - public override uint Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override uint Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions? options) { return reader.GetUInt32(); } - public override void Write(Utf8JsonWriter writer, uint value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, uint value, JsonSerializerOptions? options) { writer.WriteNumberValue(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterUInt64.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterUInt64.cs index 4bb14140987e44..4f5d6eb4929440 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterUInt64.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterUInt64.cs @@ -6,12 +6,12 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class JsonConverterUInt64 : JsonConverter { - public override ulong Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override ulong Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions? options) { return reader.GetUInt64(); } - public override void Write(Utf8JsonWriter writer, ulong value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, ulong value, JsonSerializerOptions? options) { writer.WriteNumberValue(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterUri.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterUri.cs index a819050909c2cc..2d75f1ad0b0689 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterUri.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterUri.cs @@ -2,14 +2,16 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Diagnostics; + namespace System.Text.Json.Serialization.Converters { internal sealed class JsonConverterUri : JsonConverter { - public override Uri Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override Uri Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions? options) { - string uriString = reader.GetString(); - if (Uri.TryCreate(uriString, UriKind.RelativeOrAbsolute, out Uri value)) + string? uriString = reader.GetString(); + if (Uri.TryCreate(uriString, UriKind.RelativeOrAbsolute, out Uri? value)) { return value; } @@ -18,7 +20,7 @@ public override Uri Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSeri return null; } - public override void Write(Utf8JsonWriter writer, Uri value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, Uri value, JsonSerializerOptions? options) { writer.WriteStringValue(value.OriginalString); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ImmutableCollectionCreator.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ImmutableCollectionCreator.cs index efdfb1809ad941..559dde962aa1f3 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ImmutableCollectionCreator.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ImmutableCollectionCreator.cs @@ -5,6 +5,7 @@ using System.Collections; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Reflection; namespace System.Text.Json @@ -12,14 +13,14 @@ namespace System.Text.Json internal abstract class ImmutableCollectionCreator { public abstract void RegisterCreatorDelegateFromMethod(MethodInfo creator); - public abstract bool CreateImmutableEnumerable(IList items, out IEnumerable collection); - public abstract bool CreateImmutableDictionary(IDictionary items, out IDictionary collection); + public abstract bool CreateImmutableEnumerable(IList items, [NotNullWhen(true)] out IEnumerable? collection); + public abstract bool CreateImmutableDictionary(IDictionary items, [NotNullWhen(true)] out IDictionary? collection); } internal sealed class ImmutableEnumerableCreator : ImmutableCollectionCreator where TCollection : IEnumerable { - private Func, TCollection> _creatorDelegate; + private Func, TCollection>? _creatorDelegate; public override void RegisterCreatorDelegateFromMethod(MethodInfo creator) { @@ -34,7 +35,7 @@ public override bool CreateImmutableEnumerable(IList items, out IEnumerable coll return true; } - public override bool CreateImmutableDictionary(IDictionary items, out IDictionary collection) + public override bool CreateImmutableDictionary(IDictionary items, out IDictionary? collection) { // Shouldn't be calling this method for immutable dictionaries. collection = default; @@ -43,9 +44,9 @@ public override bool CreateImmutableDictionary(IDictionary items, out IDictionar private IEnumerable CreateGenericTElementIEnumerable(IList sourceList) { - foreach (object item in sourceList) + foreach (object? item in sourceList) { - yield return (TElement)item; + yield return (TElement)item!; } } } @@ -53,7 +54,7 @@ private IEnumerable CreateGenericTElementIEnumerable(IList sourceList) internal sealed class ImmutableDictionaryCreator : ImmutableCollectionCreator where TCollection : IReadOnlyDictionary { - private Func>, TCollection> _creatorDelegate; + private Func>, TCollection>? _creatorDelegate; public override void RegisterCreatorDelegateFromMethod(MethodInfo creator) { @@ -62,7 +63,7 @@ public override void RegisterCreatorDelegateFromMethod(MethodInfo creator) typeof(Func>, TCollection>)); } - public override bool CreateImmutableEnumerable(IList items, out IEnumerable collection) + public override bool CreateImmutableEnumerable(IList items, out IEnumerable? collection) { // Shouldn't be calling this method for immutable non-dictionaries. collection = default; @@ -78,9 +79,11 @@ public override bool CreateImmutableDictionary(IDictionary items, out IDictionar private IEnumerable> CreateGenericTElementIDictionary(IDictionary sourceDictionary) { +#pragma warning disable 8605 foreach (DictionaryEntry item in sourceDictionary) +#pragma warning restore 8605 { - yield return new KeyValuePair((string)item.Key, (TElement)item.Value); + yield return new KeyValuePair((string)item.Key, (TElement)item.Value!); } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonCamelCaseNamingPolicy.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonCamelCaseNamingPolicy.cs index 172d45d8e50c70..76c9d53ab065da 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonCamelCaseNamingPolicy.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonCamelCaseNamingPolicy.cs @@ -2,11 +2,14 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Diagnostics.CodeAnalysis; + namespace System.Text.Json { internal sealed class JsonCamelCaseNamingPolicy : JsonNamingPolicy { - public override string ConvertName(string name) + [return: NotNullIfNotNull("name")] + public override string? ConvertName(string? name) { if (string.IsNullOrEmpty(name) || !char.IsUpper(name[0])) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.AddProperty.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.AddProperty.cs index 7337db0f24c8a8..fb91bafd4e78ea 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.AddProperty.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.AddProperty.cs @@ -26,10 +26,10 @@ private JsonPropertyInfo AddProperty(Type propertyType, PropertyInfo propertyInf parentClassType, propertyInfo, out Type runtimeType, - out Type elementType, - out Type nullableUnderlyingType, + out Type? elementType, + out Type? nullableUnderlyingType, out _, - out JsonConverter converter, + out JsonConverter? converter, checkForAddMethod: false, options); @@ -50,11 +50,11 @@ private JsonPropertyInfo AddProperty(Type propertyType, PropertyInfo propertyInf internal static JsonPropertyInfo CreateProperty( Type declaredPropertyType, Type runtimePropertyType, - PropertyInfo propertyInfo, + PropertyInfo? propertyInfo, Type parentClassType, - Type collectionElementType, - Type nullableUnderlyingType, - JsonConverter converter, + Type? collectionElementType, + Type? nullableUnderlyingType, + JsonConverter? converter, ClassType classType, JsonSerializerOptions options) { @@ -65,11 +65,11 @@ internal static JsonPropertyInfo CreateProperty( if (treatAsNullable && converter != null) { - propertyInfoClassType = typeof(JsonPropertyInfoNullable<,>).MakeGenericType(parentClassType, nullableUnderlyingType); + propertyInfoClassType = typeof(JsonPropertyInfoNullable<,>).MakeGenericType(parentClassType, nullableUnderlyingType!); } else { - Type typeToConvert = converter?.TypeToConvert; + Type? typeToConvert = converter?.TypeToConvert; if (typeToConvert == null) { typeToConvert = declaredPropertyType; @@ -103,7 +103,7 @@ internal static JsonPropertyInfo CreateProperty( BindingFlags.Instance | BindingFlags.Public, binder: null, args: null, - culture: null); + culture: null)!; jsonPropertyInfo.Initialize( parentClassType, @@ -128,9 +128,9 @@ internal static JsonPropertyInfo CreateProperty( internal static JsonPropertyInfo CreatePolicyProperty( Type declaredPropertyType, Type runtimePropertyType, - Type elementType, - Type nullableUnderlyingType, - JsonConverter converter, + Type? elementType, + Type? nullableUnderlyingType, + JsonConverter? converter, ClassType classType, JsonSerializerOptions options) { @@ -151,7 +151,7 @@ internal static JsonPropertyInfo CreatePolicyProperty( /// internal JsonPropertyInfo CreateRootProperty(JsonSerializerOptions options) { - JsonConverter converter = options.DetermineConverterForProperty(Type, Type, propertyInfo: null); + JsonConverter? converter = options.DetermineConverterForProperty(Type, Type, propertyInfo: null); return CreateProperty( declaredPropertyType: Type, @@ -174,10 +174,10 @@ static JsonPropertyInfo CreateRuntimeProperty((JsonPropertyInfo property, Type r arg.classType, key.property.PropertyInfo, out _, - out Type elementType, - out Type nullableType, + out Type? elementType, + out Type? nullableType, out _, - out JsonConverter converter, + out JsonConverter? converter, checkForAddMethod: false, arg.options); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs index 1b0dcdd38bbf58..5ee457a7fd095c 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs @@ -6,6 +6,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -25,28 +26,28 @@ internal sealed partial class JsonClassInfo private const int PropertyNameCountCacheThreshold = 64; // All of the serializable properties on a POCO (except the optional extension property) keyed on property name. - public volatile Dictionary PropertyCache; + public volatile Dictionary? PropertyCache; // Serializable runtime/polymorphic properties, keyed on property and runtime type. - public ConcurrentDictionary<(JsonPropertyInfo, Type), JsonPropertyInfo> RuntimePropertyCache; + public ConcurrentDictionary<(JsonPropertyInfo, Type), JsonPropertyInfo>? RuntimePropertyCache; // All of the serializable properties on a POCO including the optional extension property. // Used for performance during serialization instead of 'PropertyCache' above. - public volatile JsonPropertyInfo[] PropertyCacheArray; + public volatile JsonPropertyInfo[]? PropertyCacheArray; // Fast cache of properties by first JSON ordering; may not contain all properties. Accessed before PropertyCache. // Use an array (instead of List) for highest performance. - private volatile PropertyRef[] _propertyRefsSorted; + private volatile PropertyRef[]? _propertyRefsSorted; - public delegate object ConstructorDelegate(); - public ConstructorDelegate CreateObject { get; private set; } + public delegate object? ConstructorDelegate(); + public ConstructorDelegate? CreateObject { get; private set; } public ClassType ClassType { get; private set; } - public JsonPropertyInfo DataExtensionProperty { get; private set; } + public JsonPropertyInfo? DataExtensionProperty { get; private set; } // If enumerable, the JsonClassInfo for the element type. - private JsonClassInfo _elementClassInfo; + private JsonClassInfo? _elementClassInfo; /// /// Return the JsonClassInfo for the element type, or null if the type is not an enumerable or dictionary. @@ -55,7 +56,7 @@ internal sealed partial class JsonClassInfo /// This should not be called during warm-up (initial creation of JsonClassInfos) to avoid recursive behavior /// which could result in a StackOverflowException. /// - public JsonClassInfo ElementClassInfo + public JsonClassInfo? ElementClassInfo { get { @@ -71,7 +72,7 @@ public JsonClassInfo ElementClassInfo } } - public Type ElementType { get; set; } + public Type? ElementType { get; set; } public JsonSerializerOptions Options { get; private set; } @@ -123,10 +124,10 @@ public JsonClassInfo(Type type, JsonSerializerOptions options) parentClassType: type, propertyInfo: null, out Type runtimeType, - out Type elementType, - out Type nullableUnderlyingType, - out MethodInfo addMethod, - out JsonConverter converter, + out Type? elementType, + out Type? nullableUnderlyingType, + out MethodInfo? addMethod, + out JsonConverter? converter, checkForAddMethod: true, options); @@ -154,10 +155,10 @@ public JsonClassInfo(Type type, JsonSerializerOptions options) propertyInfo.SetMethod?.IsPublic == true) { JsonPropertyInfo jsonPropertyInfo = AddProperty(propertyInfo.PropertyType, propertyInfo, type, options); - Debug.Assert(jsonPropertyInfo != null); + Debug.Assert(jsonPropertyInfo != null && jsonPropertyInfo.NameAsString != null); // If the JsonPropertyNameAttribute or naming policy results in collisions, throw an exception. - if (!JsonHelpers.TryAdd(cache, jsonPropertyInfo.NameAsString, jsonPropertyInfo)) + if (!JsonHelpers.TryAdd(cache, jsonPropertyInfo.NameAsString!, jsonPropertyInfo)) { JsonPropertyInfo other = cache[jsonPropertyInfo.NameAsString]; @@ -179,7 +180,7 @@ public JsonClassInfo(Type type, JsonSerializerOptions options) if (DetermineExtensionDataProperty(cache)) { // Remove from cache since it is handled independently. - cache.Remove(DataExtensionProperty.NameAsString); + cache.Remove(DataExtensionProperty!.NameAsString!); cacheArray = new JsonPropertyInfo[cache.Count + 1]; @@ -228,7 +229,7 @@ public JsonClassInfo(Type type, JsonSerializerOptions options) private bool DetermineExtensionDataProperty(Dictionary cache) { - JsonPropertyInfo jsonPropertyInfo = GetPropertyWithUniqueAttribute(typeof(JsonExtensionDataAttribute), cache); + JsonPropertyInfo? jsonPropertyInfo = GetPropertyWithUniqueAttribute(typeof(JsonExtensionDataAttribute), cache); if (jsonPropertyInfo != null) { Type declaredPropertyType = jsonPropertyInfo.DeclaredPropertyType; @@ -245,13 +246,14 @@ private bool DetermineExtensionDataProperty(Dictionary return false; } - private JsonPropertyInfo GetPropertyWithUniqueAttribute(Type attributeType, Dictionary cache) + private JsonPropertyInfo? GetPropertyWithUniqueAttribute(Type attributeType, Dictionary cache) { - JsonPropertyInfo property = null; + JsonPropertyInfo? property = null; foreach (JsonPropertyInfo jsonPropertyInfo in cache.Values) { - Attribute attribute = jsonPropertyInfo.PropertyInfo.GetCustomAttribute(attributeType); + Debug.Assert(jsonPropertyInfo.PropertyInfo != null); + Attribute? attribute = jsonPropertyInfo.PropertyInfo.GetCustomAttribute(attributeType); if (attribute != null) { if (property != null) @@ -270,10 +272,10 @@ private JsonPropertyInfo GetPropertyWithUniqueAttribute(Type attributeType, Dict [MethodImpl(MethodImplOptions.AggressiveInlining)] public JsonPropertyInfo GetProperty(ReadOnlySpan propertyName, ref ReadStackFrame frame) { - JsonPropertyInfo info = null; + JsonPropertyInfo? info = null; // Keep a local copy of the cache in case it changes by another thread. - PropertyRef[] localPropertyRefsSorted = _propertyRefsSorted; + PropertyRef[]? localPropertyRefsSorted = _propertyRefsSorted; ulong key = GetKey(propertyName); @@ -396,12 +398,12 @@ private Dictionary CreatePropertyCache(int capacity) return new Dictionary(capacity, comparer); } - public JsonPropertyInfo PolicyProperty { get; private set; } + public JsonPropertyInfo? PolicyProperty { get; private set; } - public MethodInfo AddItemToObject { get; private set; } + public MethodInfo? AddItemToObject { get; private set; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool TryIsPropertyRefEqual(in PropertyRef propertyRef, ReadOnlySpan propertyName, ulong key, ref JsonPropertyInfo info) + private static bool TryIsPropertyRefEqual(in PropertyRef propertyRef, ReadOnlySpan propertyName, ulong key, [NotNullWhen(true)] ref JsonPropertyInfo? info) { if (key == propertyRef.Key) { @@ -519,12 +521,12 @@ public static ulong GetKey(ReadOnlySpan propertyName) public static ClassType GetClassType( Type type, Type parentClassType, - PropertyInfo propertyInfo, + PropertyInfo? propertyInfo, out Type runtimeType, - out Type elementType, - out Type nullableUnderlyingType, - out MethodInfo addMethod, - out JsonConverter converter, + out Type? elementType, + out Type? nullableUnderlyingType, + out MethodInfo? addMethod, + out JsonConverter? converter, bool checkForAddMethod, JsonSerializerOptions options) { @@ -582,7 +584,7 @@ public static ClassType GetClassType( return ClassType.Enumerable; } - if (type.FullName.StartsWith("System.Collections.Generic.IEnumerable`1")) + if (type.FullName!.StartsWith("System.Collections.Generic.IEnumerable`1")) { elementType = type.GetGenericArguments()[0]; runtimeType = typeof(List<>).MakeGenericType(elementType); @@ -601,7 +603,7 @@ public static ClassType GetClassType( } { - Type genericIDictionaryType = type.GetInterface("System.Collections.Generic.IDictionary`2") ?? type.GetInterface("System.Collections.Generic.IReadOnlyDictionary`2"); + Type? genericIDictionaryType = type.GetInterface("System.Collections.Generic.IDictionary`2") ?? type.GetInterface("System.Collections.Generic.IReadOnlyDictionary`2"); if (genericIDictionaryType != null) { Type[] genericTypes = genericIDictionaryType.GetGenericArguments(); @@ -641,7 +643,7 @@ public static ClassType GetClassType( } { - Type genericIEnumerableType = type.GetInterface("System.Collections.Generic.IEnumerable`1"); + Type? genericIEnumerableType = type.GetInterface("System.Collections.Generic.IEnumerable`1"); if (genericIEnumerableType != null) { @@ -690,7 +692,7 @@ public static ClassType GetClassType( if (checkForAddMethod) { - Type genericICollectionType = type.GetInterface("System.Collections.Generic.ICollection`1"); + Type? genericICollectionType = type.GetInterface("System.Collections.Generic.ICollection`1"); if (genericICollectionType != null) { addMethod = genericICollectionType.GetMethod("Add"); @@ -698,7 +700,7 @@ public static ClassType GetClassType( else { // Non-immutable stack or queue. - MethodInfo methodInfo = type.GetMethod("Push") ?? type.GetMethod("Enqueue"); + MethodInfo? methodInfo = type.GetMethod("Push") ?? type.GetMethod("Enqueue"); if (methodInfo?.ReturnType == typeof(void)) { addMethod = methodInfo; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverter.cs index 1bee8212319922..ea06f03a3a42ad 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverter.cs @@ -19,6 +19,6 @@ internal JsonConverter() { } public abstract bool CanConvert(Type typeToConvert); // This is used internally to quickly determine the type being converted for JsonConverter. - internal virtual Type TypeToConvert => null; + internal virtual Type? TypeToConvert => null; } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterAttribute.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterAttribute.cs index 2d0573a809d488..51095cd5c7b125 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterAttribute.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterAttribute.cs @@ -34,7 +34,7 @@ protected JsonConverterAttribute() { } /// /// The type of the converter to create, or null if should be used to obtain the converter. /// - public Type ConverterType { get; private set; } + public Type? ConverterType { get; private set; } /// /// If overridden and is null, allows a custom attribute to create the converter in order to pass additional state. @@ -42,7 +42,7 @@ protected JsonConverterAttribute() { } /// /// The custom converter. /// - public virtual JsonConverter CreateConverter(Type typeToConvert) + public virtual JsonConverter? CreateConverter(Type typeToConvert) { return null; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterFactory.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterFactory.cs index 35cdd393d674e2..e03b8894419c42 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterFactory.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterFactory.cs @@ -19,7 +19,7 @@ public abstract class JsonConverterFactory : JsonConverter /// protected JsonConverterFactory() { } - internal JsonConverter GetConverterInternal(Type typeToConvert, JsonSerializerOptions options) + internal JsonConverter GetConverterInternal(Type typeToConvert, JsonSerializerOptions? options) { Debug.Assert(CanConvert(typeToConvert)); return CreateConverter(typeToConvert, options); @@ -33,6 +33,6 @@ internal JsonConverter GetConverterInternal(Type typeToConvert, JsonSerializerOp /// /// An instance of a where T is compatible with . /// - public abstract JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options); + public abstract JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions? options); } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs index df8577a2d3e6bf..b188b84a1b5e7c 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs @@ -38,7 +38,7 @@ public override bool CanConvert(Type typeToConvert) /// The being converted. /// The being used. /// The value that was converted. - public abstract T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options); + public abstract T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions? options); /// /// Write the value as JSON. @@ -50,7 +50,7 @@ public override bool CanConvert(Type typeToConvert) /// The to write to. /// The value to convert. /// The being used. - public abstract void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options); + public abstract void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions? options); internal override Type TypeToConvert => typeof(T); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonDefaultNamingPolicy.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonDefaultNamingPolicy.cs index 0f56d4001439e1..3f7dec4f499dee 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonDefaultNamingPolicy.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonDefaultNamingPolicy.cs @@ -2,10 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Diagnostics.CodeAnalysis; + namespace System.Text.Json { internal class JsonDefaultNamingPolicy : JsonNamingPolicy { - public override string ConvertName(string name) => name; + [return: NotNullIfNotNull("name")] + public override string? ConvertName(string? name) => name; } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonNamingPolicy.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonNamingPolicy.cs index 00c2f55b2e243b..c2ab8ed3183f6d 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonNamingPolicy.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonNamingPolicy.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Diagnostics.CodeAnalysis; + namespace System.Text.Json { /// @@ -26,6 +28,7 @@ protected JsonNamingPolicy() { } /// /// The name to convert. /// The converted name. - public abstract string ConvertName(string name); + [return: NotNullIfNotNull("name")] + public abstract string? ConvertName(string? name); } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfo.cs index d9c378e2931cea..9a178824a420f3 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfo.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfo.cs @@ -4,6 +4,7 @@ using System.Collections; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Text.Json.Serialization; using System.Text.Json.Serialization.Converters; @@ -20,17 +21,18 @@ internal abstract class JsonPropertyInfo public static readonly JsonPropertyInfo s_missingProperty = GetMissingProperty(); - private JsonClassInfo _elementClassInfo; - private JsonClassInfo _runtimeClassInfo; - private JsonClassInfo _declaredTypeClassInfo; + private JsonClassInfo? _elementClassInfo; + private JsonClassInfo? _runtimeClassInfo; + private JsonClassInfo? _declaredTypeClassInfo; - private JsonPropertyInfo _dictionaryValuePropertyPolicy; + private JsonPropertyInfo? _dictionaryValuePropertyPolicy; public bool CanBeNull { get; private set; } public ClassType ClassType; - public abstract JsonConverter ConverterBase { get; set; } + [DisallowNull] + public abstract JsonConverter? ConverterBase { get; set; } private static JsonPropertyInfo GetMissingProperty() { @@ -60,7 +62,7 @@ public void CopyRuntimeSettingsTo(JsonPropertyInfo other) // Create a property that is ignored at run-time. It uses the same type (typeof(sbyte)) to help // prevent issues with unsupported types and helps ensure we don't accidently (de)serialize it. - public static JsonPropertyInfo CreateIgnoredPropertyPlaceholder(PropertyInfo propertyInfo, JsonSerializerOptions options) + public static JsonPropertyInfo CreateIgnoredPropertyPlaceholder(PropertyInfo? propertyInfo, JsonSerializerOptions options) { JsonPropertyInfo jsonPropertyInfo = new JsonPropertyInfoNotNullable(); jsonPropertyInfo.Options = options; @@ -73,7 +75,7 @@ public static JsonPropertyInfo CreateIgnoredPropertyPlaceholder(PropertyInfo pro return jsonPropertyInfo; } - public Type DeclaredPropertyType { get; private set; } + public Type DeclaredPropertyType { get; private set; } = null!; private void DeterminePropertyName() { @@ -82,7 +84,7 @@ private void DeterminePropertyName() return; } - JsonPropertyNameAttribute nameAttribute = GetAttribute(PropertyInfo); + JsonPropertyNameAttribute? nameAttribute = GetAttribute(PropertyInfo); if (nameAttribute != null) { string name = nameAttribute.Name; @@ -95,7 +97,7 @@ private void DeterminePropertyName() } else if (Options.PropertyNamingPolicy != null) { - string name = Options.PropertyNamingPolicy.ConvertName(PropertyInfo.Name); + string? name = Options.PropertyNamingPolicy.ConvertName(PropertyInfo.Name); if (name == null) { ThrowHelper.ThrowInvalidOperationException_SerializerPropertyNameNull(ParentClassType, this); @@ -152,11 +154,13 @@ private void DetermineSerializationCapabilities() } else if (ClassType == ClassType.Dictionary && DefaultImmutableDictionaryConverter.IsImmutableDictionary(RuntimePropertyType)) { + Debug.Assert(ElementType != null); DefaultImmutableDictionaryConverter.RegisterImmutableDictionary(RuntimePropertyType, ElementType, Options); DictionaryConverter = s_jsonImmutableDictionaryConverter; } else if (ClassType == ClassType.Enumerable && DefaultImmutableEnumerableConverter.IsImmutableEnumerable(RuntimePropertyType)) { + Debug.Assert(ElementType != null); DefaultImmutableEnumerableConverter.RegisterImmutableCollection(RuntimePropertyType, ElementType, Options); EnumerableConverter = s_jsonImmutableEnumerableConverter; } @@ -183,9 +187,9 @@ public JsonPropertyInfo DictionaryValuePropertyPolicy if (_dictionaryValuePropertyPolicy == null) { // Use the existing PolicyProperty if there is one. - if ((_dictionaryValuePropertyPolicy = ElementClassInfo.PolicyProperty) == null) + if ((_dictionaryValuePropertyPolicy = ElementClassInfo!.PolicyProperty) == null) { - Type dictionaryValueType = ElementType; + Type? dictionaryValueType = ElementType; Debug.Assert(dictionaryValueType != null); _dictionaryValuePropertyPolicy = JsonClassInfo.CreatePolicyProperty( @@ -210,7 +214,7 @@ public JsonPropertyInfo DictionaryValuePropertyPolicy /// This should not be called during warm-up (initial creation of JsonClassInfos) to avoid recursive behavior /// which could result in a StackOverflowException. /// - public JsonClassInfo ElementClassInfo + public JsonClassInfo? ElementClassInfo { get { @@ -225,23 +229,23 @@ public JsonClassInfo ElementClassInfo } } - public Type ElementType { get; set; } + public Type? ElementType { get; set; } - public JsonEnumerableConverter EnumerableConverter { get; private set; } - public JsonDictionaryConverter DictionaryConverter { get; private set; } + public JsonEnumerableConverter? EnumerableConverter { get; private set; } + public JsonDictionaryConverter? DictionaryConverter { get; private set; } // The escaped name passed to the writer. // Use a field here (not a property) to avoid value semantics. public JsonEncodedText? EscapedName; - public static TAttribute GetAttribute(PropertyInfo propertyInfo) where TAttribute : Attribute + public static TAttribute? GetAttribute(PropertyInfo? propertyInfo) where TAttribute : Attribute { - return (TAttribute)propertyInfo?.GetCustomAttribute(typeof(TAttribute), inherit: false); + return (TAttribute?)propertyInfo?.GetCustomAttribute(typeof(TAttribute), inherit: false); } public abstract Type GetDictionaryConcreteType(); - public void GetDictionaryKeyAndValue(ref WriteStackFrame writeStackFrame, out string key, out object value) + public void GetDictionaryKeyAndValue(ref WriteStackFrame writeStackFrame, out string key, out object? value) { Debug.Assert(ClassType == ClassType.Dictionary); @@ -256,7 +260,7 @@ public void GetDictionaryKeyAndValue(ref WriteStackFrame writeStackFrame, out st else { throw ThrowHelper.GetNotSupportedException_SerializationNotSupportedCollection( - writeStackFrame.JsonPropertyInfo.DeclaredPropertyType, + writeStackFrame.JsonPropertyInfo!.DeclaredPropertyType, writeStackFrame.JsonPropertyInfo.ParentClassType, writeStackFrame.JsonPropertyInfo.PropertyInfo); } @@ -268,7 +272,7 @@ public void GetDictionaryKeyAndValue(ref WriteStackFrame writeStackFrame, out st } } - public abstract void GetDictionaryKeyAndValueFromGenericDictionary(ref WriteStackFrame writeStackFrame, out string key, out object value); + public abstract void GetDictionaryKeyAndValueFromGenericDictionary(ref WriteStackFrame writeStackFrame, out string key, out object? value); public virtual void GetPolicies() { @@ -277,7 +281,7 @@ public virtual void GetPolicies() IgnoreNullValues = Options.IgnoreNullValues; } - public abstract object GetValueAsObject(object obj); + public abstract object? GetValueAsObject(object? obj); public bool HasGetter { get; set; } public bool HasSetter { get; set; } @@ -289,9 +293,9 @@ public virtual void Initialize( Type declaredPropertyType, Type runtimePropertyType, ClassType runtimeClassType, - PropertyInfo propertyInfo, - Type elementType, - JsonConverter converter, + PropertyInfo? propertyInfo, + Type? elementType, + JsonConverter? converter, bool treatAsNullable, JsonSerializerOptions options) { @@ -312,17 +316,17 @@ public virtual void Initialize( } } - public abstract bool TryCreateEnumerableAddMethod(object target, out object addMethodDelegate); + public abstract bool TryCreateEnumerableAddMethod(object target, [NotNullWhen(true)] out object? addMethodDelegate); - public abstract object CreateEnumerableAddMethod(MethodInfo addMethod, object target); + public abstract object? CreateEnumerableAddMethod(MethodInfo addMethod, object target); - public abstract void AddObjectToEnumerableWithReflection(object addMethodDelegate, object value); + public abstract void AddObjectToEnumerableWithReflection(object addMethodDelegate, object? value); - public abstract void AddObjectToParentEnumerable(object addMethodDelegate, object value); + public abstract void AddObjectToParentEnumerable(object addMethodDelegate, object? value); - public abstract void AddObjectToDictionary(object target, string key, object value); + public abstract void AddObjectToDictionary(object target, string key, object? value); - public abstract void AddObjectToParentDictionary(object target, string key, object value); + public abstract void AddObjectToParentDictionary(object target, string key, object? value); public abstract bool CanPopulateDictionary(object target); @@ -333,17 +337,17 @@ public virtual void Initialize( public bool IsPropertyPolicy { get; protected set; } // The name from a Json value. This is cached for performance on first deserialize. - public byte[] JsonPropertyName { get; set; } + public byte[]? JsonPropertyName { get; set; } // The name of the property with any casing policy or the name specified from JsonPropertyNameAttribute. - public byte[] Name { get; private set; } - public string NameAsString { get; private set; } + public byte[]? Name { get; private set; } + public string? NameAsString { get; private set; } // Key for fast property name lookup. public ulong PropertyNameKey { get; set; } // Options can be referenced here since all JsonPropertyInfos originate from a JsonClassInfo that is cached on JsonSerializerOptions. - protected JsonSerializerOptions Options { get; set; } + protected JsonSerializerOptions Options { get; set; } = null!; // initialized in Init method protected abstract void OnRead(ref ReadStack state, ref Utf8JsonReader reader); protected abstract void OnReadEnumerable(ref ReadStack state, ref Utf8JsonReader reader); @@ -351,16 +355,16 @@ public virtual void Initialize( protected virtual void OnWriteDictionary(ref WriteStackFrame current, Utf8JsonWriter writer) { } protected abstract void OnWriteEnumerable(ref WriteStackFrame current, Utf8JsonWriter writer); - public Type ParentClassType { get; private set; } + public Type? ParentClassType { get; private set; } - public PropertyInfo PropertyInfo { get; private set; } + public PropertyInfo? PropertyInfo { get; private set; } public void Read(JsonTokenType tokenType, ref ReadStack state, ref Utf8JsonReader reader) { Debug.Assert(ShouldDeserialize); - JsonPropertyInfo propertyInfo; - JsonClassInfo elementClassInfo = ElementClassInfo; + JsonPropertyInfo? propertyInfo; + JsonClassInfo? elementClassInfo = ElementClassInfo; if (elementClassInfo != null && (propertyInfo = elementClassInfo.PolicyProperty) != null) { if (!state.Current.CollectionPropertyInitialized) @@ -455,9 +459,9 @@ public JsonClassInfo DeclaredTypeClassInfo } } - public Type RuntimePropertyType { get; private set; } + public Type RuntimePropertyType { get; private set; } = null!; - public abstract void SetValueAsObject(object obj, object value); + public abstract void SetValueAsObject(object? obj, object? value); public bool ShouldSerialize { get; private set; } public bool ShouldDeserialize { get; private set; } @@ -514,8 +518,11 @@ public void Write(ref WriteStack state, Utf8JsonWriter writer) if (state.Current.CollectionEnumerator != null) { + Debug.Assert(ElementClassInfo != null); + // Forward the setter to the value-based JsonPropertyInfo. - JsonPropertyInfo propertyInfo = ElementClassInfo.PolicyProperty; + JsonPropertyInfo? propertyInfo = ElementClassInfo.PolicyProperty; + Debug.Assert(propertyInfo != null); propertyInfo.WriteEnumerable(ref state, writer); } // For performance on release build, don't verify converter correctness for internal converters. diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoCommon.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoCommon.cs index 7b9c78ed22e736..0b4d73459c1c75 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoCommon.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoCommon.cs @@ -5,6 +5,7 @@ using System.Collections; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Text.Json.Serialization; @@ -15,21 +16,21 @@ namespace System.Text.Json /// internal abstract class JsonPropertyInfoCommon : JsonPropertyInfo { - public Func Get { get; private set; } - public Action Set { get; private set; } + public Func? Get { get; private set; } + public Action? Set { get; private set; } - public Action AddItemToEnumerable { get; private set; } + public Action? AddItemToEnumerable { get; private set; } - public JsonConverter Converter { get; internal set; } + public JsonConverter? Converter { get; internal set; } public override void Initialize( Type parentClassType, Type declaredPropertyType, Type runtimePropertyType, ClassType runtimeClassType, - PropertyInfo propertyInfo, - Type elementType, - JsonConverter converter, + PropertyInfo? propertyInfo, + Type? elementType, + JsonConverter? converter, bool treatAsNullable, JsonSerializerOptions options) { @@ -68,7 +69,8 @@ public override void Initialize( GetPolicies(); } - public override JsonConverter ConverterBase + [DisallowNull] + public override JsonConverter? ConverterBase { get { @@ -83,7 +85,7 @@ public override JsonConverter ConverterBase } } - public override object GetValueAsObject(object obj) + public override object? GetValueAsObject(object? obj) { if (IsPropertyPolicy) { @@ -91,40 +93,41 @@ public override object GetValueAsObject(object obj) } Debug.Assert(HasGetter); - return Get(obj); + return Get!(obj); } - public override void SetValueAsObject(object obj, object value) + public override void SetValueAsObject(object? obj, object? value) { Debug.Assert(HasSetter); - TDeclaredProperty typedValue = (TDeclaredProperty)value; + TDeclaredProperty typedValue = (TDeclaredProperty)value!; if (typedValue != null || !IgnoreNullValues) { - Set(obj, typedValue); + Set!(obj, typedValue); } } - private JsonPropertyInfo _elementPropertyInfo; + private JsonPropertyInfo? _elementPropertyInfo; private void SetPropertyInfoForObjectElement() { + Debug.Assert(ElementClassInfo != null); if (_elementPropertyInfo == null && ElementClassInfo.PolicyProperty == null) { _elementPropertyInfo = ElementClassInfo.CreateRootProperty(Options); } } - public override bool TryCreateEnumerableAddMethod(object target, out object addMethodDelegate) + public override bool TryCreateEnumerableAddMethod(object target, [NotNullWhen(true)] out object? addMethodDelegate) { SetPropertyInfoForObjectElement(); - Debug.Assert((_elementPropertyInfo ?? ElementClassInfo.PolicyProperty) != null); + Debug.Assert((_elementPropertyInfo ?? ElementClassInfo!.PolicyProperty) != null); - addMethodDelegate = (_elementPropertyInfo ?? ElementClassInfo.PolicyProperty).CreateEnumerableAddMethod(RuntimeClassInfo.AddItemToObject, target); + addMethodDelegate = (_elementPropertyInfo ?? ElementClassInfo!.PolicyProperty!).CreateEnumerableAddMethod(RuntimeClassInfo.AddItemToObject!, target); return addMethodDelegate != null; } - public override object CreateEnumerableAddMethod(MethodInfo addMethod, object target) + public override object? CreateEnumerableAddMethod(MethodInfo addMethod, object target) { if (target is ICollection collection && collection.IsReadOnly) { @@ -134,29 +137,29 @@ public override object CreateEnumerableAddMethod(MethodInfo addMethod, object ta return Options.MemberAccessorStrategy.CreateAddDelegate(addMethod, target); } - public override void AddObjectToEnumerableWithReflection(object addMethodDelegate, object value) + public override void AddObjectToEnumerableWithReflection(object addMethodDelegate, object? value) { - Debug.Assert((_elementPropertyInfo ?? ElementClassInfo.PolicyProperty) != null); - (_elementPropertyInfo ?? ElementClassInfo.PolicyProperty).AddObjectToParentEnumerable(addMethodDelegate, value); + Debug.Assert((_elementPropertyInfo ?? ElementClassInfo?.PolicyProperty) != null); + (_elementPropertyInfo ?? ElementClassInfo!.PolicyProperty!).AddObjectToParentEnumerable(addMethodDelegate, value); } - public override void AddObjectToParentEnumerable(object addMethodDelegate, object value) + public override void AddObjectToParentEnumerable(object addMethodDelegate, object? value) { - ((Action)addMethodDelegate)((TDeclaredProperty)value); + ((Action)addMethodDelegate)((TDeclaredProperty)value!); } - public override void AddObjectToDictionary(object target, string key, object value) + public override void AddObjectToDictionary(object target, string key, object? value) { - Debug.Assert((_elementPropertyInfo ?? ElementClassInfo.PolicyProperty) != null); - (_elementPropertyInfo ?? ElementClassInfo.PolicyProperty).AddObjectToParentDictionary(target, key, value); + Debug.Assert((_elementPropertyInfo ?? ElementClassInfo?.PolicyProperty) != null); + (_elementPropertyInfo ?? ElementClassInfo!.PolicyProperty!).AddObjectToParentDictionary(target, key, value); } - public override void AddObjectToParentDictionary(object target, string key, object value) + public override void AddObjectToParentDictionary(object target, string key, object? value) { if (target is IDictionary genericDict) { Debug.Assert(!genericDict.IsReadOnly); - genericDict[key] = (TDeclaredProperty)value; + genericDict[key] = (TDeclaredProperty)value!; } else { @@ -167,8 +170,8 @@ public override void AddObjectToParentDictionary(object target, string key, obje public override bool CanPopulateDictionary(object target) { SetPropertyInfoForObjectElement(); - Debug.Assert((_elementPropertyInfo ?? ElementClassInfo.PolicyProperty) != null); - return (_elementPropertyInfo ?? ElementClassInfo.PolicyProperty).ParentDictionaryCanBePopulated(target); + Debug.Assert((_elementPropertyInfo ?? ElementClassInfo!.PolicyProperty) != null); + return (_elementPropertyInfo ?? ElementClassInfo!.PolicyProperty!).ParentDictionaryCanBePopulated(target); } public override bool ParentDictionaryCanBePopulated(object target) @@ -179,7 +182,7 @@ public override bool ParentDictionaryCanBePopulated(object target) } else if (target is IDictionary dict && !dict.IsReadOnly) { - Type genericDictType = target.GetType().GetInterface("System.Collections.Generic.IDictionary`2") ?? + Type? genericDictType = target.GetType().GetInterface("System.Collections.Generic.IDictionary`2") ?? target.GetType().GetInterface("System.Collections.Generic.IReadOnlyDictionary`2"); if (genericDictType != null && genericDictType.GetGenericArguments()[0] != typeof(string)) @@ -208,9 +211,9 @@ public override IDictionary CreateConverterDictionary() // CreateRange method to create and return the desired immutable collection type. public override IEnumerable CreateImmutableCollectionInstance(ref ReadStack state, Type collectionType, string delegateKey, IList sourceList, JsonSerializerOptions options) { - IEnumerable collection = null; + IEnumerable? collection = null; - if (!options.TryGetCreateRangeDelegate(delegateKey, out ImmutableCollectionCreator creator) || + if (!options.TryGetCreateRangeDelegate(delegateKey, out ImmutableCollectionCreator? creator) || !creator.CreateImmutableEnumerable(sourceList, out collection)) { ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(collectionType, state.JsonPath()); @@ -224,9 +227,9 @@ public override IEnumerable CreateImmutableCollectionInstance(ref ReadStack stat // CreateRange method to create and return the desired immutable collection type. public override IDictionary CreateImmutableDictionaryInstance(ref ReadStack state, Type collectionType, string delegateKey, IDictionary sourceDictionary, JsonSerializerOptions options) { - IDictionary collection = null; + IDictionary? collection = null; - if (!options.TryGetCreateRangeDelegate(delegateKey, out ImmutableCollectionCreator creator) || + if (!options.TryGetCreateRangeDelegate(delegateKey, out ImmutableCollectionCreator? creator) || !creator.CreateImmutableDictionary(sourceDictionary, out collection)) { ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(collectionType, state.JsonPath()); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoNotNullable.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoNotNullable.cs index 71b438bf42d543..63d3ff482f92e3 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoNotNullable.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoNotNullable.cs @@ -30,6 +30,7 @@ protected override void OnRead(ref ReadStack state, ref Utf8JsonReader reader) } else { + Debug.Assert(Set != null); Set(state.Current.ReturnValue, value); } } @@ -63,11 +64,12 @@ protected override void OnWrite(ref WriteStackFrame current, Utf8JsonWriter writ TConverter value; if (IsPropertyPolicy) { - value = (TConverter)current.CurrentValue; + value = (TConverter)current.CurrentValue!; } else { - value = (TConverter)Get(current.CurrentValue); + Debug.Assert(Get != null); + value = (TConverter)Get(current.CurrentValue)!; } if (value == null) @@ -92,6 +94,7 @@ protected override void OnWrite(ref WriteStackFrame current, Utf8JsonWriter writ protected override void OnWriteDictionary(ref WriteStackFrame current, Utf8JsonWriter writer) { + Debug.Assert(Converter != null); JsonSerializer.WriteDictionary(Converter, Options, ref current, writer); } @@ -110,7 +113,7 @@ protected override void OnWriteEnumerable(ref WriteStackFrame current, Utf8JsonW } else { - value = (TConverter)current.CollectionEnumerator.Current; + value = (TConverter)current.CollectionEnumerator.Current!; } if (value == null) @@ -129,7 +132,7 @@ public override Type GetDictionaryConcreteType() return typeof(Dictionary); } - public override void GetDictionaryKeyAndValueFromGenericDictionary(ref WriteStackFrame writeStackFrame, out string key, out object value) + public override void GetDictionaryKeyAndValueFromGenericDictionary(ref WriteStackFrame writeStackFrame, out string key, out object? value) { if (writeStackFrame.CollectionEnumerator is IEnumerator> genericEnumerator) { @@ -139,7 +142,7 @@ public override void GetDictionaryKeyAndValueFromGenericDictionary(ref WriteStac else { throw ThrowHelper.GetNotSupportedException_SerializationNotSupportedCollection( - writeStackFrame.JsonPropertyInfo.DeclaredPropertyType, + writeStackFrame.JsonPropertyInfo!.DeclaredPropertyType, writeStackFrame.JsonPropertyInfo.ParentClassType, writeStackFrame.JsonPropertyInfo.PropertyInfo); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoNotNullableContravariant.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoNotNullableContravariant.cs index 63039b7b6497bd..e42c8c6ee26625 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoNotNullableContravariant.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoNotNullableContravariant.cs @@ -30,7 +30,8 @@ protected override void OnRead(ref ReadStack state, ref Utf8JsonReader reader) } else { - Set(state.Current.ReturnValue, (TDeclaredProperty)value); + Debug.Assert(Set != null); + Set(state.Current.ReturnValue, (TDeclaredProperty)value!); } return; @@ -65,10 +66,11 @@ protected override void OnWrite(ref WriteStackFrame current, Utf8JsonWriter writ TConverter value; if (IsPropertyPolicy) { - value = (TConverter)current.CurrentValue; + value = (TConverter)current.CurrentValue!; } else { + Debug.Assert(Get != null); value = (TConverter)Get(current.CurrentValue); } @@ -94,6 +96,7 @@ protected override void OnWrite(ref WriteStackFrame current, Utf8JsonWriter writ protected override void OnWriteDictionary(ref WriteStackFrame current, Utf8JsonWriter writer) { + Debug.Assert(Converter != null); JsonSerializer.WriteDictionary(Converter, Options, ref current, writer); } @@ -111,7 +114,7 @@ protected override void OnWriteEnumerable(ref WriteStackFrame current, Utf8JsonW } else { - value = (TConverter)current.CollectionEnumerator.Current; + value = (TConverter)current.CollectionEnumerator.Current!; } if (value == null) @@ -130,7 +133,7 @@ public override Type GetDictionaryConcreteType() return typeof(Dictionary); } - public override void GetDictionaryKeyAndValueFromGenericDictionary(ref WriteStackFrame writeStackFrame, out string key, out object value) + public override void GetDictionaryKeyAndValueFromGenericDictionary(ref WriteStackFrame writeStackFrame, out string key, out object? value) { if (writeStackFrame.CollectionEnumerator is IEnumerator> genericEnumerator) { @@ -140,7 +143,7 @@ public override void GetDictionaryKeyAndValueFromGenericDictionary(ref WriteStac else { throw ThrowHelper.GetNotSupportedException_SerializationNotSupportedCollection( - writeStackFrame.JsonPropertyInfo.DeclaredPropertyType, + writeStackFrame.JsonPropertyInfo!.DeclaredPropertyType, writeStackFrame.JsonPropertyInfo.ParentClassType, writeStackFrame.JsonPropertyInfo.PropertyInfo); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoNullable.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoNullable.cs index 3605750fe5d38f..1dc66e8dff3644 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoNullable.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoNullable.cs @@ -33,6 +33,7 @@ protected override void OnRead(ref ReadStack state, ref Utf8JsonReader reader) } else { + Debug.Assert(Set != null); Set(state.Current.ReturnValue, value); } } @@ -58,6 +59,7 @@ protected override void OnWrite(ref WriteStackFrame current, Utf8JsonWriter writ } else { + Debug.Assert(Get != null); value = Get(current.CurrentValue); } @@ -85,7 +87,7 @@ protected override void OnWriteDictionary(ref WriteStackFrame current, Utf8JsonW { Debug.Assert(Converter != null && current.CollectionEnumerator != null); - string key = null; + string? key = null; TProperty? value = null; if (current.CollectionEnumerator is IEnumerator> enumerator) { @@ -94,7 +96,7 @@ protected override void OnWriteDictionary(ref WriteStackFrame current, Utf8JsonW } else { - if (((DictionaryEntry)current.CollectionEnumerator.Current).Key is string keyAsString) + if (((DictionaryEntry)current.CollectionEnumerator.Current!).Key is string keyAsString) { key = keyAsString; value = (TProperty?)((DictionaryEntry)current.CollectionEnumerator.Current).Value; @@ -102,7 +104,7 @@ protected override void OnWriteDictionary(ref WriteStackFrame current, Utf8JsonW else { throw ThrowHelper.GetNotSupportedException_SerializationNotSupportedCollection( - current.JsonPropertyInfo.DeclaredPropertyType, + current.JsonPropertyInfo!.DeclaredPropertyType, current.JsonPropertyInfo.ParentClassType, current.JsonPropertyInfo.PropertyInfo); } @@ -126,11 +128,11 @@ protected override void OnWriteDictionary(ref WriteStackFrame current, Utf8JsonW if (value == null) { - writer.WriteNull(key); + writer.WriteNull(key!); } else { - writer.WritePropertyName(key); + writer.WritePropertyName(key!); Converter.Write(writer, value.GetValueOrDefault(), Options); } } @@ -168,7 +170,7 @@ public override Type GetDictionaryConcreteType() return typeof(Dictionary); } - public override void GetDictionaryKeyAndValueFromGenericDictionary(ref WriteStackFrame writeStackFrame, out string key, out object value) + public override void GetDictionaryKeyAndValueFromGenericDictionary(ref WriteStackFrame writeStackFrame, out string key, out object? value) { if (writeStackFrame.CollectionEnumerator is IEnumerator> genericEnumerator) { @@ -178,7 +180,7 @@ public override void GetDictionaryKeyAndValueFromGenericDictionary(ref WriteStac else { throw ThrowHelper.GetNotSupportedException_SerializationNotSupportedCollection( - writeStackFrame.JsonPropertyInfo.DeclaredPropertyType, + writeStackFrame.JsonPropertyInfo!.DeclaredPropertyType, writeStackFrame.JsonPropertyInfo.ParentClassType, writeStackFrame.JsonPropertyInfo.PropertyInfo); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleArray.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleArray.cs index 47e092d39a1f7b..0136b0cef60e19 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleArray.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleArray.cs @@ -22,7 +22,7 @@ private static void HandleStartArray(JsonSerializerOptions options, ref ReadStac return; } - JsonPropertyInfo jsonPropertyInfo = state.Current.JsonPropertyInfo; + JsonPropertyInfo? jsonPropertyInfo = state.Current.JsonPropertyInfo; if (jsonPropertyInfo == null) { jsonPropertyInfo = state.Current.JsonClassInfo.CreateRootProperty(options); @@ -37,7 +37,7 @@ private static void HandleStartArray(JsonSerializerOptions options, ref ReadStac if (state.Current.CollectionPropertyInitialized) { // An array nested in a dictionary or array, so push a new stack frame. - Type elementType = jsonPropertyInfo.ElementClassInfo.Type; + Type elementType = jsonPropertyInfo.ElementClassInfo!.Type; state.Push(); state.Current.Initialize(elementType, options); @@ -57,7 +57,7 @@ private static void HandleStartArray(JsonSerializerOptions options, ref ReadStac } // Set or replace the existing enumerable value. - object value = ReadStackFrame.CreateEnumerableValue(ref state); + object? value = ReadStackFrame.CreateEnumerableValue(ref state); // If value is not null, then we don't have a converter so apply the value. if (value != null) @@ -66,6 +66,7 @@ private static void HandleStartArray(JsonSerializerOptions options, ref ReadStac if (state.Current.ReturnValue != null) { + Debug.Assert(state.Current.JsonPropertyInfo != null); state.Current.JsonPropertyInfo.SetValueAsObject(state.Current.ReturnValue, value); } else @@ -88,21 +89,22 @@ private static bool HandleEndArray( return lastFrame; } - IEnumerable value = ReadStackFrame.GetEnumerableValue(ref state.Current); + IEnumerable? value = ReadStackFrame.GetEnumerableValue(ref state.Current); bool setPropertyDirectly = false; if (state.Current.TempEnumerableValues != null) { + Debug.Assert(state.Current.JsonPropertyInfo != null); // We have a converter; possibilities: // - Add value to current frame's current property or TempEnumerableValues. // - Add value to previous frame's current property or TempEnumerableValues. // - Set current property on current frame to value. // - Set current property on previous frame to value. // - Set ReturnValue if root frame and value is the actual return value. - JsonEnumerableConverter converter = state.Current.JsonPropertyInfo.EnumerableConverter; + JsonEnumerableConverter? converter = state.Current.JsonPropertyInfo.EnumerableConverter; Debug.Assert(converter != null); - value = converter.CreateFromList(ref state, (IList)value, options); + value = converter.CreateFromList(ref state, (IList)value!, options); state.Current.TempEnumerableValues = null; // Since we used a converter, we just processed an array or an immutable collection. This means we created a new enumerable object. @@ -146,11 +148,11 @@ private static bool HandleEndArray( // If this method is changed, also change ApplyValueToEnumerable. internal static void ApplyObjectToEnumerable( - object value, + object? value, ref ReadStack state, bool setPropertyDirectly = false) { - Debug.Assert(!state.Current.SkipProperty); + Debug.Assert(!state.Current.SkipProperty && state.Current.JsonPropertyInfo != null); if (state.Current.IsProcessingObject(ClassType.Enumerable)) { @@ -168,6 +170,7 @@ internal static void ApplyObjectToEnumerable( } else { + Debug.Assert(value != null); ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(value.GetType()); return; } @@ -191,7 +194,7 @@ internal static void ApplyObjectToEnumerable( { JsonPropertyInfo jsonPropertyInfo = state.Current.JsonPropertyInfo; - object currentEnumerable = jsonPropertyInfo.GetValueAsObject(state.Current.ReturnValue); + object? currentEnumerable = jsonPropertyInfo.GetValueAsObject(state.Current.ReturnValue); if (currentEnumerable == null) { jsonPropertyInfo.SetValueAsObject(state.Current.ReturnValue, value); @@ -209,7 +212,7 @@ internal static void ApplyObjectToEnumerable( } else if (state.Current.IsProcessingObject(ClassType.Dictionary) || (state.Current.IsProcessingProperty(ClassType.Dictionary) && !setPropertyDirectly)) { - string key = state.Current.KeyName; + string? key = state.Current.KeyName; Debug.Assert(!string.IsNullOrEmpty(key)); if (state.Current.TempDictionaryValues != null) @@ -220,7 +223,7 @@ internal static void ApplyObjectToEnumerable( { Debug.Assert(state.Current.ReturnValue != null); - object currentDictionary = state.Current.JsonPropertyInfo.GetValueAsObject(state.Current.ReturnValue); + object? currentDictionary = state.Current.JsonPropertyInfo.GetValueAsObject(state.Current.ReturnValue); if (currentDictionary is IDictionary dict) { @@ -229,6 +232,7 @@ internal static void ApplyObjectToEnumerable( } else { + Debug.Assert(currentDictionary != null); state.Current.JsonPropertyInfo.AddObjectToDictionary(currentDictionary, key, value); } } @@ -271,7 +275,7 @@ internal static void ApplyValueToEnumerable( JsonPropertyInfo jsonPropertyInfo = state.Current.JsonPropertyInfo; - object currentEnumerable = jsonPropertyInfo.GetValueAsObject(state.Current.ReturnValue); + object? currentEnumerable = jsonPropertyInfo.GetValueAsObject(state.Current.ReturnValue); if (currentEnumerable == null) { jsonPropertyInfo.SetValueAsObject(state.Current.ReturnValue, value); @@ -284,7 +288,7 @@ internal static void ApplyValueToEnumerable( } else if (state.Current.IsProcessingDictionary()) { - string key = state.Current.KeyName; + string? key = state.Current.KeyName; Debug.Assert(!string.IsNullOrEmpty(key)); if (state.Current.TempDictionaryValues != null) @@ -293,9 +297,9 @@ internal static void ApplyValueToEnumerable( } else { - Debug.Assert(state.Current.ReturnValue != null); + Debug.Assert(state.Current.ReturnValue != null && state.Current.JsonPropertyInfo != null); - object currentDictionary = state.Current.JsonPropertyInfo.GetValueAsObject(state.Current.ReturnValue); + object? currentDictionary = state.Current.JsonPropertyInfo.GetValueAsObject(state.Current.ReturnValue); if (currentDictionary is IDictionary genericDict) { @@ -309,6 +313,7 @@ internal static void ApplyValueToEnumerable( } else { + Debug.Assert(currentDictionary != null); throw ThrowHelper.GetNotSupportedException_SerializationNotSupportedCollection(currentDictionary.GetType(), parentType: null, memberInfo: null); } } @@ -321,7 +326,7 @@ internal static void ApplyValueToEnumerable( } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void AddValueToEnumerable(ref ReadStack state, object target, TProperty value) + private static void AddValueToEnumerable(ref ReadStack state, object? target, TProperty value) { if (target is IList genericList) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleDictionary.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleDictionary.cs index a614ab0f4dd402..8ddaa6fd66f3fe 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleDictionary.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleDictionary.cs @@ -14,7 +14,7 @@ private static void HandleStartDictionary(JsonSerializerOptions options, ref Rea { Debug.Assert(!state.Current.IsProcessingEnumerable()); - JsonPropertyInfo jsonPropertyInfo = state.Current.JsonPropertyInfo; + JsonPropertyInfo? jsonPropertyInfo = state.Current.JsonPropertyInfo; if (jsonPropertyInfo == null) { jsonPropertyInfo = state.Current.JsonClassInfo.CreateRootProperty(options); @@ -26,14 +26,14 @@ private static void HandleStartDictionary(JsonSerializerOptions options, ref Rea if (state.Current.CollectionPropertyInitialized) { state.Push(); - state.Current.JsonClassInfo = jsonPropertyInfo.ElementClassInfo; + state.Current.JsonClassInfo = jsonPropertyInfo.ElementClassInfo!; state.Current.InitializeJsonPropertyInfo(); JsonClassInfo classInfo = state.Current.JsonClassInfo; if (state.Current.IsProcessingDictionary()) { - object dictValue = ReadStackFrame.CreateDictionaryValue(ref state); + object? dictValue = ReadStackFrame.CreateDictionaryValue(ref state); // If value is not null, then we don't have a converter so apply the value. if (dictValue != null) @@ -63,13 +63,14 @@ private static void HandleStartDictionary(JsonSerializerOptions options, ref Rea state.Current.CollectionPropertyInitialized = true; - object value = ReadStackFrame.CreateDictionaryValue(ref state); + object? value = ReadStackFrame.CreateDictionaryValue(ref state); if (value != null) { state.Current.DetermineIfDictionaryCanBePopulated(value); if (state.Current.ReturnValue != null) { + Debug.Assert(state.Current.JsonPropertyInfo != null); state.Current.JsonPropertyInfo.SetValueAsObject(state.Current.ReturnValue, value); } else @@ -82,13 +83,13 @@ private static void HandleStartDictionary(JsonSerializerOptions options, ref Rea private static void HandleEndDictionary(JsonSerializerOptions options, ref ReadStack state) { - Debug.Assert(!state.Current.SkipProperty); + Debug.Assert(!state.Current.SkipProperty && state.Current.JsonPropertyInfo != null); if (state.Current.IsProcessingProperty(ClassType.Dictionary)) { if (state.Current.TempDictionaryValues != null) { - JsonDictionaryConverter converter = state.Current.JsonPropertyInfo.DictionaryConverter; + JsonDictionaryConverter converter = state.Current.JsonPropertyInfo.DictionaryConverter!; state.Current.JsonPropertyInfo.SetValueAsObject(state.Current.ReturnValue, converter.CreateFromDictionary(ref state, state.Current.TempDictionaryValues, options)); state.Current.EndProperty(); } @@ -110,10 +111,10 @@ private static void HandleEndDictionary(JsonSerializerOptions options, ref ReadS } else { - object value; + object? value; if (state.Current.TempDictionaryValues != null) { - JsonDictionaryConverter converter = state.Current.JsonPropertyInfo.DictionaryConverter; + JsonDictionaryConverter converter = state.Current.JsonPropertyInfo.DictionaryConverter!; value = converter.CreateFromDictionary(ref state, state.Current.TempDictionaryValues, options); } else diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleNull.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleNull.cs index c3878ed2c11ab6..c5c67426333ade 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleNull.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleNull.cs @@ -19,7 +19,7 @@ private static bool HandleNull(JsonSerializerOptions options, ref Utf8JsonReader return false; } - JsonPropertyInfo jsonPropertyInfo = state.Current.JsonPropertyInfo; + JsonPropertyInfo? jsonPropertyInfo = state.Current.JsonPropertyInfo; if (jsonPropertyInfo == null || (reader.CurrentDepth == 0 && jsonPropertyInfo.CanBeNull)) { @@ -71,7 +71,7 @@ private static bool HandleNull(JsonSerializerOptions options, ref Utf8JsonReader if (!jsonPropertyInfo.IgnoreNullValues) { - state.Current.JsonPropertyInfo.SetValueAsObject(state.Current.ReturnValue, value: null); + state.Current.JsonPropertyInfo!.SetValueAsObject(state.Current.ReturnValue, value: null); } return false; @@ -79,7 +79,7 @@ private static bool HandleNull(JsonSerializerOptions options, ref Utf8JsonReader private static void AddNullToCollection(JsonPropertyInfo jsonPropertyInfo, ref Utf8JsonReader reader, ref ReadStack state) { - JsonPropertyInfo elementPropertyInfo = jsonPropertyInfo.ElementClassInfo.PolicyProperty; + JsonPropertyInfo? elementPropertyInfo = jsonPropertyInfo.ElementClassInfo!.PolicyProperty; // if elementPropertyInfo == null then this element doesn't need a converter (an object). if (elementPropertyInfo?.CanBeNull == false) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleObject.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleObject.cs index 5c0aa80725c286..5795dc40d982c1 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleObject.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleObject.cs @@ -22,7 +22,7 @@ private static void HandleStartObject(JsonSerializerOptions options, ref ReadSta if (!state.Current.CollectionPropertyInitialized) { // We have bad JSON: enumerable element appeared without preceding StartArray token. - ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(state.Current.JsonPropertyInfo.DeclaredPropertyType); + ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(state.Current.JsonPropertyInfo!.DeclaredPropertyType); } Type objType = state.Current.GetElementType(); @@ -43,7 +43,7 @@ private static void HandleStartObject(JsonSerializerOptions options, ref ReadSta if (state.Current.IsProcessingObject(ClassType.Dictionary)) { - object value = ReadStackFrame.CreateDictionaryValue(ref state); + object? value = ReadStackFrame.CreateDictionaryValue(ref state); // If value is not null, then we don't have a converter so apply the value. if (value != null) @@ -81,7 +81,7 @@ private static void HandleEndObject(ref ReadStack state) state.Current.JsonClassInfo.UpdateSortedPropertyCache(ref state.Current); } - object value = state.Current.ReturnValue; + object? value = state.Current.ReturnValue; if (state.IsLastFrame) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandlePropertyName.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandlePropertyName.cs index b59abd393f35c6..2b96ba518107ff 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandlePropertyName.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandlePropertyName.cs @@ -54,7 +54,7 @@ private static void HandlePropertyName( JsonPropertyInfo jsonPropertyInfo = state.Current.JsonClassInfo.GetProperty(propertyName, ref state.Current); if (jsonPropertyInfo == JsonPropertyInfo.s_missingProperty) { - JsonPropertyInfo dataExtProperty = state.Current.JsonClassInfo.DataExtensionProperty; + JsonPropertyInfo? dataExtProperty = state.Current.JsonClassInfo.DataExtensionProperty; if (dataExtProperty == null) { state.Current.JsonPropertyInfo = JsonPropertyInfo.s_missingProperty; @@ -108,7 +108,7 @@ private static void CreateDataExtensionProperty( Debug.Assert(jsonPropertyInfo != null); Debug.Assert(state.Current.ReturnValue != null); - IDictionary extensionData = (IDictionary)jsonPropertyInfo.GetValueAsObject(state.Current.ReturnValue); + IDictionary? extensionData = (IDictionary?)jsonPropertyInfo.GetValueAsObject(state.Current.ReturnValue); if (extensionData == null) { // Create the appropriate dictionary type. We already verified the types. @@ -119,7 +119,8 @@ private static void CreateDataExtensionProperty( jsonPropertyInfo.DeclaredPropertyType.GetGenericArguments()[1].UnderlyingSystemType == typeof(object) || jsonPropertyInfo.DeclaredPropertyType.GetGenericArguments()[1].UnderlyingSystemType == typeof(JsonElement)); - extensionData = (IDictionary)jsonPropertyInfo.RuntimeClassInfo.CreateObject(); + Debug.Assert(jsonPropertyInfo.RuntimeClassInfo.CreateObject != null); + extensionData = (IDictionary?)jsonPropertyInfo.RuntimeClassInfo.CreateObject(); jsonPropertyInfo.SetValueAsObject(state.Current.ReturnValue, extensionData); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleValue.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleValue.cs index 868a7c8091451d..633faf89a5a3f7 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleValue.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleValue.cs @@ -17,7 +17,7 @@ private static void HandleValue(JsonTokenType tokenType, JsonSerializerOptions o return; } - JsonPropertyInfo jsonPropertyInfo = state.Current.JsonPropertyInfo; + JsonPropertyInfo? jsonPropertyInfo = state.Current.JsonPropertyInfo; if (jsonPropertyInfo == null) { jsonPropertyInfo = state.Current.JsonClassInfo.CreateRootProperty(options); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Helpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Helpers.cs index 8d41758722e819..350946775e7db8 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Helpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Helpers.cs @@ -6,7 +6,7 @@ namespace System.Text.Json { public static partial class JsonSerializer { - private static object ReadCore( + private static object? ReadCore( Type returnType, JsonSerializerOptions options, ref Utf8JsonReader reader) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Span.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Span.cs index 7f9f13f1048d6f..9fdbd0d6065abe 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Span.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Span.cs @@ -19,9 +19,9 @@ public static partial class JsonSerializer /// is not compatible with the JSON, /// or when there is remaining data in the Stream. /// - public static TValue Deserialize(ReadOnlySpan utf8Json, JsonSerializerOptions options = null) + public static TValue Deserialize(ReadOnlySpan utf8Json, JsonSerializerOptions? options = null) { - return (TValue)ParseCore(utf8Json, typeof(TValue), options); + return (TValue)ParseCore(utf8Json, typeof(TValue), options)!; } /// @@ -39,7 +39,7 @@ public static TValue Deserialize(ReadOnlySpan utf8Json, JsonSerial /// is not compatible with the JSON, /// or when there is remaining data in the Stream. /// - public static object Deserialize(ReadOnlySpan utf8Json, Type returnType, JsonSerializerOptions options = null) + public static object? Deserialize(ReadOnlySpan utf8Json, Type returnType, JsonSerializerOptions? options = null) { if (returnType == null) throw new ArgumentNullException(nameof(returnType)); @@ -47,7 +47,7 @@ public static object Deserialize(ReadOnlySpan utf8Json, Type returnType, J return ParseCore(utf8Json, returnType, options); } - private static object ParseCore(ReadOnlySpan utf8Json, Type returnType, JsonSerializerOptions options) + private static object? ParseCore(ReadOnlySpan utf8Json, Type returnType, JsonSerializerOptions? options) { if (options == null) { @@ -56,7 +56,7 @@ private static object ParseCore(ReadOnlySpan utf8Json, Type returnType, Js var readerState = new JsonReaderState(options.GetReaderOptions()); var reader = new Utf8JsonReader(utf8Json, isFinalBlock: true, readerState); - object result = ReadCore(returnType, options, ref reader); + object? result = ReadCore(returnType, options, ref reader); // The reader should have thrown if we have remaining bytes. Debug.Assert(reader.BytesConsumed == utf8Json.Length); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Stream.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Stream.cs index 1dce5edc707851..bd82cf0f11bfc6 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Stream.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Stream.cs @@ -29,7 +29,7 @@ public static partial class JsonSerializer /// public static ValueTask DeserializeAsync( Stream utf8Json, - JsonSerializerOptions options = null, + JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) { if (utf8Json == null) @@ -60,7 +60,7 @@ public static ValueTask DeserializeAsync( public static ValueTask DeserializeAsync( Stream utf8Json, Type returnType, - JsonSerializerOptions options = null, + JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) { if (utf8Json == null) @@ -75,7 +75,7 @@ public static ValueTask DeserializeAsync( private static async ValueTask ReadAsync( Stream utf8Json, Type returnType, - JsonSerializerOptions options = null, + JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) { if (options == null) @@ -197,7 +197,7 @@ private static async ValueTask ReadAsync( // The reader should have thrown if we have remaining bytes. Debug.Assert(bytesInBuffer == 0); - return (TValue)readStack.Current.ReturnValue; + return (TValue)readStack.Current.ReturnValue!; } private static void ReadCore( diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.String.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.String.cs index 3fed716a591eb2..4e623c017293b4 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.String.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.String.cs @@ -26,9 +26,9 @@ public static partial class JsonSerializer /// Using a is not as efficient as using the /// UTF-8 methods since the implementation natively uses UTF-8. /// - public static TValue Deserialize(string json, JsonSerializerOptions options = null) + public static TValue Deserialize(string json, JsonSerializerOptions? options = null) { - return (TValue)Deserialize(json, typeof(TValue), options); + return (TValue)Deserialize(json, typeof(TValue), options)!; } /// @@ -49,7 +49,7 @@ public static TValue Deserialize(string json, JsonSerializerOptions opti /// Using a is not as efficient as using the /// UTF-8 methods since the implementation natively uses UTF-8. /// - public static object Deserialize(string json, Type returnType, JsonSerializerOptions options = null) + public static object? Deserialize(string json, Type returnType, JsonSerializerOptions? options = null) { const long ArrayPoolMaxSizeBeforeUsingNormalAlloc = 1024 * 1024; @@ -68,8 +68,8 @@ public static object Deserialize(string json, Type returnType, JsonSerializerOpt options = JsonSerializerOptions.s_defaultOptions; } - object result; - byte[] tempArray = null; + object? result; + byte[]? tempArray = null; // For performance, avoid obtaining actual byte count unless memory usage is higher than the threshold. Span utf8 = json.Length <= (ArrayPoolMaxSizeBeforeUsingNormalAlloc / JsonConstants.MaxExpansionFactorWhileTranscoding) ? diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Utf8JsonReader.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Utf8JsonReader.cs index 7db0f4a921de61..056a87f244a753 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Utf8JsonReader.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Utf8JsonReader.cs @@ -47,9 +47,9 @@ public static partial class JsonSerializer /// Hence, , , are used while reading. /// /// - public static TValue Deserialize(ref Utf8JsonReader reader, JsonSerializerOptions options = null) + public static TValue Deserialize(ref Utf8JsonReader reader, JsonSerializerOptions? options = null) { - return (TValue)ReadValueCore(ref reader, typeof(TValue), options); + return (TValue)ReadValueCore(ref reader, typeof(TValue), options)!; } /// @@ -93,7 +93,7 @@ public static TValue Deserialize(ref Utf8JsonReader reader, JsonSerializ /// Hence, , , are used while reading. /// /// - public static object Deserialize(ref Utf8JsonReader reader, Type returnType, JsonSerializerOptions options = null) + public static object? Deserialize(ref Utf8JsonReader reader, Type returnType, JsonSerializerOptions? options = null) { if (returnType == null) throw new ArgumentNullException(nameof(returnType)); @@ -101,7 +101,7 @@ public static object Deserialize(ref Utf8JsonReader reader, Type returnType, Jso return ReadValueCore(ref reader, returnType, options); } - private static object ReadValueCore(ref Utf8JsonReader reader, Type returnType, JsonSerializerOptions options) + private static object? ReadValueCore(ref Utf8JsonReader reader, Type returnType, JsonSerializerOptions? options) { if (options == null) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.cs index d3f8ce83aa9ac8..0090ac206a8113 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.cs @@ -184,7 +184,7 @@ private static ReadOnlySpan GetUnescapedString(ReadOnlySpan utf8Sour { // The escaped name is always longer than the unescaped, so it is safe to use escaped name for the buffer length. int length = utf8Source.Length; - byte[] pooledName = null; + byte[]? pooledName = null; Span unescapedName = length <= JsonConstants.StackallocThreshold ? stackalloc byte[length] : diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.ByteArray.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.ByteArray.cs index 06064ca96286d0..93efcb45016bef 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.ByteArray.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.ByteArray.cs @@ -12,7 +12,7 @@ public static partial class JsonSerializer /// A UTF-8 representation of the value. /// The value to convert. /// Options to control the conversion behavior. - public static byte[] SerializeToUtf8Bytes(TValue value, JsonSerializerOptions options = null) + public static byte[] SerializeToUtf8Bytes(TValue value, JsonSerializerOptions? options = null) { return WriteCoreBytes(value, typeof(TValue), options); } @@ -24,7 +24,7 @@ public static byte[] SerializeToUtf8Bytes(TValue value, JsonSerializerOp /// The value to convert. /// The type of the to convert. /// Options to control the conversion behavior. - public static byte[] SerializeToUtf8Bytes(object value, Type inputType, JsonSerializerOptions options = null) + public static byte[] SerializeToUtf8Bytes(object? value, Type? inputType, JsonSerializerOptions? options = null) { VerifyValueAndType(value, inputType); return WriteCoreBytes(value, inputType, options); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.HandleDictionary.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.HandleDictionary.cs index 22c1f2324ceea7..1fe93f7aa77330 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.HandleDictionary.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.HandleDictionary.cs @@ -17,16 +17,14 @@ private static bool HandleDictionary( Utf8JsonWriter writer, ref WriteStack state) { - JsonPropertyInfo jsonPropertyInfo = state.Current.JsonPropertyInfo; + JsonPropertyInfo jsonPropertyInfo = state.Current.JsonPropertyInfo!; if (state.Current.CollectionEnumerator == null) { - IEnumerable enumerable; - - enumerable = (IEnumerable)jsonPropertyInfo.GetValueAsObject(state.Current.CurrentValue); + IEnumerable? enumerable = (IEnumerable?)jsonPropertyInfo.GetValueAsObject(state.Current.CurrentValue); if (enumerable == null) { - if ((state.Current.JsonClassInfo.ClassType != ClassType.Object || // Write null dictionary values - !state.Current.JsonPropertyInfo.IgnoreNullValues) && // Ignore ClassType.Object properties if IgnoreNullValues is true + if ((state.Current.JsonClassInfo!.ClassType != ClassType.Object || // Write null dictionary values + !jsonPropertyInfo.IgnoreNullValues) && // Ignore ClassType.Object properties if IgnoreNullValues is true state.Current.ExtensionDataStatus != ExtensionDataWriteStatus.Writing) // Ignore null extension property (which is a dictionary) { // Write a null object or enumerable. @@ -59,8 +57,8 @@ private static bool HandleDictionary( Debug.Assert(state.Current.CollectionEnumerator.Current != null); bool obtainedValues = false; - string key = default; - object value = default; + string? key = default; + object? value = default; // Check for polymorphism. if (elementClassInfo.ClassType == ClassType.Unknown) @@ -72,7 +70,7 @@ private static bool HandleDictionary( if (elementClassInfo.ClassType == ClassType.Value) { - elementClassInfo.PolicyProperty.WriteDictionary(ref state, writer); + elementClassInfo.PolicyProperty!.WriteDictionary(ref state, writer); } else { @@ -125,7 +123,7 @@ internal static void WriteDictionary( { Debug.Assert(converter != null && current.CollectionEnumerator != null); - string key; + string? key; TProperty value; if (current.CollectionEnumerator is IEnumerator> enumerator) { @@ -141,12 +139,12 @@ internal static void WriteDictionary( iDictionaryEnumerator.Key is string keyAsString) { key = keyAsString; - value = (TProperty)iDictionaryEnumerator.Value; + value = (TProperty)iDictionaryEnumerator.Value!; } else { throw ThrowHelper.GetNotSupportedException_SerializationNotSupportedCollection( - current.JsonPropertyInfo.DeclaredPropertyType, + current.JsonPropertyInfo!.DeclaredPropertyType, current.JsonPropertyInfo.ParentClassType, current.JsonPropertyInfo.PropertyInfo); } @@ -167,11 +165,11 @@ internal static void WriteDictionary( if (value == null) { - writer.WriteNull(key); + writer.WriteNull(key!); } else { - writer.WritePropertyName(key); + writer.WritePropertyName(key!); converter.Write(writer, value, options); } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.HandleEnumerable.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.HandleEnumerable.cs index 9ef8bc6a485a5b..2fb2973140f3a9 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.HandleEnumerable.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.HandleEnumerable.cs @@ -15,16 +15,16 @@ private static bool HandleEnumerable( Utf8JsonWriter writer, ref WriteStack state) { - Debug.Assert(state.Current.JsonPropertyInfo.ClassType == ClassType.Enumerable); + Debug.Assert(state.Current.JsonPropertyInfo!.ClassType == ClassType.Enumerable); if (state.Current.CollectionEnumerator == null) { - IEnumerable enumerable = (IEnumerable)state.Current.JsonPropertyInfo.GetValueAsObject(state.Current.CurrentValue); + IEnumerable? enumerable = (IEnumerable?)state.Current.JsonPropertyInfo.GetValueAsObject(state.Current.CurrentValue); if (enumerable == null) { // If applicable, we only want to ignore object properties. - if (state.Current.JsonClassInfo.ClassType != ClassType.Object || + if (state.Current.JsonClassInfo!.ClassType != ClassType.Object || !state.Current.JsonPropertyInfo.IgnoreNullValues) { // Write a null object or enumerable. @@ -49,13 +49,13 @@ private static bool HandleEnumerable( // Check for polymorphism. if (elementClassInfo.ClassType == ClassType.Unknown) { - object currentValue = state.Current.CollectionEnumerator.Current; + object? currentValue = state.Current.CollectionEnumerator.Current; GetRuntimeClassInfo(currentValue, ref elementClassInfo, options); } if (elementClassInfo.ClassType == ClassType.Value) { - elementClassInfo.PolicyProperty.WriteEnumerable(ref state, writer); + elementClassInfo.PolicyProperty!.WriteEnumerable(ref state, writer); } else if (state.Current.CollectionEnumerator.Current == null) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.HandleObject.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.HandleObject.cs index 540c86eadb017d..62b06e776c284a 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.HandleObject.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.HandleObject.cs @@ -41,9 +41,9 @@ private static bool WriteObject( if (state.Current.ExtensionDataStatus != ExtensionDataWriteStatus.Finished) { // If ClassType.Unknown at this point, we are typeof(object) which should not have any properties. - Debug.Assert(state.Current.JsonClassInfo.ClassType != ClassType.Unknown); + Debug.Assert(state.Current.JsonClassInfo!.ClassType != ClassType.Unknown); - JsonPropertyInfo jsonPropertyInfo = state.Current.JsonClassInfo.PropertyCacheArray[state.Current.PropertyEnumeratorIndex - 1]; + JsonPropertyInfo jsonPropertyInfo = state.Current.JsonClassInfo.PropertyCacheArray![state.Current.PropertyEnumeratorIndex - 1]; HandleObject(jsonPropertyInfo, options, writer, ref state); return false; @@ -72,7 +72,7 @@ private static void HandleObject( ref WriteStack state) { Debug.Assert( - state.Current.JsonClassInfo.ClassType == ClassType.Object || + state.Current.JsonClassInfo!.ClassType == ClassType.Object || state.Current.JsonClassInfo.ClassType == ClassType.Unknown); if (!jsonPropertyInfo.ShouldSerialize) @@ -82,7 +82,7 @@ private static void HandleObject( } bool obtainedValue = false; - object currentValue = null; + object? currentValue = null; // Check for polymorphism. if (jsonPropertyInfo.ClassType == ClassType.Unknown) @@ -104,7 +104,7 @@ private static void HandleObject( // A property that returns an enumerator keeps the same stack frame. if (jsonPropertyInfo.ClassType == ClassType.Enumerable) { - bool endOfEnumerable = HandleEnumerable(jsonPropertyInfo.ElementClassInfo, options, writer, ref state); + bool endOfEnumerable = HandleEnumerable(jsonPropertyInfo.ElementClassInfo!, options, writer, ref state); if (endOfEnumerable) { state.Current.MoveToNextProperty = true; @@ -116,7 +116,7 @@ private static void HandleObject( // A property that returns a dictionary keeps the same stack frame. if (jsonPropertyInfo.ClassType == ClassType.Dictionary) { - bool endOfEnumerable = HandleDictionary(jsonPropertyInfo.ElementClassInfo, options, writer, ref state); + bool endOfEnumerable = HandleDictionary(jsonPropertyInfo.ElementClassInfo!, options, writer, ref state); if (endOfEnumerable) { state.Current.MoveToNextProperty = true; @@ -147,6 +147,7 @@ private static void HandleObject( { if (!jsonPropertyInfo.IgnoreNullValues) { + Debug.Assert(jsonPropertyInfo.EscapedName != null); writer.WriteNull(jsonPropertyInfo.EscapedName.Value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Helpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Helpers.cs index 0413a3f206f650..4016265c271473 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Helpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Helpers.cs @@ -8,7 +8,7 @@ namespace System.Text.Json { public static partial class JsonSerializer { - private static void GetRuntimeClassInfo(object value, ref JsonClassInfo jsonClassInfo, JsonSerializerOptions options) + private static void GetRuntimeClassInfo(object? value, ref JsonClassInfo jsonClassInfo, JsonSerializerOptions options) { if (value != null) { @@ -22,7 +22,7 @@ private static void GetRuntimeClassInfo(object value, ref JsonClassInfo jsonClas } } - private static void GetRuntimePropertyInfo(object value, JsonClassInfo jsonClassInfo, ref JsonPropertyInfo jsonPropertyInfo, JsonSerializerOptions options) + private static void GetRuntimePropertyInfo(object? value, JsonClassInfo jsonClassInfo, ref JsonPropertyInfo jsonPropertyInfo, JsonSerializerOptions options) { if (value != null) { @@ -36,7 +36,7 @@ private static void GetRuntimePropertyInfo(object value, JsonClassInfo jsonClass } } - private static void VerifyValueAndType(object value, Type type) + private static void VerifyValueAndType(object? value, Type? type) { if (type == null) { @@ -54,7 +54,7 @@ private static void VerifyValueAndType(object value, Type type) } } - private static byte[] WriteCoreBytes(object value, Type type, JsonSerializerOptions options) + private static byte[] WriteCoreBytes(object? value, Type? type, JsonSerializerOptions? options) { if (options == null) { @@ -72,7 +72,7 @@ private static byte[] WriteCoreBytes(object value, Type type, JsonSerializerOpti return result; } - private static string WriteCoreString(object value, Type type, JsonSerializerOptions options) + private static string WriteCoreString(object? value, Type? type, JsonSerializerOptions? options) { if (options == null) { @@ -90,7 +90,7 @@ private static string WriteCoreString(object value, Type type, JsonSerializerOpt return result; } - private static void WriteValueCore(Utf8JsonWriter writer, object value, Type type, JsonSerializerOptions options) + private static void WriteValueCore(Utf8JsonWriter writer, object? value, Type? type, JsonSerializerOptions? options) { if (options == null) { @@ -105,7 +105,7 @@ private static void WriteValueCore(Utf8JsonWriter writer, object value, Type typ WriteCore(writer, value, type, options); } - private static void WriteCore(PooledByteBufferWriter output, object value, Type type, JsonSerializerOptions options) + private static void WriteCore(PooledByteBufferWriter output, object? value, Type? type, JsonSerializerOptions options) { using (var writer = new Utf8JsonWriter(output, options.GetWriterOptions())) { @@ -113,7 +113,7 @@ private static void WriteCore(PooledByteBufferWriter output, object value, Type } } - private static void WriteCore(Utf8JsonWriter writer, object value, Type type, JsonSerializerOptions options) + private static void WriteCore(Utf8JsonWriter writer, object? value, Type? type, JsonSerializerOptions options) { Debug.Assert(type != null || value == null); Debug.Assert(writer != null); @@ -131,6 +131,7 @@ private static void WriteCore(Utf8JsonWriter writer, object value, Type type, Js } WriteStack state = default; + Debug.Assert(type != null); state.Current.Initialize(type, options); state.Current.CurrentValue = value; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Stream.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Stream.cs index ca3bd482296a98..00a08a2d050bc8 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Stream.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Stream.cs @@ -18,7 +18,7 @@ public static partial class JsonSerializer /// The value to convert. /// Options to control the conversion behavior. /// The which may be used to cancel the write operation. - public static Task SerializeAsync(Stream utf8Json, TValue value, JsonSerializerOptions options = null, CancellationToken cancellationToken = default) + public static Task SerializeAsync(Stream utf8Json, TValue value, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) { return WriteAsyncCore(utf8Json, value, typeof(TValue), options, cancellationToken); } @@ -32,7 +32,7 @@ public static Task SerializeAsync(Stream utf8Json, TValue value, JsonSer /// The type of the to convert. /// Options to control the conversion behavior. /// The which may be used to cancel the write operation. - public static Task SerializeAsync(Stream utf8Json, object value, Type inputType, JsonSerializerOptions options = null, CancellationToken cancellationToken = default) + public static Task SerializeAsync(Stream utf8Json, object? value, Type? inputType, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) { if (utf8Json == null) throw new ArgumentNullException(nameof(utf8Json)); @@ -42,7 +42,7 @@ public static Task SerializeAsync(Stream utf8Json, object value, Type inputType, return WriteAsyncCore(utf8Json, value, inputType, options, cancellationToken); } - private static async Task WriteAsyncCore(Stream utf8Json, object value, Type inputType, JsonSerializerOptions options, CancellationToken cancellationToken) + private static async Task WriteAsyncCore(Stream utf8Json, object? value, Type? inputType, JsonSerializerOptions? options, CancellationToken cancellationToken) { if (options == null) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.String.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.String.cs index 8937e2c9ec8642..d545d3a29e545e 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.String.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.String.cs @@ -16,7 +16,7 @@ public static partial class JsonSerializer /// encoding since the implementation internally uses UTF-8. See also /// and . /// - public static string Serialize(TValue value, JsonSerializerOptions options = null) + public static string Serialize(TValue value, JsonSerializerOptions? options = null) { return WriteCoreString(value, typeof(TValue), options); } @@ -32,7 +32,7 @@ public static string Serialize(TValue value, JsonSerializerOptions optio /// encoding since the implementation internally uses UTF-8. See also /// and . /// - public static string Serialize(object value, Type inputType, JsonSerializerOptions options = null) + public static string Serialize(object? value, Type? inputType, JsonSerializerOptions? options = null) { VerifyValueAndType(value, inputType); return WriteCoreString(value, inputType, options); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Utf8JsonWriter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Utf8JsonWriter.cs index 8e285557f37ea1..0280b53f51ee71 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Utf8JsonWriter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Utf8JsonWriter.cs @@ -15,7 +15,7 @@ public static partial class JsonSerializer /// /// is null. /// - public static void Serialize(Utf8JsonWriter writer, TValue value, JsonSerializerOptions options = null) + public static void Serialize(Utf8JsonWriter writer, TValue value, JsonSerializerOptions? options = null) { WriteValueCore(writer, value, typeof(TValue), options); } @@ -30,7 +30,7 @@ public static void Serialize(Utf8JsonWriter writer, TValue value, JsonSe /// /// is null. /// - public static void Serialize(Utf8JsonWriter writer, object value, Type inputType, JsonSerializerOptions options = null) + public static void Serialize(Utf8JsonWriter writer, object? value, Type? inputType, JsonSerializerOptions? options = null) { VerifyValueAndType(value, inputType); WriteValueCore(writer, value, inputType, options); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.cs index 5f25813631d5df..ce6e11fa7eae08 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.cs @@ -25,18 +25,18 @@ private static bool Write( { do { - switch (state.Current.JsonClassInfo.ClassType) + switch (state.Current.JsonClassInfo!.ClassType) { case ClassType.Enumerable: - finishedSerializing = HandleEnumerable(state.Current.JsonClassInfo.ElementClassInfo, options, writer, ref state); + finishedSerializing = HandleEnumerable(state.Current.JsonClassInfo.ElementClassInfo!, options, writer, ref state); break; case ClassType.Value: - Debug.Assert(state.Current.JsonPropertyInfo.ClassType == ClassType.Value); + Debug.Assert(state.Current.JsonPropertyInfo!.ClassType == ClassType.Value); state.Current.JsonPropertyInfo.Write(ref state, writer); finishedSerializing = true; break; case ClassType.Dictionary: - finishedSerializing = HandleDictionary(state.Current.JsonClassInfo.ElementClassInfo, options, writer, ref state); + finishedSerializing = HandleDictionary(state.Current.JsonClassInfo.ElementClassInfo!, options, writer, ref state); break; default: Debug.Assert(state.Current.JsonClassInfo.ClassType == ClassType.Object || diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs index 9be3015f510dc6..11f6e5d322eeaa 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs @@ -23,7 +23,7 @@ public sealed partial class JsonSerializerOptions private static readonly List s_defaultFactoryConverters = GetDefaultConverters(); // The cached converters (custom or built-in). - private readonly ConcurrentDictionary _converters = new ConcurrentDictionary(); + private readonly ConcurrentDictionary _converters = new ConcurrentDictionary(); private static Dictionary GetDefaultSimpleConverters() { @@ -32,7 +32,7 @@ private static Dictionary GetDefaultSimpleConverters() // Use a dictionary for simple converters. foreach (JsonConverter converter in DefaultSimpleConverters) { - converters.Add(converter.TypeToConvert, converter); + converters.Add(converter.TypeToConvert!, converter); } Debug.Assert(NumberOfSimpleConverters == converters.Count); @@ -65,14 +65,14 @@ private static List GetDefaultConverters() /// public IList Converters { get; } - internal JsonConverter DetermineConverterForProperty(Type parentClassType, Type runtimePropertyType, PropertyInfo propertyInfo) + internal JsonConverter? DetermineConverterForProperty(Type parentClassType, Type runtimePropertyType, PropertyInfo? propertyInfo) { - JsonConverter converter = null; + JsonConverter? converter = null; // Priority 1: attempt to get converter from JsonConverterAttribute on property. if (propertyInfo != null) { - JsonConverterAttribute converterAttribute = (JsonConverterAttribute) + JsonConverterAttribute? converterAttribute = (JsonConverterAttribute?) GetAttributeThatCanHaveMultiple(parentClassType, typeof(JsonConverterAttribute), propertyInfo); if (converterAttribute != null) @@ -101,9 +101,9 @@ internal JsonConverter DetermineConverterForProperty(Type parentClassType, Type /// /// The first converter that supports the given type, or null if there is no converter. /// - public JsonConverter GetConverter(Type typeToConvert) + public JsonConverter? GetConverter(Type typeToConvert) { - if (_converters.TryGetValue(typeToConvert, out JsonConverter converter)) + if (_converters.TryGetValue(typeToConvert, out JsonConverter? converter)) { return converter; } @@ -122,7 +122,7 @@ public JsonConverter GetConverter(Type typeToConvert) // Priority 3: Attempt to get converter from [JsonConverter] on the type being converted. if (converter == null) { - JsonConverterAttribute converterAttribute = (JsonConverterAttribute) + JsonConverterAttribute? converterAttribute = (JsonConverterAttribute?) GetAttributeThatCanHaveMultiple(typeToConvert, typeof(JsonConverterAttribute)); if (converterAttribute != null) @@ -134,7 +134,7 @@ public JsonConverter GetConverter(Type typeToConvert) // Priority 4: Attempt to get built-in converter. if (converter == null) { - if (s_defaultSimpleConverters.TryGetValue(typeToConvert, out JsonConverter foundConverter)) + if (s_defaultSimpleConverters.TryGetValue(typeToConvert, out JsonConverter? foundConverter)) { converter = foundConverter; } @@ -163,6 +163,7 @@ public JsonConverter GetConverter(Type typeToConvert) if (converter != null) { + Debug.Assert(converter.TypeToConvert != null); Type converterTypeToConvert = converter.TypeToConvert; if (!converterTypeToConvert.IsAssignableFrom(typeToConvert) && @@ -189,11 +190,11 @@ internal bool HasConverter(Type typeToConvert) return GetConverter(typeToConvert) != null; } - private JsonConverter GetConverterFromAttribute(JsonConverterAttribute converterAttribute, Type typeToConvert, Type classTypeAttributeIsOn, PropertyInfo propertyInfo) + private JsonConverter GetConverterFromAttribute(JsonConverterAttribute converterAttribute, Type typeToConvert, Type classTypeAttributeIsOn, PropertyInfo? propertyInfo) { - JsonConverter converter; + JsonConverter? converter; - Type type = converterAttribute.ConverterType; + Type? type = converterAttribute.ConverterType; if (type == null) { // Allow the attribute to create the converter. @@ -205,15 +206,16 @@ private JsonConverter GetConverterFromAttribute(JsonConverterAttribute converter } else { - ConstructorInfo ctor = type.GetConstructor(Type.EmptyTypes); + ConstructorInfo ctor = type.GetConstructor(Type.EmptyTypes)!; if (!typeof(JsonConverter).IsAssignableFrom(type) || !ctor.IsPublic) { ThrowHelper.ThrowInvalidOperationException_SerializationConverterOnAttributeInvalid(classTypeAttributeIsOn, propertyInfo); } - converter = (JsonConverter)Activator.CreateInstance(type); + converter = (JsonConverter?)Activator.CreateInstance(type); } + Debug.Assert(converter != null); if (!converter.CanConvert(typeToConvert)) { ThrowHelper.ThrowInvalidOperationException_SerializationConverterOnAttributeNotCompatible(classTypeAttributeIsOn, propertyInfo, typeToConvert); @@ -222,19 +224,19 @@ private JsonConverter GetConverterFromAttribute(JsonConverterAttribute converter return converter; } - private static Attribute GetAttributeThatCanHaveMultiple(Type classType, Type attributeType, PropertyInfo propertyInfo) + private static Attribute? GetAttributeThatCanHaveMultiple(Type classType, Type attributeType, PropertyInfo propertyInfo) { - object[] attributes = propertyInfo?.GetCustomAttributes(attributeType, inherit: false); + object[] attributes = propertyInfo.GetCustomAttributes(attributeType, inherit: false); return GetAttributeThatCanHaveMultiple(attributeType, classType, propertyInfo, attributes); } - private static Attribute GetAttributeThatCanHaveMultiple(Type classType, Type attributeType) + private static Attribute? GetAttributeThatCanHaveMultiple(Type classType, Type attributeType) { object[] attributes = classType.GetCustomAttributes(attributeType, inherit: false); return GetAttributeThatCanHaveMultiple(attributeType, classType, null, attributes); } - private static Attribute GetAttributeThatCanHaveMultiple(Type attributeType, Type classType, PropertyInfo propertyInfo, object[] attributes) + private static Attribute? GetAttributeThatCanHaveMultiple(Type attributeType, Type classType, PropertyInfo? propertyInfo, object[] attributes) { if (attributes.Length == 0) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs index c4f78503c7538d..c4568ed3c6e70f 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs @@ -6,6 +6,7 @@ using System.Diagnostics; using System.Text.Json.Serialization; using System.Text.Encodings.Web; +using System.Diagnostics.CodeAnalysis; namespace System.Text.Json { @@ -19,12 +20,12 @@ public sealed partial class JsonSerializerOptions internal static readonly JsonSerializerOptions s_defaultOptions = new JsonSerializerOptions(); private readonly ConcurrentDictionary _classes = new ConcurrentDictionary(); - private static readonly ConcurrentDictionary s_createRangeDelegates = new ConcurrentDictionary(); - private MemberAccessor _memberAccessorStrategy; - private JsonNamingPolicy _dictionayKeyPolicy; - private JsonNamingPolicy _jsonPropertyNamingPolicy; + private static readonly ConcurrentDictionary s_createRangeDelegates = new ConcurrentDictionary(); + private MemberAccessor? _memberAccessorStrategy; + private JsonNamingPolicy? _dictionayKeyPolicy; + private JsonNamingPolicy? _jsonPropertyNamingPolicy; private JsonCommentHandling _readCommentHandling; - private JavaScriptEncoder _encoder; + private JavaScriptEncoder? _encoder; private int _defaultBufferSize = BufferSizeDefault; private int _maxDepth; private bool _allowTrailingCommas; @@ -95,7 +96,7 @@ public int DefaultBufferSize /// /// The encoder to use when escaping strings, or to use the default encoder. /// - public JavaScriptEncoder Encoder + public JavaScriptEncoder? Encoder { get { @@ -116,7 +117,7 @@ public JavaScriptEncoder Encoder /// This property can be set to to specify a camel-casing policy. /// It is not used when deserializing. /// - public JsonNamingPolicy DictionaryKeyPolicy + public JsonNamingPolicy? DictionaryKeyPolicy { get { @@ -214,7 +215,7 @@ public int MaxDepth /// The policy is not used for properties that have a applied. /// This property can be set to to specify a camel-casing policy. /// - public JsonNamingPolicy PropertyNamingPolicy + public JsonNamingPolicy? PropertyNamingPolicy { get { @@ -319,7 +320,7 @@ internal JsonClassInfo GetOrAddClass(Type classType) _haveTypesBeenCreated = true; // todo: for performance and reduced instances, consider using the converters and JsonClassInfo from s_defaultOptions by cloning (or reference directly if no changes). - if (!_classes.TryGetValue(classType, out JsonClassInfo result)) + if (!_classes.TryGetValue(classType, out JsonClassInfo? result)) { result = _classes.GetOrAdd(classType, new JsonClassInfo(classType, this)); } @@ -354,12 +355,12 @@ internal bool CreateRangeDelegatesContainsKey(string key) return s_createRangeDelegates.ContainsKey(key); } - internal bool TryGetCreateRangeDelegate(string delegateKey, out ImmutableCollectionCreator createRangeDelegate) + internal bool TryGetCreateRangeDelegate(string delegateKey, [NotNullWhen(true)] out ImmutableCollectionCreator? createRangeDelegate) { return s_createRangeDelegates.TryGetValue(delegateKey, out createRangeDelegate) && createRangeDelegate != null; } - internal bool TryAddCreateRangeDelegate(string key, ImmutableCollectionCreator createRangeDelegate) + internal bool TryAddCreateRangeDelegate(string key, ImmutableCollectionCreator? createRangeDelegate) { return s_createRangeDelegates.TryAdd(key, createRangeDelegate); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonStringEnumConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonStringEnumConverter.cs index 9daddb0b63b41d..3c0973afdda5b4 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonStringEnumConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonStringEnumConverter.cs @@ -16,7 +16,7 @@ namespace System.Text.Json.Serialization /// public sealed class JsonStringEnumConverter : JsonConverterFactory { - private readonly JsonNamingPolicy _namingPolicy; + private readonly JsonNamingPolicy? _namingPolicy; private readonly EnumConverterOptions _converterOptions; /// @@ -39,7 +39,7 @@ public JsonStringEnumConverter() /// True to allow undefined enum values. When true, if an enum value isn't /// defined it will output as a number rather than a string. /// - public JsonStringEnumConverter(JsonNamingPolicy namingPolicy = null, bool allowIntegerValues = true) + public JsonStringEnumConverter(JsonNamingPolicy? namingPolicy = null, bool allowIntegerValues = true) { _namingPolicy = namingPolicy; _converterOptions = allowIntegerValues @@ -57,14 +57,14 @@ public override bool CanConvert(Type typeToConvert) [PreserveDependency( ".ctor(System.Text.Json.Serialization.Converters.EnumConverterOptions, System.Text.Json.JsonNamingPolicy)", "System.Text.Json.Serialization.Converters.JsonConverterEnum`1")] - public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) + public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions? options) { JsonConverter converter = (JsonConverter)Activator.CreateInstance( typeof(JsonConverterEnum<>).MakeGenericType(typeToConvert), BindingFlags.Instance | BindingFlags.Public, binder: null, - new object[] { _converterOptions, _namingPolicy }, - culture: null); + new object?[] { _converterOptions, _namingPolicy }, + culture: null)!; return converter; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/MemberAccessor.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/MemberAccessor.cs index c3b31ad300b49d..ca9eaa3e41e3f4 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/MemberAccessor.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/MemberAccessor.cs @@ -9,17 +9,17 @@ namespace System.Text.Json { internal abstract class MemberAccessor { - public abstract JsonClassInfo.ConstructorDelegate CreateConstructor(Type classType); + public abstract JsonClassInfo.ConstructorDelegate? CreateConstructor(Type classType); public abstract Action CreateAddDelegate(MethodInfo addMethod, object target); - public abstract ImmutableCollectionCreator ImmutableCollectionCreateRange(Type constructingType, Type collectionType, Type elementType); + public abstract ImmutableCollectionCreator? ImmutableCollectionCreateRange(Type constructingType, Type collectionType, Type elementType); - public abstract ImmutableCollectionCreator ImmutableDictionaryCreateRange(Type constructingType, Type collectionType, Type elementType); + public abstract ImmutableCollectionCreator? ImmutableDictionaryCreateRange(Type constructingType, Type collectionType, Type elementType); - protected MethodInfo ImmutableCollectionCreateRangeMethod(Type constructingType, Type elementType) + protected MethodInfo? ImmutableCollectionCreateRangeMethod(Type constructingType, Type elementType) { - MethodInfo createRangeMethod = FindImmutableCreateRangeMethod(constructingType); + MethodInfo? createRangeMethod = FindImmutableCreateRangeMethod(constructingType); if (createRangeMethod == null) { @@ -29,9 +29,9 @@ protected MethodInfo ImmutableCollectionCreateRangeMethod(Type constructingType, return createRangeMethod.MakeGenericMethod(elementType); } - protected MethodInfo ImmutableDictionaryCreateRangeMethod(Type constructingType, Type elementType) + protected MethodInfo? ImmutableDictionaryCreateRangeMethod(Type constructingType, Type elementType) { - MethodInfo createRangeMethod = FindImmutableCreateRangeMethod(constructingType); + MethodInfo? createRangeMethod = FindImmutableCreateRangeMethod(constructingType); if (createRangeMethod == null) { @@ -41,7 +41,7 @@ protected MethodInfo ImmutableDictionaryCreateRangeMethod(Type constructingType, return createRangeMethod.MakeGenericMethod(typeof(string), elementType); } - private MethodInfo FindImmutableCreateRangeMethod(Type constructingType) + private MethodInfo? FindImmutableCreateRangeMethod(Type constructingType) { MethodInfo[] constructingTypeMethods = constructingType.GetMethods(); @@ -60,8 +60,8 @@ private MethodInfo FindImmutableCreateRangeMethod(Type constructingType) return null; } - public abstract Func CreatePropertyGetter(PropertyInfo propertyInfo); + public abstract Func CreatePropertyGetter(PropertyInfo propertyInfo); - public abstract Action CreatePropertySetter(PropertyInfo propertyInfo); + public abstract Action CreatePropertySetter(PropertyInfo propertyInfo); } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/PooledByteBufferWriter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/PooledByteBufferWriter.cs index 585094523e682f..a94a5544fd0e68 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/PooledByteBufferWriter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/PooledByteBufferWriter.cs @@ -12,7 +12,7 @@ namespace System.Text.Json { internal sealed class PooledByteBufferWriter : IBufferWriter, IDisposable { - private byte[] _rentedBuffer; + private byte[]? _rentedBuffer; private int _index; private const int MinimumBufferSize = 256; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStack.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStack.cs index f63a6c6355b4ca..1063ffd7d51773 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStack.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStack.cs @@ -70,7 +70,7 @@ public string JsonPath() private void AppendStackFrame(StringBuilder sb, in ReadStackFrame frame) { // Append the property name. - string propertyName = GetPropertyName(frame); + string? propertyName = GetPropertyName(frame); AppendPropertyName(sb, propertyName); if (frame.JsonClassInfo != null) @@ -82,11 +82,11 @@ private void AppendStackFrame(StringBuilder sb, in ReadStackFrame frame) } else if (frame.IsProcessingEnumerable()) { - IList list = frame.TempEnumerableValues; + IList? list = frame.TempEnumerableValues; if (list == null && frame.ReturnValue != null) { - list = (IList)frame.JsonPropertyInfo?.GetValueAsObject(frame.ReturnValue); + list = (IList?)frame.JsonPropertyInfo?.GetValueAsObject(frame.ReturnValue); } if (list != null) { @@ -98,7 +98,7 @@ private void AppendStackFrame(StringBuilder sb, in ReadStackFrame frame) } } - private void AppendPropertyName(StringBuilder sb, string propertyName) + private void AppendPropertyName(StringBuilder sb, string? propertyName) { if (propertyName != null) { @@ -116,17 +116,17 @@ private void AppendPropertyName(StringBuilder sb, string propertyName) } } - private string GetPropertyName(in ReadStackFrame frame) + private string? GetPropertyName(in ReadStackFrame frame) { // Attempt to get the JSON property name from the frame. - byte[] utf8PropertyName = frame.JsonPropertyName; + byte[]? utf8PropertyName = frame.JsonPropertyName; if (utf8PropertyName == null) { // Attempt to get the JSON property name from the JsonPropertyInfo. utf8PropertyName = frame.JsonPropertyInfo?.JsonPropertyName; } - string propertyName; + string? propertyName; if (utf8PropertyName != null) { propertyName = JsonHelpers.Utf8GetString(utf8PropertyName); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStackFrame.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStackFrame.cs index f9d064cd3b8f4e..a0a8a18d6c510b 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStackFrame.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStackFrame.cs @@ -13,23 +13,23 @@ namespace System.Text.Json internal struct ReadStackFrame { // The object (POCO or IEnumerable) that is being populated - public object ReturnValue; + public object? ReturnValue; public JsonClassInfo JsonClassInfo; // Support Dictionary keys. - public string KeyName; + public string? KeyName; // Support JSON Path on exceptions. - public byte[] JsonPropertyName; + public byte[]? JsonPropertyName; // Current property values. - public JsonPropertyInfo JsonPropertyInfo; + public JsonPropertyInfo? JsonPropertyInfo; // Delegate used to add elements to the current property. - public object AddObjectToEnumerable; + public object? AddObjectToEnumerable; // Support System.Array and other types that don't implement IList. - public IList TempEnumerableValues; + public IList? TempEnumerableValues; // Has an array or dictionary property been initialized. public bool CollectionPropertyInitialized; @@ -40,11 +40,11 @@ internal struct ReadStackFrame // Support IDictionary constructible types, i.e. types that we // support by passing and IDictionary to their constructors: // immutable dictionaries, Hashtable, SortedList - public IDictionary TempDictionaryValues; + public IDictionary? TempDictionaryValues; // For performance, we order the properties by the first deserialize and PropertyIndex helps find the right slot quicker. public int PropertyIndex; - public List PropertyRefCache; + public List? PropertyRefCache; /// /// Is the current object an Enumerable or Dictionary. @@ -124,6 +124,7 @@ public bool IsProcessingValue() if (CollectionPropertyInitialized) { + Debug.Assert(JsonPropertyInfo != null && JsonPropertyInfo.ElementClassInfo != null); classType = JsonPropertyInfo.ElementClassInfo.ClassType; } else if (JsonPropertyInfo == null) @@ -159,7 +160,7 @@ public void InitializeJsonPropertyInfo() public void Reset() { Drain = false; - JsonClassInfo = null; + JsonClassInfo = null!; PropertyRefCache = null; ReturnValue = null; EndObject(); @@ -182,18 +183,19 @@ public void EndProperty() KeyName = null; } - public static object CreateEnumerableValue(ref ReadStack state) + public static object? CreateEnumerableValue(ref ReadStack state) { + Debug.Assert(state.Current.JsonPropertyInfo != null); JsonPropertyInfo jsonPropertyInfo = state.Current.JsonPropertyInfo; // If the property has an EnumerableConverter, then we use tempEnumerableValues. if (jsonPropertyInfo.EnumerableConverter != null) { IList converterList; - JsonClassInfo elementClassInfo = jsonPropertyInfo.ElementClassInfo; + JsonClassInfo elementClassInfo = jsonPropertyInfo.ElementClassInfo!; if (elementClassInfo.ClassType == ClassType.Value) { - converterList = elementClassInfo.PolicyProperty.CreateConverterList(); + converterList = elementClassInfo.PolicyProperty!.CreateConverterList(); } else { @@ -221,18 +223,19 @@ public static object CreateEnumerableValue(ref ReadStack state) return runtimeClassInfo.CreateObject(); } - public static object CreateDictionaryValue(ref ReadStack state) + public static object? CreateDictionaryValue(ref ReadStack state) { + Debug.Assert(state.Current.JsonPropertyInfo != null); JsonPropertyInfo jsonPropertyInfo = state.Current.JsonPropertyInfo; // If the property has a DictionaryConverter, then we use tempDictionaryValues. if (jsonPropertyInfo.DictionaryConverter != null) { IDictionary converterDictionary; - JsonClassInfo elementClassInfo = jsonPropertyInfo.ElementClassInfo; + JsonClassInfo elementClassInfo = jsonPropertyInfo.ElementClassInfo!; if (elementClassInfo.ClassType == ClassType.Value) { - converterDictionary = elementClassInfo.PolicyProperty.CreateConverterDictionary(); + converterDictionary = elementClassInfo.PolicyProperty!.CreateConverterDictionary(); } else { @@ -262,20 +265,21 @@ public static object CreateDictionaryValue(ref ReadStack state) public Type GetElementType() { + Debug.Assert(JsonPropertyInfo != null); if (IsProcessingCollectionProperty()) { - return JsonPropertyInfo.ElementClassInfo.Type; + return JsonPropertyInfo.ElementClassInfo!.Type; } if (IsProcessingCollectionObject()) { - return JsonClassInfo.ElementClassInfo.Type; + return JsonClassInfo.ElementClassInfo!.Type; } return JsonPropertyInfo.RuntimePropertyType; } - public static IEnumerable GetEnumerableValue(ref ReadStackFrame current) + public static IEnumerable? GetEnumerableValue(ref ReadStackFrame current) { if (current.IsProcessingObject(ClassType.Enumerable)) { @@ -291,11 +295,11 @@ public static IEnumerable GetEnumerableValue(ref ReadStackFrame current) public void DetermineEnumerablePopulationStrategy(object targetEnumerable) { - Debug.Assert(JsonPropertyInfo.ClassType == ClassType.Enumerable); + Debug.Assert(JsonPropertyInfo!.ClassType == ClassType.Enumerable); if (JsonPropertyInfo.RuntimeClassInfo.AddItemToObject != null) { - if (!JsonPropertyInfo.TryCreateEnumerableAddMethod(targetEnumerable, out object addMethodDelegate)) + if (!JsonPropertyInfo.TryCreateEnumerableAddMethod(targetEnumerable, out object? addMethodDelegate)) { // No "add" method for this collection, hence, not supported for deserialization. throw ThrowHelper.GetNotSupportedException_SerializationNotSupportedCollection( @@ -328,7 +332,7 @@ public void DetermineEnumerablePopulationStrategy(object targetEnumerable) public void DetermineIfDictionaryCanBePopulated(object targetDictionary) { - Debug.Assert(JsonPropertyInfo.ClassType == ClassType.Dictionary); + Debug.Assert(JsonPropertyInfo!.ClassType == ClassType.Dictionary); if (!JsonPropertyInfo.CanPopulateDictionary(targetDictionary)) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReflectionEmitMemberAccessor.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReflectionEmitMemberAccessor.cs index 323174d6466aad..5ec012d30feca7 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReflectionEmitMemberAccessor.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReflectionEmitMemberAccessor.cs @@ -12,10 +12,10 @@ namespace System.Text.Json { internal sealed class ReflectionEmitMemberAccessor : MemberAccessor { - public override JsonClassInfo.ConstructorDelegate CreateConstructor(Type type) + public override JsonClassInfo.ConstructorDelegate? CreateConstructor(Type type) { Debug.Assert(type != null); - ConstructorInfo realMethod = type.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, binder: null, Type.EmptyTypes, modifiers: null); + ConstructorInfo? realMethod = type.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, binder: null, Type.EmptyTypes, modifiers: null); if (type.IsAbstract) { @@ -62,9 +62,9 @@ public override Action CreateAddDelegate(MethodInfo addMet } [PreserveDependency(".ctor()", "System.Text.Json.ImmutableEnumerableCreator`2")] - public override ImmutableCollectionCreator ImmutableCollectionCreateRange(Type constructingType, Type collectionType, Type elementType) + public override ImmutableCollectionCreator? ImmutableCollectionCreateRange(Type constructingType, Type collectionType, Type elementType) { - MethodInfo createRange = ImmutableCollectionCreateRangeMethod(constructingType, elementType); + MethodInfo? createRange = ImmutableCollectionCreateRangeMethod(constructingType, elementType); if (createRange == null) { @@ -73,7 +73,7 @@ public override ImmutableCollectionCreator ImmutableCollectionCreateRange(Type c Type creatorType = typeof(ImmutableEnumerableCreator<,>).MakeGenericType(elementType, collectionType); - ConstructorInfo realMethod = creatorType.GetConstructor( + ConstructorInfo? realMethod = creatorType.GetConstructor( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, binder: null, Type.EmptyTypes, @@ -95,14 +95,14 @@ public override ImmutableCollectionCreator ImmutableCollectionCreateRange(Type c JsonClassInfo.ConstructorDelegate constructor = (JsonClassInfo.ConstructorDelegate)dynamicMethod.CreateDelegate( typeof(JsonClassInfo.ConstructorDelegate)); - ImmutableCollectionCreator creator = (ImmutableCollectionCreator)constructor(); + ImmutableCollectionCreator creator = (ImmutableCollectionCreator)constructor()!; creator.RegisterCreatorDelegateFromMethod(createRange); return creator; } [PreserveDependency(".ctor()", "System.Text.Json.ImmutableDictionaryCreator`2")] - public override ImmutableCollectionCreator ImmutableDictionaryCreateRange(Type constructingType, Type collectionType, Type elementType) + public override ImmutableCollectionCreator? ImmutableDictionaryCreateRange(Type constructingType, Type collectionType, Type elementType) { Debug.Assert(collectionType.IsGenericType); @@ -112,7 +112,7 @@ public override ImmutableCollectionCreator ImmutableDictionaryCreateRange(Type c throw ThrowHelper.GetNotSupportedException_SerializationNotSupportedCollection(collectionType, parentType: null, memberInfo: null); } - MethodInfo createRange = ImmutableDictionaryCreateRangeMethod(constructingType, elementType); + MethodInfo? createRange = ImmutableDictionaryCreateRangeMethod(constructingType, elementType); if (createRange == null) { @@ -121,7 +121,7 @@ public override ImmutableCollectionCreator ImmutableDictionaryCreateRange(Type c Type creatorType = typeof(ImmutableDictionaryCreator<,>).MakeGenericType(elementType, collectionType); - ConstructorInfo realMethod = creatorType.GetConstructor( + ConstructorInfo? realMethod = creatorType.GetConstructor( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, binder: null, Type.EmptyTypes, @@ -143,20 +143,21 @@ public override ImmutableCollectionCreator ImmutableDictionaryCreateRange(Type c JsonClassInfo.ConstructorDelegate constructor = (JsonClassInfo.ConstructorDelegate)dynamicMethod.CreateDelegate( typeof(JsonClassInfo.ConstructorDelegate)); - ImmutableCollectionCreator creator = (ImmutableCollectionCreator)constructor(); + ImmutableCollectionCreator creator = (ImmutableCollectionCreator)constructor()!; creator.RegisterCreatorDelegateFromMethod(createRange); return creator; } - public override Func CreatePropertyGetter(PropertyInfo propertyInfo) => - (Func)CreatePropertyGetter(propertyInfo, typeof(TClass)); + public override Func CreatePropertyGetter(PropertyInfo propertyInfo) => + (Func)CreatePropertyGetter(propertyInfo, typeof(TClass)); private static Delegate CreatePropertyGetter(PropertyInfo propertyInfo, Type classType) { - MethodInfo realMethod = propertyInfo.GetGetMethod(); + MethodInfo? realMethod = propertyInfo.GetGetMethod(); Type objectType = typeof(object); + Debug.Assert(realMethod != null); var dynamicMethod = new DynamicMethod( realMethod.Name, propertyInfo.PropertyType, @@ -184,14 +185,15 @@ private static Delegate CreatePropertyGetter(PropertyInfo propertyInfo, Type cla return dynamicMethod.CreateDelegate(typeof(Func<,>).MakeGenericType(objectType, propertyInfo.PropertyType)); } - public override Action CreatePropertySetter(PropertyInfo propertyInfo) => - (Action)CreatePropertySetter(propertyInfo, typeof(TClass)); + public override Action CreatePropertySetter(PropertyInfo propertyInfo) => + (Action)CreatePropertySetter(propertyInfo, typeof(TClass)); private static Delegate CreatePropertySetter(PropertyInfo propertyInfo, Type classType) { - MethodInfo realMethod = propertyInfo.GetSetMethod(); + MethodInfo? realMethod = propertyInfo.GetSetMethod(); Type objectType = typeof(object); + Debug.Assert(realMethod != null); var dynamicMethod = new DynamicMethod( realMethod.Name, typeof(void), diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReflectionMemberAccessor.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReflectionMemberAccessor.cs index 819dcc2d99094f..7cdcf07575d729 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReflectionMemberAccessor.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReflectionMemberAccessor.cs @@ -16,18 +16,18 @@ internal sealed class ReflectionMemberAccessor : MemberAccessor private delegate void SetProperty(TClass obj, TProperty value); private delegate void SetPropertyByRef(ref TClass obj, TProperty value); - private delegate Func GetPropertyByRefFactory(GetPropertyByRef set); - private delegate Action SetPropertyByRefFactory(SetPropertyByRef set); + private delegate Func GetPropertyByRefFactory(GetPropertyByRef set); + private delegate Action SetPropertyByRefFactory(SetPropertyByRef set); - private static readonly MethodInfo s_createStructPropertyGetterMethod = new GetPropertyByRefFactory(CreateStructPropertyGetter) + private static readonly MethodInfo s_createStructPropertyGetterMethod = new GetPropertyByRefFactory(CreateStructPropertyGetter!) .Method.GetGenericMethodDefinition(); - private static readonly MethodInfo s_createStructPropertySetterMethod = new SetPropertyByRefFactory(CreateStructPropertySetter) + private static readonly MethodInfo s_createStructPropertySetterMethod = new SetPropertyByRefFactory(CreateStructPropertySetter!) .Method.GetGenericMethodDefinition(); - public override JsonClassInfo.ConstructorDelegate CreateConstructor(Type type) + public override JsonClassInfo.ConstructorDelegate? CreateConstructor(Type type) { Debug.Assert(type != null); - ConstructorInfo realMethod = type.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, binder: null, Type.EmptyTypes, modifiers: null); + ConstructorInfo? realMethod = type.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, binder: null, Type.EmptyTypes, modifiers: null); if (type.IsAbstract) { @@ -49,9 +49,9 @@ public override Action CreateAddDelegate(MethodInfo addMet } [PreserveDependency(".ctor()", "System.Text.Json.ImmutableEnumerableCreator`2")] - public override ImmutableCollectionCreator ImmutableCollectionCreateRange(Type constructingType, Type collectionType, Type elementType) + public override ImmutableCollectionCreator? ImmutableCollectionCreateRange(Type constructingType, Type collectionType, Type elementType) { - MethodInfo createRange = ImmutableCollectionCreateRangeMethod(constructingType, elementType); + MethodInfo? createRange = ImmutableCollectionCreateRangeMethod(constructingType, elementType); if (createRange == null) { @@ -64,7 +64,7 @@ public override ImmutableCollectionCreator ImmutableCollectionCreateRange(Type c BindingFlags.NonPublic | BindingFlags.Instance, binder: null, Type.EmptyTypes, - modifiers: null); + modifiers: null)!; ImmutableCollectionCreator creator = (ImmutableCollectionCreator)constructor.Invoke(Array.Empty()); creator.RegisterCreatorDelegateFromMethod(createRange); @@ -72,7 +72,7 @@ public override ImmutableCollectionCreator ImmutableCollectionCreateRange(Type c } [PreserveDependency(".ctor()", "System.Text.Json.ImmutableDictionaryCreator`2")] - public override ImmutableCollectionCreator ImmutableDictionaryCreateRange(Type constructingType, Type collectionType, Type elementType) + public override ImmutableCollectionCreator? ImmutableDictionaryCreateRange(Type constructingType, Type collectionType, Type elementType) { Debug.Assert(collectionType.IsGenericType); @@ -82,7 +82,7 @@ public override ImmutableCollectionCreator ImmutableDictionaryCreateRange(Type c throw ThrowHelper.GetNotSupportedException_SerializationNotSupportedCollection(collectionType, parentType: null, memberInfo: null); } - MethodInfo createRange = ImmutableDictionaryCreateRangeMethod(constructingType, elementType); + MethodInfo? createRange = ImmutableDictionaryCreateRangeMethod(constructingType, elementType); if (createRange == null) { @@ -95,16 +95,16 @@ public override ImmutableCollectionCreator ImmutableDictionaryCreateRange(Type c BindingFlags.NonPublic | BindingFlags.Instance, binder: null, Type.EmptyTypes, - modifiers: null); + modifiers: null)!; ImmutableCollectionCreator creator = (ImmutableCollectionCreator)constructor.Invoke(Array.Empty()); creator.RegisterCreatorDelegateFromMethod(createRange); return creator; } - public override Func CreatePropertyGetter(PropertyInfo propertyInfo) + public override Func CreatePropertyGetter(PropertyInfo propertyInfo) { - MethodInfo getMethodInfo = propertyInfo.GetGetMethod(); + MethodInfo getMethodInfo = propertyInfo.GetGetMethod()!; if (typeof(TClass).IsValueType) { @@ -116,16 +116,16 @@ public override Func CreatePropertyGetter( else { var propertyGetter = CreateDelegate>(getMethodInfo); - return delegate (object obj) + return delegate (object? obj) { - return propertyGetter((TClass)obj); + return propertyGetter((TClass)obj!); }; } } - public override Action CreatePropertySetter(PropertyInfo propertyInfo) + public override Action CreatePropertySetter(PropertyInfo propertyInfo) { - MethodInfo setMethodInfo = propertyInfo.GetSetMethod(); + MethodInfo setMethodInfo = propertyInfo.GetSetMethod()!; if (typeof(TClass).IsValueType) { @@ -137,9 +137,9 @@ public override Action CreatePropertySetter>(setMethodInfo); - return delegate (object obj, TProperty value) + return delegate (object? obj, TProperty value) { - propertySetter((TClass)obj, value); + propertySetter((TClass)obj!, value); }; } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/WriteStack.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/WriteStack.cs index a9157b23aa0a1c..23cc8041800550 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/WriteStack.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/WriteStack.cs @@ -39,7 +39,7 @@ public void Push() _index++; } - public void Push(JsonClassInfo nextClassInfo, object nextValue) + public void Push(JsonClassInfo nextClassInfo, object? nextValue) { Push(); Current.JsonClassInfo = nextClassInfo; @@ -50,7 +50,7 @@ public void Push(JsonClassInfo nextClassInfo, object nextValue) if (classType == ClassType.Enumerable || nextClassInfo.ClassType == ClassType.Dictionary) { Current.PopStackOnEndCollection = true; - Current.JsonPropertyInfo = Current.JsonClassInfo.PolicyProperty; + Current.JsonPropertyInfo = Current.JsonClassInfo.PolicyProperty!; } else { @@ -84,11 +84,11 @@ public string PropertyPath() private void AppendStackFrame(StringBuilder sb, in WriteStackFrame frame) { // Append the property name. - string propertyName = frame.JsonPropertyInfo?.PropertyInfo?.Name; + string? propertyName = frame.JsonPropertyInfo?.PropertyInfo?.Name; AppendPropertyName(sb, propertyName); } - private void AppendPropertyName(StringBuilder sb, string propertyName) + private void AppendPropertyName(StringBuilder sb, string? propertyName) { if (propertyName != null) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/WriteStackFrame.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/WriteStackFrame.cs index afa42b75a9fa7b..3a5adcea79dc17 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/WriteStackFrame.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/WriteStackFrame.cs @@ -12,14 +12,14 @@ namespace System.Text.Json internal struct WriteStackFrame { // The object (POCO or IEnumerable) that is being populated. - public object CurrentValue; - public JsonClassInfo JsonClassInfo; + public object? CurrentValue; + public JsonClassInfo? JsonClassInfo; // Support Dictionary keys. - public string KeyName; + public string? KeyName; // The current IEnumerable or IDictionary. - public IEnumerator CollectionEnumerator; + public IEnumerator? CollectionEnumerator; // Note all bools are kept together for packing: public bool PopStackOnEndCollection; @@ -31,7 +31,7 @@ internal struct WriteStackFrame // The current property. public int PropertyEnumeratorIndex; public ExtensionDataWriteStatus ExtensionDataStatus; - public JsonPropertyInfo JsonPropertyInfo; + public JsonPropertyInfo? JsonPropertyInfo; public void Initialize(Type type, JsonSerializerOptions options) { @@ -46,7 +46,7 @@ public void WriteObjectOrArrayStart(ClassType classType, Utf8JsonWriter writer, { if (JsonPropertyInfo?.EscapedName.HasValue == true) { - WriteObjectOrArrayStart(classType, JsonPropertyInfo.EscapedName.Value, writer, writeNull); + WriteObjectOrArrayStart(classType, JsonPropertyInfo.EscapedName!.Value, writer, writeNull); } else if (KeyName != null) { @@ -129,6 +129,7 @@ public void NextProperty() { EndProperty(); + Debug.Assert(JsonClassInfo != null && JsonClassInfo.PropertyCacheArray != null); int maxPropertyIndex = JsonClassInfo.PropertyCacheArray.Length; ++PropertyEnumeratorIndex; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs b/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs index 9cd7589737a4c0..c516dfbf4f9361 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.CompilerServices; using System.Text.Json.Serialization; @@ -12,13 +13,13 @@ namespace System.Text.Json internal static partial class ThrowHelper { [MethodImpl(MethodImplOptions.NoInlining)] - public static void ThrowArgumentException_DeserializeWrongType(Type type, object value) + public static void ThrowArgumentException_DeserializeWrongType(Type? type, object value) { throw new ArgumentException(SR.Format(SR.DeserializeWrongType, type, value.GetType())); } [MethodImpl(MethodImplOptions.NoInlining)] - public static NotSupportedException GetNotSupportedException_SerializationNotSupportedCollection(Type propertyType, Type parentType, MemberInfo memberInfo) + public static NotSupportedException GetNotSupportedException_SerializationNotSupportedCollection(Type? propertyType, Type? parentType, MemberInfo? memberInfo) { if (parentType != null && parentType != typeof(object) && memberInfo != null) { @@ -33,16 +34,18 @@ public static void ThrowInvalidOperationException_SerializerCycleDetected(int ma throw new JsonException(SR.Format(SR.SerializerCycleDetected, maxDepth)); } + [DoesNotReturn] [MethodImpl(MethodImplOptions.NoInlining)] - public static void ThrowJsonException_DeserializeUnableToConvertValue(Type propertyType) + public static void ThrowJsonException_DeserializeUnableToConvertValue(Type? propertyType) { var ex = new JsonException(SR.Format(SR.DeserializeUnableToConvertValue, propertyType)); ex.AppendPathInformation = true; throw ex; } + [DoesNotReturn] [MethodImpl(MethodImplOptions.NoInlining)] - public static void ThrowJsonException_DeserializeUnableToConvertValue(Type propertyType, string path, Exception innerException = null) + public static void ThrowJsonException_DeserializeUnableToConvertValue(Type? propertyType, string? path, Exception? innerException = null) { string message = SR.Format(SR.DeserializeUnableToConvertValue, propertyType) + $" Path: {path}."; throw new JsonException(message, path, null, null, innerException); @@ -55,7 +58,7 @@ public static void ThrowJsonException_DepthTooLarge(int currentDepth, JsonSerial } [MethodImpl(MethodImplOptions.NoInlining)] - public static void ThrowJsonException_SerializationConverterRead(JsonConverter converter) + public static void ThrowJsonException_SerializationConverterRead(JsonConverter? converter) { var ex = new JsonException(SR.Format(SR.SerializationConverterRead, converter)); ex.AppendPathInformation = true; @@ -63,13 +66,14 @@ public static void ThrowJsonException_SerializationConverterRead(JsonConverter c } [MethodImpl(MethodImplOptions.NoInlining)] - public static void ThrowJsonException_SerializationConverterWrite(JsonConverter converter) + public static void ThrowJsonException_SerializationConverterWrite(JsonConverter? converter) { var ex = new JsonException(SR.Format(SR.SerializationConverterWrite, converter)); ex.AppendPathInformation = true; throw ex; } + [DoesNotReturn] [MethodImpl(MethodImplOptions.NoInlining)] public static void ThrowJsonException() { @@ -77,13 +81,14 @@ public static void ThrowJsonException() } [MethodImpl(MethodImplOptions.NoInlining)] - public static void ThrowInvalidOperationException_SerializationConverterNotCompatible(Type converterType, Type type) + public static void ThrowInvalidOperationException_SerializationConverterNotCompatible(Type? converterType, Type? type) { throw new InvalidOperationException(SR.Format(SR.SerializationConverterNotCompatible, converterType, type)); } + [DoesNotReturn] [MethodImpl(MethodImplOptions.NoInlining)] - public static void ThrowInvalidOperationException_SerializationConverterOnAttributeInvalid(Type classType, PropertyInfo propertyInfo) + public static void ThrowInvalidOperationException_SerializationConverterOnAttributeInvalid(Type classType, PropertyInfo? propertyInfo) { string location = classType.ToString(); if (propertyInfo != null) @@ -94,8 +99,9 @@ public static void ThrowInvalidOperationException_SerializationConverterOnAttrib throw new InvalidOperationException(SR.Format(SR.SerializationConverterOnAttributeInvalid, location)); } + [DoesNotReturn] [MethodImpl(MethodImplOptions.NoInlining)] - public static void ThrowInvalidOperationException_SerializationConverterOnAttributeNotCompatible(Type classTypeAttributeIsOn, PropertyInfo propertyInfo, Type typeToConvert) + public static void ThrowInvalidOperationException_SerializationConverterOnAttributeNotCompatible(Type classTypeAttributeIsOn, PropertyInfo? propertyInfo, Type typeToConvert) { string location = classTypeAttributeIsOn.ToString(); @@ -116,13 +122,14 @@ public static void ThrowInvalidOperationException_SerializerOptionsImmutable() [MethodImpl(MethodImplOptions.NoInlining)] public static void ThrowInvalidOperationException_SerializerPropertyNameConflict(JsonClassInfo jsonClassInfo, JsonPropertyInfo jsonPropertyInfo) { - throw new InvalidOperationException(SR.Format(SR.SerializerPropertyNameConflict, jsonClassInfo.Type, jsonPropertyInfo.PropertyInfo.Name)); + throw new InvalidOperationException(SR.Format(SR.SerializerPropertyNameConflict, jsonClassInfo.Type, jsonPropertyInfo.PropertyInfo?.Name)); } + [DoesNotReturn] [MethodImpl(MethodImplOptions.NoInlining)] - public static void ThrowInvalidOperationException_SerializerPropertyNameNull(Type parentType, JsonPropertyInfo jsonPropertyInfo) + public static void ThrowInvalidOperationException_SerializerPropertyNameNull(Type? parentType, JsonPropertyInfo jsonPropertyInfo) { - throw new InvalidOperationException(SR.Format(SR.SerializerPropertyNameNull, parentType, jsonPropertyInfo.PropertyInfo.Name)); + throw new InvalidOperationException(SR.Format(SR.SerializerPropertyNameNull, parentType, jsonPropertyInfo.PropertyInfo?.Name)); } [MethodImpl(MethodImplOptions.NoInlining)] @@ -154,7 +161,7 @@ public static void ReThrowWithPath(in ReadStack readStack, JsonReaderException e } [MethodImpl(MethodImplOptions.NoInlining)] - public static void ReThrowWithPath(in ReadStack readStack, in Utf8JsonReader reader, Exception ex) + public static void ReThrowWithPath(in ReadStack readStack, in Utf8JsonReader reader, Exception? ex) { JsonException jsonException = new JsonException(null, ex); AddExceptionInformation(readStack, reader, jsonException); @@ -172,12 +179,12 @@ public static void AddExceptionInformation(in ReadStack readStack, in Utf8JsonRe string path = readStack.JsonPath(); ex.Path = path; - string message = ex.Message; + string? message = ex._message; if (string.IsNullOrEmpty(message)) { // Use a default message. - Type propertyType = readStack.Current.JsonPropertyInfo?.RuntimePropertyType; + Type? propertyType = readStack.Current.JsonPropertyInfo?.RuntimePropertyType; if (propertyType == null) { propertyType = readStack.Current.JsonClassInfo.Type; @@ -195,7 +202,7 @@ public static void AddExceptionInformation(in ReadStack readStack, in Utf8JsonRe } [MethodImpl(MethodImplOptions.NoInlining)] - public static void ReThrowWithPath(in WriteStack writeStack, Exception ex) + public static void ReThrowWithPath(in WriteStack writeStack, Exception? ex) { JsonException jsonException = new JsonException(null, ex); AddExceptionInformation(writeStack, jsonException); @@ -207,7 +214,7 @@ public static void AddExceptionInformation(in WriteStack writeStack, JsonExcepti string path = writeStack.PropertyPath(); ex.Path = path; - string message = ex.Message; + string? message = ex._message; if (string.IsNullOrEmpty(message)) { // Use a default message. @@ -222,8 +229,9 @@ public static void AddExceptionInformation(in WriteStack writeStack, JsonExcepti } } + [DoesNotReturn] [MethodImpl(MethodImplOptions.NoInlining)] - public static void ThrowInvalidOperationException_SerializationDuplicateAttribute(Type attribute, Type classType, PropertyInfo propertyInfo) + public static void ThrowInvalidOperationException_SerializationDuplicateAttribute(Type? attribute, Type classType, PropertyInfo? propertyInfo) { string location = classType.ToString(); if (propertyInfo != null) @@ -235,7 +243,7 @@ public static void ThrowInvalidOperationException_SerializationDuplicateAttribut } [MethodImpl(MethodImplOptions.NoInlining)] - public static void ThrowInvalidOperationException_SerializationDuplicateTypeAttribute(Type classType, Type attribute) + public static void ThrowInvalidOperationException_SerializationDuplicateTypeAttribute(Type? classType, Type? attribute) { throw new InvalidOperationException(SR.Format(SR.SerializationDuplicateTypeAttribute, classType, attribute)); } @@ -243,9 +251,10 @@ public static void ThrowInvalidOperationException_SerializationDuplicateTypeAttr [MethodImpl(MethodImplOptions.NoInlining)] public static void ThrowInvalidOperationException_SerializationDataExtensionPropertyInvalid(JsonClassInfo jsonClassInfo, JsonPropertyInfo jsonPropertyInfo) { - throw new InvalidOperationException(SR.Format(SR.SerializationDataExtensionPropertyInvalid, jsonClassInfo.Type, jsonPropertyInfo.PropertyInfo.Name)); + throw new InvalidOperationException(SR.Format(SR.SerializationDataExtensionPropertyInvalid, jsonClassInfo.Type, jsonPropertyInfo.PropertyInfo?.Name)); } + [DoesNotReturn] [MethodImpl(MethodImplOptions.NoInlining)] public static void ThrowNotSupportedException_DeserializeCreateObjectDelegateIsNull(Type invalidType) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.cs b/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.cs index cf4fd17a76253b..921268bf06eede 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.cs @@ -12,29 +12,29 @@ internal static partial class ThrowHelper // If the exception source is this value, the serializer will re-throw as JsonException. public const string ExceptionSourceValueToRethrowAsJsonException = "System.Text.Json.Rethrowable"; - public static ArgumentOutOfRangeException GetArgumentOutOfRangeException_MaxDepthMustBePositive(string parameterName) + public static ArgumentOutOfRangeException GetArgumentOutOfRangeException_MaxDepthMustBePositive(string? parameterName) { return GetArgumentOutOfRangeException(parameterName, SR.MaxDepthMustBePositive); } [MethodImpl(MethodImplOptions.NoInlining)] - private static ArgumentOutOfRangeException GetArgumentOutOfRangeException(string parameterName, string message) + private static ArgumentOutOfRangeException GetArgumentOutOfRangeException(string? parameterName, string? message) { return new ArgumentOutOfRangeException(parameterName, message); } - public static ArgumentOutOfRangeException GetArgumentOutOfRangeException_CommentEnumMustBeInRange(string parameterName) + public static ArgumentOutOfRangeException GetArgumentOutOfRangeException_CommentEnumMustBeInRange(string? parameterName) { return GetArgumentOutOfRangeException(parameterName, SR.CommentHandlingMustBeValid); } [MethodImpl(MethodImplOptions.NoInlining)] - private static ArgumentException GetArgumentException(string message) + private static ArgumentException GetArgumentException(string? message) { return new ArgumentException(message); } - public static void ThrowArgumentException(string message) + public static void ThrowArgumentException(string? message) { throw GetArgumentException(message); } @@ -137,13 +137,13 @@ public static void ThrowInvalidOperationException(int currentDepth) ThrowInvalidOperationException(SR.Format(SR.DepthTooLarge, currentDepth, JsonConstants.MaxWriterDepth)); } - public static void ThrowInvalidOperationException(string message) + public static void ThrowInvalidOperationException(string? message) { throw GetInvalidOperationException(message); } [MethodImpl(MethodImplOptions.NoInlining)] - private static InvalidOperationException GetInvalidOperationException(string message) + private static InvalidOperationException GetInvalidOperationException(string? message) { var ex = new InvalidOperationException(message); ex.Source = ExceptionSourceValueToRethrowAsJsonException; @@ -215,7 +215,7 @@ public static InvalidOperationException GetInvalidOperationException_CannotSkipO } [MethodImpl(MethodImplOptions.NoInlining)] - private static InvalidOperationException GetInvalidOperationException(string message, JsonTokenType tokenType) + private static InvalidOperationException GetInvalidOperationException(string? message, JsonTokenType tokenType) { return GetInvalidOperationException(SR.Format(SR.InvalidCast, tokenType, message)); } @@ -236,7 +236,7 @@ internal static InvalidOperationException GetJsonElementWrongTypeException( [MethodImpl(MethodImplOptions.NoInlining)] internal static InvalidOperationException GetJsonElementWrongTypeException( - string expectedTypeName, + string? expectedTypeName, JsonTokenType actualType) { return GetJsonElementWrongTypeException(expectedTypeName, actualType.ToValueKind()); @@ -253,7 +253,7 @@ internal static InvalidOperationException GetJsonElementWrongTypeException( [MethodImpl(MethodImplOptions.NoInlining)] internal static InvalidOperationException GetJsonElementWrongTypeException( - string expectedTypeName, + string? expectedTypeName, JsonValueKind actualType) { return GetInvalidOperationException( @@ -287,7 +287,7 @@ internal static string GetPrintableString(byte value) // This function will convert an ExceptionResource enum value to the resource string. [MethodImpl(MethodImplOptions.NoInlining)] - private static string GetResourceString(ref Utf8JsonReader json, ExceptionResource resource, byte nextByte, string characters) + private static string GetResourceString(ref Utf8JsonReader json, ExceptionResource resource, byte nextByte, string? characters) { string character = GetPrintableString(nextByte); @@ -459,17 +459,17 @@ public static void ThrowInvalidOperationException_ReadInvalidUTF16() throw GetInvalidOperationException(SR.CannotReadIncompleteUTF16); } - public static InvalidOperationException GetInvalidOperationException_ReadInvalidUTF8(DecoderFallbackException innerException) + public static InvalidOperationException GetInvalidOperationException_ReadInvalidUTF8(DecoderFallbackException? innerException) { return GetInvalidOperationException(SR.CannotTranscodeInvalidUtf8, innerException); } - public static ArgumentException GetArgumentException_ReadInvalidUTF16(EncoderFallbackException innerException) + public static ArgumentException GetArgumentException_ReadInvalidUTF16(EncoderFallbackException? innerException) { return new ArgumentException(SR.CannotTranscodeInvalidUtf16, innerException); } - public static InvalidOperationException GetInvalidOperationException(string message, Exception innerException) + public static InvalidOperationException GetInvalidOperationException(string? message, Exception? innerException) { InvalidOperationException ex = new InvalidOperationException(message, innerException); ex.Source = ExceptionSourceValueToRethrowAsJsonException; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs index a6e0c8c9e79729..143375a9e7c044 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs @@ -54,12 +54,12 @@ internal static partial class JsonWriterHelper private static bool NeedsEscapingNoBoundsCheck(char value) => AllowList[value] == 0; - public static int NeedsEscaping(ReadOnlySpan value, JavaScriptEncoder encoder) + public static int NeedsEscaping(ReadOnlySpan value, JavaScriptEncoder? encoder) { return (encoder ?? JavaScriptEncoder.Default).FindFirstCharacterToEncodeUtf8(value); } - public static unsafe int NeedsEscaping(ReadOnlySpan value, JavaScriptEncoder encoder) + public static unsafe int NeedsEscaping(ReadOnlySpan value, JavaScriptEncoder? encoder) { // Some implementations of JavaScriptEncoder.FindFirstCharacterToEncode may not accept // null pointers and guard against that. Hence, check up-front to return -1. @@ -100,7 +100,7 @@ private static void EscapeString(ReadOnlySpan value, Span destinatio written += encoderBytesWritten; } - public static void EscapeString(ReadOnlySpan value, Span destination, int indexOfFirstByteToEscape, JavaScriptEncoder encoder, out int written) + public static void EscapeString(ReadOnlySpan value, Span destination, int indexOfFirstByteToEscape, JavaScriptEncoder? encoder, out int written) { Debug.Assert(indexOfFirstByteToEscape >= 0 && indexOfFirstByteToEscape < value.Length); @@ -211,7 +211,7 @@ private static void EscapeString(ReadOnlySpan value, Span destinatio written += encoderCharsWritten; } - public static void EscapeString(ReadOnlySpan value, Span destination, int indexOfFirstByteToEscape, JavaScriptEncoder encoder, out int written) + public static void EscapeString(ReadOnlySpan value, Span destination, int indexOfFirstByteToEscape, JavaScriptEncoder? encoder, out int written) { Debug.Assert(indexOfFirstByteToEscape >= 0 && indexOfFirstByteToEscape < value.Length); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs index 6805d97307b061..7691bb5e3a9883 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs @@ -19,7 +19,7 @@ public struct JsonWriterOptions /// /// The encoder to use when escaping strings, or to use the default encoder. /// - public JavaScriptEncoder Encoder { get; set; } + public JavaScriptEncoder? Encoder { get; set; } /// /// Defines whether the should pretty print the JSON which includes: diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Bytes.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Bytes.cs index 6952b37b7b7051..3c1802c9301e12 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Bytes.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Bytes.cs @@ -138,7 +138,7 @@ private void WriteBase64EscapeProperty(ReadOnlySpan propertyName, ReadOnly Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); - char[] propertyArray = null; + char[]? propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); @@ -161,7 +161,7 @@ private void WriteBase64EscapeProperty(ReadOnlySpan utf8PropertyName, Read Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8PropertyName.Length); Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < utf8PropertyName.Length); - byte[] propertyArray = null; + byte[]? propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndexProp); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs index f008bfcfa633ad..da5219b98771d5 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs @@ -143,7 +143,7 @@ private void WriteStringEscapeProperty(ReadOnlySpan propertyName, DateTime Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); - char[] propertyArray = null; + char[]? propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); @@ -166,7 +166,7 @@ private void WriteStringEscapeProperty(ReadOnlySpan utf8PropertyName, Date Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8PropertyName.Length); Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < utf8PropertyName.Length); - byte[] propertyArray = null; + byte[]? propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndexProp); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs index f95fcfc03034f3..37cd479a2b7350 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs @@ -142,7 +142,7 @@ private void WriteStringEscapeProperty(ReadOnlySpan propertyName, DateTime Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); - char[] propertyArray = null; + char[]? propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); @@ -165,7 +165,7 @@ private void WriteStringEscapeProperty(ReadOnlySpan utf8PropertyName, Date Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8PropertyName.Length); Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < utf8PropertyName.Length); - byte[] propertyArray = null; + byte[]? propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndexProp); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs index d15cf699d2557d..e4b05e79b30fd1 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs @@ -142,7 +142,7 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, decimal Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); - char[] propertyArray = null; + char[]? propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); @@ -165,7 +165,7 @@ private void WriteNumberEscapeProperty(ReadOnlySpan utf8PropertyName, deci Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8PropertyName.Length); Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < utf8PropertyName.Length); - byte[] propertyArray = null; + byte[]? propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndexProp); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs index 280b7afb8537ce..f8ae05cc04c20e 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs @@ -146,7 +146,7 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, double v Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); - char[] propertyArray = null; + char[]? propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); @@ -169,7 +169,7 @@ private void WriteNumberEscapeProperty(ReadOnlySpan utf8PropertyName, doub Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8PropertyName.Length); Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < utf8PropertyName.Length); - byte[] propertyArray = null; + byte[]? propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndexProp); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs index 4dbf764b5f9f76..60ba0b03872d0d 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs @@ -146,7 +146,7 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, float va Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); - char[] propertyArray = null; + char[]? propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); @@ -169,7 +169,7 @@ private void WriteNumberEscapeProperty(ReadOnlySpan utf8PropertyName, floa Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8PropertyName.Length); Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < utf8PropertyName.Length); - byte[] propertyArray = null; + byte[]? propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndexProp); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.FormattedNumber.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.FormattedNumber.cs index 12647045fed021..b50c17c5e17c6d 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.FormattedNumber.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.FormattedNumber.cs @@ -117,7 +117,7 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, ReadOnly Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); - char[] propertyArray = null; + char[]? propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); @@ -140,7 +140,7 @@ private void WriteNumberEscapeProperty(ReadOnlySpan utf8PropertyName, Read Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8PropertyName.Length); Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < utf8PropertyName.Length); - byte[] propertyArray = null; + byte[]? propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndexProp); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs index 6828db502ab98f..b18a107c78b350 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs @@ -142,7 +142,7 @@ private void WriteStringEscapeProperty(ReadOnlySpan propertyName, Guid val Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); - char[] propertyArray = null; + char[]? propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); @@ -165,7 +165,7 @@ private void WriteStringEscapeProperty(ReadOnlySpan utf8PropertyName, Guid Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8PropertyName.Length); Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < utf8PropertyName.Length); - byte[] propertyArray = null; + byte[]? propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndexProp); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs index d16539c304aad4..152f454c625024 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs @@ -231,7 +231,7 @@ private void WriteLiteralEscapeProperty(ReadOnlySpan propertyName, ReadOnl Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); - char[] propertyArray = null; + char[]? propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); @@ -254,7 +254,7 @@ private void WriteLiteralEscapeProperty(ReadOnlySpan utf8PropertyName, Rea Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8PropertyName.Length); Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < utf8PropertyName.Length); - byte[] propertyArray = null; + byte[]? propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndexProp); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs index d74a1ec7c13e08..360bea1089d0c2 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs @@ -212,7 +212,7 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, long val Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); - char[] propertyArray = null; + char[]? propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); @@ -235,7 +235,7 @@ private void WriteNumberEscapeProperty(ReadOnlySpan utf8PropertyName, long Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8PropertyName.Length); Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < utf8PropertyName.Length); - byte[] propertyArray = null; + byte[]? propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndexProp); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs index 2dee64cc6e59ce..6ca6f1569f4833 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs @@ -85,7 +85,7 @@ private void WriteStringEscapeProperty(ReadOnlySpan propertyName, int firs { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); - char[] propertyArray = null; + char[]? propertyArray = null; if (firstEscapeIndexProp != -1) { @@ -238,7 +238,7 @@ private void WriteStringEscapeProperty(ReadOnlySpan utf8PropertyName, int { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8PropertyName.Length); - byte[] propertyArray = null; + byte[]? propertyArray = null; if (firstEscapeIndexProp != -1) { @@ -420,7 +420,7 @@ public void WriteString(string propertyName, JsonEncodedText value) /// as if were called. /// /// - public void WriteString(string propertyName, string value) + public void WriteString(string propertyName, string? value) { if (propertyName == null) { @@ -505,7 +505,7 @@ public void WriteString(ReadOnlySpan utf8PropertyName, ReadOnlySpan /// as if was called. /// /// - public void WriteString(JsonEncodedText propertyName, string value) + public void WriteString(JsonEncodedText propertyName, string? value) { if (value == null) { @@ -745,7 +745,7 @@ private void WriteStringHelperEscapeProperty(ReadOnlySpan propertyName, Re /// as if was called. /// /// - public void WriteString(ReadOnlySpan propertyName, string value) + public void WriteString(ReadOnlySpan propertyName, string? value) { if (value == null) { @@ -817,7 +817,7 @@ private void WriteStringHelperEscapeProperty(ReadOnlySpan utf8PropertyName /// as if was called. /// /// - public void WriteString(ReadOnlySpan utf8PropertyName, string value) + public void WriteString(ReadOnlySpan utf8PropertyName, string? value) { if (value == null) { @@ -834,7 +834,7 @@ private void WriteStringEscapeValueOnly(ReadOnlySpan escapedPropertyName, Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8Value.Length); Debug.Assert(firstEscapeIndex >= 0 && firstEscapeIndex < utf8Value.Length); - byte[] valueArray = null; + byte[]? valueArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(utf8Value.Length, firstEscapeIndex); @@ -857,7 +857,7 @@ private void WriteStringEscapeValueOnly(ReadOnlySpan escapedPropertyName, Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); Debug.Assert(firstEscapeIndex >= 0 && firstEscapeIndex < value.Length); - char[] valueArray = null; + char[]? valueArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndex); @@ -880,7 +880,7 @@ private void WriteStringEscapePropertyOnly(ReadOnlySpan propertyName, Read Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); Debug.Assert(firstEscapeIndex >= 0 && firstEscapeIndex < propertyName.Length); - char[] propertyArray = null; + char[]? propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndex); @@ -903,7 +903,7 @@ private void WriteStringEscapePropertyOnly(ReadOnlySpan utf8PropertyName, Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8PropertyName.Length); Debug.Assert(firstEscapeIndex >= 0 && firstEscapeIndex < utf8PropertyName.Length); - byte[] propertyArray = null; + byte[]? propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndex); @@ -1002,8 +1002,8 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); - char[] valueArray = null; - char[] propertyArray = null; + char[]? valueArray = null; + char[]? propertyArray = null; if (firstEscapeIndexVal != -1) { @@ -1071,8 +1071,8 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan utf8PropertyNam Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8Value.Length); Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8PropertyName.Length); - byte[] valueArray = null; - byte[] propertyArray = null; + byte[]? valueArray = null; + byte[]? propertyArray = null; if (firstEscapeIndexVal != -1) { @@ -1140,8 +1140,8 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8Value.Length); Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); - byte[] valueArray = null; - char[] propertyArray = null; + byte[]? valueArray = null; + char[]? propertyArray = null; if (firstEscapeIndexVal != -1) { @@ -1209,8 +1209,8 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan utf8PropertyNam Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8PropertyName.Length); - char[] valueArray = null; - byte[] propertyArray = null; + char[]? valueArray = null; + byte[]? propertyArray = null; if (firstEscapeIndexVal != -1) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs index 1acd0fcfb409a5..48d95184454344 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs @@ -221,7 +221,7 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, ulong va Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); - char[] propertyArray = null; + char[]? propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); @@ -244,7 +244,7 @@ private void WriteNumberEscapeProperty(ReadOnlySpan utf8PropertyName, ulon Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8PropertyName.Length); Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < utf8PropertyName.Length); - byte[] propertyArray = null; + byte[]? propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndexProp); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Helpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Helpers.cs index 04f5793ae10c0f..41847b8582e92e 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Helpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Helpers.cs @@ -39,7 +39,7 @@ private void ValidateWritingValue() [MethodImpl(MethodImplOptions.AggressiveInlining)] private void Base64EncodeAndWrite(ReadOnlySpan bytes, Span output, int encodingLength) { - byte[] outputText = null; + byte[]? outputText = null; Span encodedBytes = encodingLength <= JsonConstants.StackallocThreshold ? stackalloc byte[encodingLength] : diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs index b23463a7145270..ae07948e36d599 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs @@ -47,7 +47,7 @@ private void WriteStringValueHelper(ReadOnlySpan utf8Value) /// as if was called. /// /// - public void WriteStringValue(string value) + public void WriteStringValue(string? value) { if (value == null) { @@ -184,7 +184,7 @@ private void WriteStringEscapeValue(ReadOnlySpan value, int firstEscapeInd Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); Debug.Assert(firstEscapeIndexVal >= 0 && firstEscapeIndexVal < value.Length); - char[] valueArray = null; + char[]? valueArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndexVal); @@ -327,7 +327,7 @@ private void WriteStringEscapeValue(ReadOnlySpan utf8Value, int firstEscap Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8Value.Length); Debug.Assert(firstEscapeIndexVal >= 0 && firstEscapeIndexVal < utf8Value.Length); - byte[] valueArray = null; + byte[]? valueArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(utf8Value.Length, firstEscapeIndexVal); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs index 4a90fc55037505..9ba41e024b4b35 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs @@ -41,9 +41,9 @@ public sealed partial class Utf8JsonWriter : IDisposable, IAsyncDisposable private const int DefaultGrowthSize = 4096; private const int InitialGrowthSize = 256; - private IBufferWriter _output; - private Stream _stream; - private ArrayBufferWriter _arrayBufferWriter; + private IBufferWriter? _output; + private Stream? _stream; + private ArrayBufferWriter? _arrayBufferWriter; private Memory _memory; @@ -694,7 +694,7 @@ private void WriteStartEscapeProperty(ReadOnlySpan utf8PropertyName, byte Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8PropertyName.Length); Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < utf8PropertyName.Length); - byte[] propertyArray = null; + byte[]? propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndexProp); @@ -837,7 +837,7 @@ private void WriteStartEscapeProperty(ReadOnlySpan propertyName, byte toke Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); - char[] propertyArray = null; + char[]? propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp);