From a649816f4211049eeb6ffac3eaaf78d82bca7513 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Mon, 18 Nov 2019 13:16:45 -0800 Subject: [PATCH 01/25] Annotate System.Text.Json for nullable --- .../System.Text.Json/ref/System.Text.Json.cs | 173 +++++++++--------- .../ref/System.Text.Json.csproj | 1 + .../src/System.Text.Json.csproj | 1 + .../src/System/Text/Json/BitStack.cs | 1 + .../Json/Document/JsonDocument.MetadataDb.cs | 2 +- .../Text/Json/Document/JsonDocument.Parse.cs | 19 +- .../Document/JsonDocument.StackRowStack.cs | 4 +- .../Document/JsonDocument.TryGetProperty.cs | 2 +- .../System/Text/Json/Document/JsonDocument.cs | 21 ++- .../Document/JsonElement.ArrayEnumerator.cs | 4 +- .../Document/JsonElement.ObjectEnumerator.cs | 6 +- .../System/Text/Json/Document/JsonElement.cs | 76 ++++---- .../System/Text/Json/Document/JsonProperty.cs | 4 +- .../src/System/Text/Json/JsonEncodedText.cs | 16 +- .../src/System/Text/Json/JsonException.cs | 18 +- .../src/System/Text/Json/JsonHelpers.cs | 2 +- .../src/System/Text/Json/Node/JsonArray.cs | 14 +- .../src/System/Text/Json/Node/JsonBoolean.cs | 8 +- .../Json/Node/JsonNode.RecursionStackFrame.cs | 8 +- .../Text/Json/Node/JsonNode.Traversal.cs | 52 +++--- .../Json/Node/JsonNode.TraversalHelpers.cs | 10 +- .../src/System/Text/Json/Node/JsonNode.cs | 10 +- .../src/System/Text/Json/Node/JsonNull.cs | 8 +- .../src/System/Text/Json/Node/JsonNumber.cs | 10 +- .../src/System/Text/Json/Node/JsonObject.cs | 46 ++--- .../Text/Json/Node/JsonObjectEnumerator.cs | 4 +- .../Text/Json/Node/JsonObjectProperty.cs | 6 +- .../src/System/Text/Json/Node/JsonString.cs | 15 +- .../Text/Json/Reader/JsonReaderException.cs | 2 +- .../Reader/JsonReaderHelper.Unescaping.cs | 19 +- .../Text/Json/Reader/Utf8JsonReader.TryGet.cs | 7 +- .../System/Text/Json/Reader/Utf8JsonReader.cs | 2 +- .../Converters/DefaultArrayConverter.cs | 2 +- .../DefaultImmutableDictionaryConverter.cs | 9 +- .../DefaultImmutableEnumerableConverter.cs | 9 +- .../Converters/JsonConverterEnum.cs | 4 +- .../Converters/JsonKeyValuePairConverter.cs | 4 +- .../Converters/JsonValueConverterBoolean.cs | 4 +- .../Converters/JsonValueConverterByte.cs | 4 +- .../Converters/JsonValueConverterByteArray.cs | 4 +- .../Converters/JsonValueConverterChar.cs | 6 +- .../Converters/JsonValueConverterDateTime.cs | 4 +- .../JsonValueConverterDateTimeOffset.cs | 4 +- .../Converters/JsonValueConverterDecimal.cs | 4 +- .../Converters/JsonValueConverterDouble.cs | 4 +- .../Converters/JsonValueConverterEnum.cs | 14 +- .../Converters/JsonValueConverterGuid.cs | 4 +- .../Converters/JsonValueConverterInt16.cs | 4 +- .../Converters/JsonValueConverterInt32.cs | 4 +- .../Converters/JsonValueConverterInt64.cs | 4 +- .../JsonValueConverterJsonElement.cs | 4 +- .../JsonValueConverterKeyValuePair.cs | 15 +- .../Converters/JsonValueConverterObject.cs | 4 +- .../Converters/JsonValueConverterSByte.cs | 4 +- .../Converters/JsonValueConverterSingle.cs | 4 +- .../Converters/JsonValueConverterString.cs | 6 +- .../Converters/JsonValueConverterUInt16.cs | 4 +- .../Converters/JsonValueConverterUInt32.cs | 4 +- .../Converters/JsonValueConverterUInt64.cs | 4 +- .../Converters/JsonValueConverterUri.cs | 10 +- .../ImmutableCollectionCreator.cs | 21 ++- .../JsonCamelCaseNamingPolicy.cs | 5 +- .../JsonClassInfo.AddProperty.cs | 34 ++-- .../Text/Json/Serialization/JsonClassInfo.cs | 72 ++++---- .../Text/Json/Serialization/JsonConverter.cs | 2 +- .../Serialization/JsonConverterAttribute.cs | 4 +- .../Serialization/JsonConverterFactory.cs | 4 +- .../Json/Serialization/JsonConverterOfT.cs | 4 +- .../Serialization/JsonDefaultNamingPolicy.cs | 5 +- .../Json/Serialization/JsonNamingPolicy.cs | 5 +- .../Json/Serialization/JsonPropertyInfo.cs | 89 ++++----- .../Serialization/JsonPropertyInfoCommon.cs | 73 ++++---- .../JsonPropertyInfoNotNullable.cs | 14 +- ...sonPropertyInfoNotNullableContravariant.cs | 14 +- .../Serialization/JsonPropertyInfoNullable.cs | 18 +- .../JsonSerializer.Read.HandleArray.cs | 38 ++-- .../JsonSerializer.Read.HandleDictionary.cs | 17 +- .../JsonSerializer.Read.HandleNull.cs | 6 +- .../JsonSerializer.Read.HandleObject.cs | 6 +- .../JsonSerializer.Read.HandlePropertyName.cs | 7 +- .../JsonSerializer.Read.HandleValue.cs | 2 +- .../JsonSerializer.Read.Helpers.cs | 2 +- .../Serialization/JsonSerializer.Read.Span.cs | 10 +- .../JsonSerializer.Read.Stream.cs | 8 +- .../JsonSerializer.Read.String.cs | 10 +- .../JsonSerializer.Read.Utf8JsonReader.cs | 8 +- .../Json/Serialization/JsonSerializer.Read.cs | 2 +- .../JsonSerializer.Write.ByteArray.cs | 4 +- .../JsonSerializer.Write.HandleDictionary.cs | 26 ++- .../JsonSerializer.Write.HandleEnumerable.cs | 10 +- .../JsonSerializer.Write.HandleObject.cs | 13 +- .../JsonSerializer.Write.Helpers.cs | 17 +- .../JsonSerializer.Write.Stream.cs | 6 +- .../JsonSerializer.Write.String.cs | 4 +- .../JsonSerializer.Write.Utf8JsonWriter.cs | 4 +- .../Serialization/JsonSerializer.Write.cs | 8 +- .../JsonSerializerOptions.Converters.cs | 38 ++-- .../Serialization/JsonSerializerOptions.cs | 23 +-- .../Serialization/JsonStringEnumConverter.cs | 10 +- .../Text/Json/Serialization/MemberAccessor.cs | 20 +- .../Serialization/PooledByteBufferWriter.cs | 2 +- .../Text/Json/Serialization/ReadStack.cs | 14 +- .../Text/Json/Serialization/ReadStackFrame.cs | 46 ++--- .../ReflectionEmitMemberAccessor.cs | 34 ++-- .../Serialization/ReflectionMemberAccessor.cs | 40 ++-- .../Text/Json/Serialization/WriteStack.cs | 8 +- .../Json/Serialization/WriteStackFrame.cs | 13 +- .../Text/Json/ThrowHelper.Serialization.cs | 51 +++--- .../src/System/Text/Json/ThrowHelper.cs | 28 +-- .../Json/Writer/JsonWriterHelper.Escaping.cs | 8 +- .../Text/Json/Writer/JsonWriterOptions.cs | 2 +- .../Utf8JsonWriter.WriteProperties.Bytes.cs | 4 +- ...Utf8JsonWriter.WriteProperties.DateTime.cs | 4 +- ...onWriter.WriteProperties.DateTimeOffset.cs | 4 +- .../Utf8JsonWriter.WriteProperties.Decimal.cs | 4 +- .../Utf8JsonWriter.WriteProperties.Double.cs | 4 +- .../Utf8JsonWriter.WriteProperties.Float.cs | 4 +- ...nWriter.WriteProperties.FormattedNumber.cs | 4 +- .../Utf8JsonWriter.WriteProperties.Guid.cs | 4 +- .../Utf8JsonWriter.WriteProperties.Literal.cs | 4 +- ...JsonWriter.WriteProperties.SignedNumber.cs | 4 +- .../Utf8JsonWriter.WriteProperties.String.cs | 36 ++-- ...onWriter.WriteProperties.UnsignedNumber.cs | 4 +- .../Utf8JsonWriter.WriteValues.Helpers.cs | 2 +- .../Utf8JsonWriter.WriteValues.String.cs | 6 +- .../System/Text/Json/Writer/Utf8JsonWriter.cs | 10 +- 126 files changed, 904 insertions(+), 825 deletions(-) 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..c00e92d3cfdf86 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) { } @@ -71,11 +72,11 @@ 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 +97,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 +145,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 +168,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 +202,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 +214,24 @@ 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; } } +#pragma warning disable 8609 + public override string? Message { get { throw null; } } +#pragma warning restore 8609 + 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 +254,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 +263,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 @@ -275,11 +279,11 @@ public sealed partial class JsonNull : System.Text.Json.JsonNode, System.IEquata 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 @@ -303,8 +307,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 +325,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 +363,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 +384,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 +432,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,16 +455,16 @@ 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 { @@ -472,14 +477,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 +520,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 +557,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 +567,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; } @@ -684,35 +689,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 +737,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 +771,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..a24bcacf6fdc36 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,7 @@ + enable 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..954aa90bf52f7f 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 @@ -135,6 +135,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..08bd92f803a863 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; + private 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,20 +125,22 @@ 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. /// - public override string Message + public override string? Message { +#pragma warning disable 8609 get { return _message; } +#pragma warning restore 8609 } - 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..39ecf336441e1b 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 @@ -38,7 +38,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 +54,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 +65,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 +87,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..71a1158ed86eba 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,7 @@ 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) => !jsonElement.IsImmutable ? (JsonNode)jsonElement._parent! : throw new ArgumentException(SR.NotNodeJsonElementParent); /// /// Gets the represented by the . @@ -46,10 +49,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 +75,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..8057e49432ce25 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 @@ -30,7 +30,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 +43,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 +51,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 +59,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..8a0146aaf491b7 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 @@ -11,7 +11,7 @@ namespace System.Text.Json /// public sealed class JsonNumber : JsonNode, IEquatable { - private string _value; + private string _value = null!; /// /// Initializes a new instance of the class representing the value 0. @@ -557,7 +557,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 +573,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 +584,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 +606,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..bcb72673cfc7fa 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,6 +5,7 @@ using System.Globalization; using System.Buffers; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Text.Json { @@ -13,7 +14,7 @@ namespace System.Text.Json /// public sealed class JsonString : JsonNode, IEquatable { - private string _value; + private string _value = null!; /// /// Initializes a new instance of the class representing the empty value. @@ -149,7 +150,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 +166,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 +177,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 +199,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 +223,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 +239,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/JsonReaderException.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderException.cs index 2fa33d96b1db40..1039aaf3ffd7be 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderException.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderException.cs @@ -10,7 +10,7 @@ namespace System.Text.Json [Serializable] internal sealed class JsonReaderException : JsonException { - public JsonReaderException(string message, long lineNumber, long bytePositionInLine) : base(message, path: null, lineNumber, bytePositionInLine) + public JsonReaderException(string? message, long lineNumber, long bytePositionInLine) : base(message, path: null, lineNumber, bytePositionInLine) { } 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..fc20eacfc5283f 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 @@ -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..b0986a75d45f29 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,9 +21,9 @@ 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( + JsonConverter? converter = (JsonConverter?)Activator.CreateInstance( typeof(JsonConverterEnum<>).MakeGenericType(type), BindingFlags.Instance | BindingFlags.Public, binder: null, 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..2b622a9be8744c 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,12 +20,12 @@ 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]; - JsonConverter converter = (JsonConverter)Activator.CreateInstance( + JsonConverter? converter = (JsonConverter?)Activator.CreateInstance( typeof(JsonKeyValuePairConverter<,>).MakeGenericType(new Type[] { keyType, valueType }), BindingFlags.Instance | BindingFlags.Public, binder: null, 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..4bfc1be3888f34 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,7 +155,7 @@ 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)) @@ -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..6791165aa4d9b2 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..13b1847159f8f3 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..9496c7be0764f8 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,7 +30,7 @@ protected override void OnRead(ref ReadStack state, ref Utf8JsonReader reader) } else { - Set(state.Current.ReturnValue, value); + Set!(state.Current.ReturnValue, value); } } @@ -63,11 +63,11 @@ 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); + value = (TConverter)Get!(current.CurrentValue)!; } if (value == null) @@ -92,7 +92,7 @@ protected override void OnWrite(ref WriteStackFrame current, Utf8JsonWriter writ protected override void OnWriteDictionary(ref WriteStackFrame current, Utf8JsonWriter writer) { - JsonSerializer.WriteDictionary(Converter, Options, ref current, writer); + JsonSerializer.WriteDictionary(Converter!, Options, ref current, writer); } protected override void OnWriteEnumerable(ref WriteStackFrame current, Utf8JsonWriter writer) @@ -110,7 +110,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 +129,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 +139,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..8b0b2eb7d03826 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,7 @@ protected override void OnRead(ref ReadStack state, ref Utf8JsonReader reader) } else { - Set(state.Current.ReturnValue, (TDeclaredProperty)value); + Set!(state.Current.ReturnValue, (TDeclaredProperty)value!); } return; @@ -65,11 +65,11 @@ 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); + value = (TConverter)Get!(current.CurrentValue); } if (value == null) @@ -94,7 +94,7 @@ protected override void OnWrite(ref WriteStackFrame current, Utf8JsonWriter writ protected override void OnWriteDictionary(ref WriteStackFrame current, Utf8JsonWriter writer) { - JsonSerializer.WriteDictionary(Converter, Options, ref current, writer); + JsonSerializer.WriteDictionary(Converter!, Options, ref current, writer); } protected override void OnWriteEnumerable(ref WriteStackFrame current, Utf8JsonWriter writer) @@ -111,7 +111,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 +130,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 +140,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..0c03578ec9766f 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,7 +33,7 @@ protected override void OnRead(ref ReadStack state, ref Utf8JsonReader reader) } else { - Set(state.Current.ReturnValue, value); + Set!(state.Current.ReturnValue, value); } } @@ -58,7 +58,7 @@ protected override void OnWrite(ref WriteStackFrame current, Utf8JsonWriter writ } else { - value = Get(current.CurrentValue); + value = Get!(current.CurrentValue); } if (value == null) @@ -85,7 +85,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 +94,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 +102,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 +126,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 +168,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 +178,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..109c6366c568a7 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,7 +170,7 @@ internal static void ApplyObjectToEnumerable( } else { - ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(value.GetType()); + ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(value?.GetType()); return; } } @@ -191,7 +193,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 +211,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 +222,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 +231,7 @@ internal static void ApplyObjectToEnumerable( } else { + Debug.Assert(currentDictionary != null); state.Current.JsonPropertyInfo.AddObjectToDictionary(currentDictionary, key, value); } } @@ -271,7 +274,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 +287,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 +296,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 +312,7 @@ internal static void ApplyValueToEnumerable( } else { + Debug.Assert(currentDictionary != null); throw ThrowHelper.GetNotSupportedException_SerializationNotSupportedCollection(currentDictionary.GetType(), parentType: null, memberInfo: null); } } @@ -321,7 +325,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..7ecce37e02453f 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,13 +57,13 @@ 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( + JsonConverter? converter = (JsonConverter?)Activator.CreateInstance( typeof(JsonConverterEnum<>).MakeGenericType(typeToConvert), BindingFlags.Instance | BindingFlags.Public, binder: null, - new object[] { _converterOptions, _namingPolicy }, + 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..721a735a252d27 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)] @@ -134,7 +141,7 @@ public static void ThrowInvalidOperationException_SerializerDictionaryKeyNull(Ty [MethodImpl(MethodImplOptions.NoInlining)] public static void ReThrowWithPath(in ReadStack readStack, JsonReaderException ex) { - Debug.Assert(ex.Path == null); + Debug.Assert(ex.Path == null && ex.Message != null); string path = readStack.JsonPath(); string message = ex.Message; @@ -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); From 5015584fb4aefd13a666b37a7d4f477dde02ffe6 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Mon, 18 Nov 2019 17:34:40 -0800 Subject: [PATCH 02/25] Suppressing null warnings on non NetCoreApp targets --- src/libraries/System.Text.Json/src/System.Text.Json.csproj | 1 + 1 file changed, 1 insertion(+) 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 a24bcacf6fdc36..92b27e96b8be9b 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,7 @@ + $(NoWarn);8600;8601;8602;8603;8604 enable From 44d82fd3a8b17024284fc9fa3dff9e7096193346 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Mon, 18 Nov 2019 17:54:56 -0800 Subject: [PATCH 03/25] Suppress more error in other env --- src/libraries/System.Text.Json/src/System.Text.Json.csproj | 2 +- .../src/System/Text/Json/Serialization/JsonClassInfo.cs | 2 +- .../Text/Json/Serialization/JsonPropertyInfoNotNullable.cs | 3 ++- .../Serialization/JsonPropertyInfoNotNullableContravariant.cs | 3 ++- 4 files changed, 6 insertions(+), 4 deletions(-) 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 92b27e96b8be9b..493df4e5c2611d 100644 --- a/src/libraries/System.Text.Json/src/System.Text.Json.csproj +++ b/src/libraries/System.Text.Json/src/System.Text.Json.csproj @@ -10,7 +10,7 @@ - $(NoWarn);8600;8601;8602;8603;8604 + $(NoWarn);8600;8601;8602;8603;8604;8629 enable 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 4bfc1be3888f34..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 @@ -158,7 +158,7 @@ public JsonClassInfo(Type type, JsonSerializerOptions options) 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]; 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 9496c7be0764f8..f12bb1119c9131 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 @@ -92,7 +92,8 @@ protected override void OnWrite(ref WriteStackFrame current, Utf8JsonWriter writ protected override void OnWriteDictionary(ref WriteStackFrame current, Utf8JsonWriter writer) { - JsonSerializer.WriteDictionary(Converter!, Options, ref current, writer); + Debug.Assert(Converter != null); + JsonSerializer.WriteDictionary(Converter, Options, ref current, writer); } protected override void OnWriteEnumerable(ref WriteStackFrame current, Utf8JsonWriter writer) 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 8b0b2eb7d03826..f6256b2ab7a7d5 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 @@ -94,7 +94,8 @@ protected override void OnWrite(ref WriteStackFrame current, Utf8JsonWriter writ protected override void OnWriteDictionary(ref WriteStackFrame current, Utf8JsonWriter writer) { - JsonSerializer.WriteDictionary(Converter!, Options, ref current, writer); + Debug.Assert(Converter != null); + JsonSerializer.WriteDictionary(Converter, Options, ref current, writer); } protected override void OnWriteEnumerable(ref WriteStackFrame current, Utf8JsonWriter writer) From 3a7254b5de8044bdcd0737ffff60fa583bce9fb4 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Tue, 19 Nov 2019 14:40:33 -0800 Subject: [PATCH 04/25] Annotate netstandard dependent file --- .../Collections/Generic/StackExtensions.netstandard.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) 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; } } From 6917d64ba0105bc83f84768ed203708d4f72538c Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Tue, 19 Nov 2019 15:56:07 -0800 Subject: [PATCH 05/25] Some more update --- .../System.Text.Json/src/System/Text/Json/BitStack.cs | 2 +- .../Text/Json/Serialization/JsonPropertyInfoCommon.cs | 4 ++-- .../Text/Json/Serialization/JsonPropertyInfoNotNullable.cs | 6 ++++-- .../JsonPropertyInfoNotNullableContravariant.cs | 6 ++++-- .../Text/Json/Serialization/JsonPropertyInfoNullable.cs | 6 ++++-- .../Json/Serialization/JsonSerializer.Read.HandleArray.cs | 3 ++- 6 files changed, 17 insertions(+), 10 deletions(-) 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 954aa90bf52f7f..f59e65b52f25ac 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 @@ -15,7 +15,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). 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 13b1847159f8f3..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 @@ -121,7 +121,7 @@ private void SetPropertyInfoForObjectElement() 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); return addMethodDelegate != null; @@ -170,7 +170,7 @@ public override void AddObjectToParentDictionary(object target, string key, obje public override bool CanPopulateDictionary(object target) { SetPropertyInfoForObjectElement(); - Debug.Assert((_elementPropertyInfo ?? ElementClassInfo?.PolicyProperty) != null); + Debug.Assert((_elementPropertyInfo ?? ElementClassInfo!.PolicyProperty) != null); return (_elementPropertyInfo ?? ElementClassInfo!.PolicyProperty!).ParentDictionaryCanBePopulated(target); } 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 f12bb1119c9131..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,7 +30,8 @@ protected override void OnRead(ref ReadStack state, ref Utf8JsonReader reader) } else { - Set!(state.Current.ReturnValue, value); + Debug.Assert(Set != null); + Set(state.Current.ReturnValue, value); } } @@ -67,7 +68,8 @@ protected override void OnWrite(ref WriteStackFrame current, Utf8JsonWriter writ } else { - value = (TConverter)Get!(current.CurrentValue)!; + Debug.Assert(Get != null); + value = (TConverter)Get(current.CurrentValue)!; } if (value == null) 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 f6256b2ab7a7d5..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; @@ -69,7 +70,8 @@ protected override void OnWrite(ref WriteStackFrame current, Utf8JsonWriter writ } else { - value = (TConverter)Get!(current.CurrentValue); + Debug.Assert(Get != null); + value = (TConverter)Get(current.CurrentValue); } if (value == null) 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 0c03578ec9766f..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,7 +33,8 @@ protected override void OnRead(ref ReadStack state, ref Utf8JsonReader reader) } else { - Set!(state.Current.ReturnValue, value); + Debug.Assert(Set != null); + Set(state.Current.ReturnValue, value); } } @@ -58,7 +59,8 @@ protected override void OnWrite(ref WriteStackFrame current, Utf8JsonWriter writ } else { - value = Get!(current.CurrentValue); + Debug.Assert(Get != null); + value = Get(current.CurrentValue); } if (value == null) 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 109c6366c568a7..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 @@ -170,7 +170,8 @@ internal static void ApplyObjectToEnumerable( } else { - ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(value?.GetType()); + Debug.Assert(value != null); + ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(value.GetType()); return; } } From 150691f710c763666f888a80e3a2725f9e8e8fb9 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Wed, 20 Nov 2019 09:52:57 -0800 Subject: [PATCH 06/25] Enebling nullability on file which fialing for other projects --- src/libraries/System.Text.Json/src/System/Text/Json/BitStack.cs | 1 + 1 file changed, 1 insertion(+) 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 f59e65b52f25ac..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 From 0ab2dd6b65e4699b524cc7e22ef5297a52a607a2 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Wed, 20 Nov 2019 10:04:35 -0800 Subject: [PATCH 07/25] Disabling nullable warning on netfx, netstandard --- src/libraries/System.Text.Json/src/System.Text.Json.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 493df4e5c2611d..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,7 +10,7 @@ - $(NoWarn);8600;8601;8602;8603;8604;8629 + $(NoWarn);nullable enable From fba9feb05c0a64277f184e2fed041f67efce35ab Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Thu, 21 Nov 2019 11:45:07 -0800 Subject: [PATCH 08/25] Addressing feedback --- .../System.Text.Json/ref/System.Text.Json.cs | 26 +++++++++++++------ .../Text/Json/Document/JsonDocument.Parse.cs | 6 +++-- .../System/Text/Json/Document/JsonDocument.cs | 2 ++ .../System/Text/Json/Document/JsonElement.cs | 6 ++--- .../System/Text/Json/Document/JsonProperty.cs | 2 +- .../src/System/Text/Json/JsonException.cs | 8 +++--- .../src/System/Text/Json/Node/JsonBoolean.cs | 5 +++- .../Text/Json/Node/JsonNode.Traversal.cs | 4 ++- .../src/System/Text/Json/Node/JsonNode.cs | 10 ++++++- .../src/System/Text/Json/Node/JsonNull.cs | 5 +++- .../src/System/Text/Json/Node/JsonNumber.cs | 5 +++- .../src/System/Text/Json/Node/JsonString.cs | 5 +++- .../Text/Json/Reader/JsonReaderException.cs | 2 +- .../System/Text/Json/Reader/Utf8JsonReader.cs | 2 +- .../Converters/JsonConverterEnum.cs | 6 ++--- .../Converters/JsonKeyValuePairConverter.cs | 6 ++--- .../Serialization/JsonConverterFactory.cs | 4 +-- .../JsonSerializerOptions.Converters.cs | 5 ++-- .../Serialization/JsonStringEnumConverter.cs | 6 ++--- .../Text/Json/ThrowHelper.Serialization.cs | 6 ++--- 20 files changed, 78 insertions(+), 43 deletions(-) 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 c00e92d3cfdf86..62c5cb51a342c8 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -65,7 +65,10 @@ 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) { } @@ -220,9 +223,7 @@ public JsonException(string? message, string? path, long? lineNumber, long? byte 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; } } -#pragma warning disable 8609 - public override string? Message { get { throw null; } } -#pragma warning restore 8609 + public override string Message { get { throw null; } } public string? Path { get { throw null; } } public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } } @@ -274,7 +275,10 @@ 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; } } @@ -286,7 +290,10 @@ public JsonNull() { } 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) { } @@ -466,7 +473,10 @@ public JsonSerializerOptions() { } public bool WriteIndented { get { throw null; } set { } } 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) { } @@ -588,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 { 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 ce83286fe49c3f..1f680f259e9740 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 @@ -128,7 +128,8 @@ public static JsonDocument Parse(Stream utf8Json, JsonDocumentOptions options = { // Holds document content, clear it before returning it. drained.AsSpan().Clear(); - ArrayPool.Shared.Return(drained.Array!); + Debug.Assert(drained.Array != null); + ArrayPool.Shared.Return(drained.Array); throw; } } @@ -177,7 +178,8 @@ private static async Task ParseAsyncCore( { // Holds document content, clear it before returning it. drained.AsSpan().Clear(); - ArrayPool.Shared.Return(drained.Array!); + Debug.Assert(drained.Array != null); + ArrayPool.Shared.Return(drained.Array); throw; } } 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 2de33a948c7596..13d47b0bc50bbf 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 @@ -252,6 +252,7 @@ private ReadOnlyMemory GetPropertyRawValue(int valueIndex) if (lastIdx == index) { + Debug.Assert(lastString != null); return lastString; } @@ -279,6 +280,7 @@ private ReadOnlyMemory GetPropertyRawValue(int valueIndex) lastString = JsonReaderHelper.TranscodeHelper(segment); } + Debug.Assert(lastString != null); _lastIndexAndString = (index, lastString); return lastString; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonElement.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonElement.cs index fef769e66f58cf..e952feaa05fe7e 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonElement.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonElement.cs @@ -450,13 +450,13 @@ public bool GetBoolean() /// The parent has been disposed. /// /// - public string GetString() + public string? GetString() { CheckValidInstance(); if (_parent is JsonDocument document) { - return document.GetString(_idx, JsonTokenType.String)!; + return document.GetString(_idx, JsonTokenType.String); } var jsonNode = (JsonNode)_parent!; @@ -1722,7 +1722,7 @@ public ObjectEnumerator EnumerateObject() /// /// The parent has been disposed. /// - public override string ToString() + public override string? ToString() { if (_parent is JsonNode jsonNode) { 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 36595a8abb0406..680735d5077a5b 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 @@ -45,7 +45,7 @@ internal JsonProperty(JsonElement value, string? name = null) /// This method is functionally equal to doing an ordinal comparison of and /// , but can avoid creating the string instance. /// - public bool NameEquals(string text) + public bool NameEquals(string? text) { return NameEquals(text.AsSpan()); } 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 08bd92f803a863..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. @@ -130,14 +130,12 @@ public override void GetObjectData(SerializationInfo info, StreamingContext cont /// /// Gets a message that describes the current exception. /// - public override string? Message + public override string Message { -#pragma warning disable 8609 get { - return _message; + return _message ?? base.Message; } -#pragma warning restore 8609 } internal void SetMessage(string? message) 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 39ecf336441e1b..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 . 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 9f904a3c840688..bf725c14eaab0d 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 @@ -90,7 +90,9 @@ public static JsonNode DeepCopy(JsonElement jsonElement) AddToParent(new KeyValuePair(currentPair.Key, jsonNumber), ref currentNodes, ref toReturn); break; case JsonValueKind.String: - var jsonString = new JsonString(currentJsonElement.Value.GetString()); + string? value = currentJsonElement.Value.GetString(); + Debug.Assert(value != null); + var jsonString = new JsonString(value); AddToParent(new KeyValuePair(currentPair.Key, jsonString), ref currentNodes, ref toReturn); break; case JsonValueKind.True: 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 71a1158ed86eba..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 @@ -36,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 . 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 8057e49432ce25..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 . 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 8a0146aaf491b7..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,7 +9,10 @@ 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 = null!; 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 bcb72673cfc7fa..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 @@ -12,7 +12,10 @@ 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 = null!; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderException.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderException.cs index 1039aaf3ffd7be..2fa33d96b1db40 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderException.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderException.cs @@ -10,7 +10,7 @@ namespace System.Text.Json [Serializable] internal sealed class JsonReaderException : JsonException { - public JsonReaderException(string? message, long lineNumber, long bytePositionInLine) : base(message, path: null, lineNumber, bytePositionInLine) + public JsonReaderException(string message, long lineNumber, long bytePositionInLine) : base(message, path: null, lineNumber, bytePositionInLine) { } 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 fc20eacfc5283f..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()); } 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 b0986a75d45f29..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( + 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 2b622a9be8744c..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,17 +20,17 @@ 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]; - JsonConverter? converter = (JsonConverter?)Activator.CreateInstance( + JsonConverter converter = (JsonConverter)Activator.CreateInstance( typeof(JsonKeyValuePairConverter<,>).MakeGenericType(new Type[] { keyType, valueType }), 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/JsonConverterFactory.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterFactory.cs index 6791165aa4d9b2..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 @@ protected JsonConverterFactory() { } /// /// 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/JsonSerializerOptions.Converters.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs index 11f6e5d322eeaa..7ddc268cc26f7f 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 @@ -206,8 +206,9 @@ private JsonConverter GetConverterFromAttribute(JsonConverterAttribute converter } else { - ConstructorInfo ctor = type.GetConstructor(Type.EmptyTypes)!; - if (!typeof(JsonConverter).IsAssignableFrom(type) || !ctor.IsPublic) + ConstructorInfo? ctor = type.GetConstructor(Type.EmptyTypes); + + if (!typeof(JsonConverter).IsAssignableFrom(type) || ctor == null || !ctor.IsPublic) { ThrowHelper.ThrowInvalidOperationException_SerializationConverterOnAttributeInvalid(classTypeAttributeIsOn, propertyInfo); } 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 7ecce37e02453f..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 @@ -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( + JsonConverter converter = (JsonConverter)Activator.CreateInstance( typeof(JsonConverterEnum<>).MakeGenericType(typeToConvert), BindingFlags.Instance | BindingFlags.Public, binder: null, new object?[] { _converterOptions, _namingPolicy }, - culture: null); + culture: null)!; return converter; } 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 721a735a252d27..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 @@ -141,7 +141,7 @@ public static void ThrowInvalidOperationException_SerializerDictionaryKeyNull(Ty [MethodImpl(MethodImplOptions.NoInlining)] public static void ReThrowWithPath(in ReadStack readStack, JsonReaderException ex) { - Debug.Assert(ex.Path == null && ex.Message != null); + Debug.Assert(ex.Path == null); string path = readStack.JsonPath(); string message = ex.Message; @@ -179,7 +179,7 @@ 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)) { @@ -214,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. From 4ba6fe1ab102087601dcf6bf3c5aebfd20095012 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Thu, 5 Dec 2019 10:55:42 -0800 Subject: [PATCH 09/25] Applying more feedback --- .../System.Text.Json/src/System/Text/Json/JsonException.cs | 4 ++-- .../src/System/Text/Json/Reader/JsonReaderException.cs | 2 +- .../Json/Serialization/JsonSerializerOptions.Converters.cs | 1 - .../src/System/Text/Json/ThrowHelper.Serialization.cs | 4 +--- 4 files changed, 4 insertions(+), 7 deletions(-) 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 b4e511dd773bba..4f3d2b0b6683f5 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 @@ -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? byte /// /// 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; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderException.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderException.cs index 2fa33d96b1db40..32ba306190389c 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderException.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderException.cs @@ -10,7 +10,7 @@ namespace System.Text.Json [Serializable] internal sealed class JsonReaderException : JsonException { - public JsonReaderException(string message, long lineNumber, long bytePositionInLine) : base(message, path: null, lineNumber, bytePositionInLine) + public JsonReaderException(string message, long lineNumber, long bytePositionInLine) : base(message, path: string.Empty, lineNumber, bytePositionInLine) { } 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 7ddc268cc26f7f..e4e5caf5d3c423 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 @@ -207,7 +207,6 @@ private JsonConverter GetConverterFromAttribute(JsonConverterAttribute converter else { ConstructorInfo? ctor = type.GetConstructor(Type.EmptyTypes); - if (!typeof(JsonConverter).IsAssignableFrom(type) || ctor == null || !ctor.IsPublic) { ThrowHelper.ThrowInvalidOperationException_SerializationConverterOnAttributeInvalid(classTypeAttributeIsOn, propertyInfo); 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 c516dfbf4f9361..ac2d64dada2423 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 @@ -45,7 +45,7 @@ public static void ThrowJsonException_DeserializeUnableToConvertValue(Type? prop [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); @@ -141,8 +141,6 @@ public static void ThrowInvalidOperationException_SerializerDictionaryKeyNull(Ty [MethodImpl(MethodImplOptions.NoInlining)] public static void ReThrowWithPath(in ReadStack readStack, JsonReaderException ex) { - Debug.Assert(ex.Path == null); - string path = readStack.JsonPath(); string message = ex.Message; From 7391b89e4e930d194286c1a50e6b7ce825853bc8 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Thu, 5 Dec 2019 13:42:33 -0800 Subject: [PATCH 10/25] Updating ref assemblies --- .../System.Text.Json/ref/System.Text.Json.cs | 12 ++++++------ .../src/System/Text/Json/JsonException.cs | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) 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 62c5cb51a342c8..169c33d0307e8d 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -139,14 +139,14 @@ public readonly partial struct JsonElement [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)] public uint GetUInt32() { throw null; } [System.CLSCompliantAttribute(false)] public ulong GetUInt64() { throw null; } - public override string ToString() { throw null; } + public override string? ToString() { throw null; } public bool TryGetByte(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; } @@ -219,12 +219,12 @@ 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, 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 @@ -419,7 +419,7 @@ public readonly partial struct JsonProperty public System.Text.Json.JsonElement Value { get { throw null; } } public bool NameEquals(System.ReadOnlySpan utf8Text) { throw null; } public bool NameEquals(System.ReadOnlySpan text) { throw null; } - public bool NameEquals(string text) { throw null; } + public bool NameEquals(string? text) { throw null; } public override string ToString() { throw null; } public void WriteTo(System.Text.Json.Utf8JsonWriter writer) { } } 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 4f3d2b0b6683f5..38f21042b14d45 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 @@ -89,7 +89,7 @@ protected JsonException(SerializationInfo info, StreamingContext context) : base { LineNumber = (long?)info.GetValue("LineNumber", typeof(long?)); BytePositionInLine = (long?)info.GetValue("BytePositionInLine", typeof(long?)); - Path = info.GetString("Path"); + Path = info.GetString("Path")!; SetMessage(info.GetString("ActualMessage")); } @@ -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; } = string.Empty; /// /// Gets a message that describes the current exception. From 474efe4e6d6e2b00ad5883cc94405fe9a914d24f Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Thu, 5 Dec 2019 17:56:37 -0800 Subject: [PATCH 11/25] Empty path instead of banging on null --- .../System.Text.Json/src/System/Text/Json/JsonException.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 38f21042b14d45..9117cbe7caaa1e 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 @@ -89,7 +89,7 @@ protected JsonException(SerializationInfo info, StreamingContext context) : base { LineNumber = (long?)info.GetValue("LineNumber", typeof(long?)); BytePositionInLine = (long?)info.GetValue("BytePositionInLine", typeof(long?)); - Path = info.GetString("Path")!; + Path = info.GetString("Path") ?? string.Empty; SetMessage(info.GetString("ActualMessage")); } From c576bf9b8eec922450461d454963faeea7c4ffba Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Fri, 6 Dec 2019 10:54:14 -0800 Subject: [PATCH 12/25] Fix test, JsonException Path not nullable anymore --- .../tests/BinaryFormatterTestData.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs b/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs index 6f18266d87cf19..6ff4c7beec3c11 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs +++ b/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs @@ -492,7 +492,7 @@ public static IEnumerable SerializableObjects() var jsonException = new JsonException("message", path: "path", lineNumber: 1, bytePositionInLine: 2, innerException: exception); yield return new object[] { PopulateException(jsonException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFNTeXN0ZW0uVGV4dC5Kc29uLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Y2M3YjEzZmZjZDJkZGQ1MQUBAAAAHlN5c3RlbS5UZXh0Lkpzb24uSnNvbkV4Y2VwdGlvbhAAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzCkxpbmVOdW1iZXISQnl0ZVBvc2l0aW9uSW5MaW5lBFBhdGgNQWN0dWFsTWVzc2FnZQEBAwMBAQEAAQABBwMDAQEpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgxTeXN0ZW0uSW50NjQMU3lzdGVtLkludDY0AgAAAAYDAAAAHlN5c3RlbS5UZXh0Lkpzb24uSnNvbkV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKCAkBAAAAAAAAAAgJAgAAAAAAAAAGCwAAAARwYXRoCQQAAAAEBQAAAClTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbAMAAAAEaGVhZAd2ZXJzaW9uBWNvdW50AwAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlCAgJDQAAAAIAAAACAAAABAYAAAAQU3lzdGVtLkV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAIGDgAAABBTeXN0ZW0uRXhjZXB0aW9uCQQAAAAJEAAAAAkRAAAACQcAAAAJCAAAAAkJAAAAAAAAAAroAwAACQoAAAAKBA0AAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUDAAAAA2tleQV2YWx1ZQRuZXh0AgIDOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlBhYAAAAGc2VjcmV0CAEBCRcAAAABEAAAAAUAAAAJGAAAAAIAAAACAAAAAREAAAAGAAAACQ4AAAAGGgAAABdJbm5lciBleGNlcHRpb24gbWVzc2FnZQoKCgoKAAAAAAoAFROACgoBFwAAAA0AAAAICAEAAAAGGwAAAANvbmUKARgAAAANAAAACRYAAAAIAQEJHQAAAAEdAAAADQAAAAgIAQAAAAkbAAAACgs=", TargetFrameworkMoniker.netcoreapp30) } }; - var jsonExceptionNulls = new JsonException("message", null, null, null); + var jsonExceptionNulls = new JsonException("message", string.Empty, null, null); yield return new object[] { PopulateException(jsonExceptionNulls), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFNTeXN0ZW0uVGV4dC5Kc29uLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Y2M3YjEzZmZjZDJkZGQ1MQUBAAAAHlN5c3RlbS5UZXh0Lkpzb24uSnNvbkV4Y2VwdGlvbhAAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzCkxpbmVOdW1iZXISQnl0ZVBvc2l0aW9uSW5MaW5lBFBhdGgNQWN0dWFsTWVzc2FnZQEBAwMBAQEAAQABBwMDAQEpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAm5TeXN0ZW0uTnVsbGFibGVgMVtbU3lzdGVtLkludDY0LCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXW5TeXN0ZW0uTnVsbGFibGVgMVtbU3lzdGVtLkludDY0LCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQIAAAAGAwAAAB5TeXN0ZW0uVGV4dC5Kc29uLkpzb25FeGNlcHRpb24GBAAAAAdtZXNzYWdlCQUAAAAKBgYAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYHAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBggAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgkAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKCgoKCQQAAAAEBQAAAClTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbAMAAAAEaGVhZAd2ZXJzaW9uBWNvdW50AwAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlCAgJCwAAAAIAAAACAAAABAsAAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUDAAAAA2tleQV2YWx1ZQRuZXh0AgIDOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlBgwAAAAGc2VjcmV0CAEBCQ0AAAABDQAAAAsAAAAICAEAAAAGDgAAAANvbmUKCw==", TargetFrameworkMoniker.netcoreapp30) } }; // The JsonReaderException is internal. From f37abb5766a58ae6d705afe25e9438425f7be01d Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Fri, 6 Dec 2019 17:24:17 -0800 Subject: [PATCH 13/25] More review update --- .../Json/Serialization/JsonCamelCaseNamingPolicy.cs | 5 +---- .../System/Text/Json/Serialization/JsonClassInfo.cs | 3 ++- .../Text/Json/Serialization/JsonDefaultNamingPolicy.cs | 5 +---- .../System/Text/Json/Serialization/JsonNamingPolicy.cs | 5 +---- .../System/Text/Json/Serialization/JsonPropertyInfo.cs | 2 +- .../Serialization/JsonSerializer.Read.HandleArray.cs | 5 ++--- .../JsonSerializer.Read.HandleDictionary.cs | 10 +++++++--- .../Serialization/JsonSerializer.Read.HandleNull.cs | 4 +--- .../Serialization/JsonSerializer.Read.HandleObject.cs | 6 ++++-- .../JsonSerializer.Read.HandlePropertyName.cs | 2 +- .../Serialization/JsonSerializer.Read.HandleValue.cs | 2 ++ .../JsonSerializer.Write.HandleDictionary.cs | 7 ++++++- .../System/Text/Json/Serialization/ReadStackFrame.cs | 10 ++++++---- .../Json/Serialization/ReflectionEmitMemberAccessor.cs | 6 ++++-- .../src/System/Text/Json/ThrowHelper.Serialization.cs | 3 ++- 15 files changed, 41 insertions(+), 34 deletions(-) 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 76c9d53ab065da..172d45d8e50c70 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,14 +2,11 @@ // 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 { - [return: NotNullIfNotNull("name")] - public override string? ConvertName(string? 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.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs index 5ee457a7fd095c..a83f9d6edbb557 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 @@ -584,7 +584,8 @@ public static ClassType GetClassType( return ClassType.Enumerable; } - if (type.FullName!.StartsWith("System.Collections.Generic.IEnumerable`1")) + Debug.Assert(type.FullName! != null); + if (type.FullName.StartsWith("System.Collections.Generic.IEnumerable`1")) { elementType = type.GetGenericArguments()[0]; runtimeType = typeof(List<>).MakeGenericType(elementType); 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 3f7dec4f499dee..0f56d4001439e1 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,13 +2,10 @@ // 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 { - [return: NotNullIfNotNull("name")] - public override string? ConvertName(string? name) => 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 c2ab8ed3183f6d..00c2f55b2e243b 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,8 +2,6 @@ // 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 { /// @@ -28,7 +26,6 @@ protected JsonNamingPolicy() { } /// /// The name to convert. /// The converted name. - [return: NotNullIfNotNull("name")] - public abstract string? ConvertName(string? 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 9a178824a420f3..8f6adfdc6830b0 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 @@ -97,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); 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 0136b0cef60e19..854b9a2391ae1c 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 @@ -21,7 +21,7 @@ private static void HandleStartArray(JsonSerializerOptions options, ref ReadStac state.Current.Drain = true; return; } - + Debug.Assert(state.Current.JsonClassInfo != null); JsonPropertyInfo? jsonPropertyInfo = state.Current.JsonPropertyInfo; if (jsonPropertyInfo == null) { @@ -66,8 +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); + state.Current.JsonPropertyInfo!.SetValueAsObject(state.Current.ReturnValue, value); } else { 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 8ddaa6fd66f3fe..29a11f6ca075e5 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 @@ -17,7 +17,7 @@ private static void HandleStartDictionary(JsonSerializerOptions options, ref Rea JsonPropertyInfo? jsonPropertyInfo = state.Current.JsonPropertyInfo; if (jsonPropertyInfo == null) { - jsonPropertyInfo = state.Current.JsonClassInfo.CreateRootProperty(options); + jsonPropertyInfo = state.Current.JsonClassInfo!.CreateRootProperty(options); } Debug.Assert(jsonPropertyInfo != null); @@ -89,12 +89,15 @@ private static void HandleEndDictionary(JsonSerializerOptions options, ref ReadS { if (state.Current.TempDictionaryValues != null) { - JsonDictionaryConverter converter = state.Current.JsonPropertyInfo.DictionaryConverter!; + JsonDictionaryConverter? converter = state.Current.JsonPropertyInfo.DictionaryConverter; + Debug.Assert(converter != null); state.Current.JsonPropertyInfo.SetValueAsObject(state.Current.ReturnValue, converter.CreateFromDictionary(ref state, state.Current.TempDictionaryValues, options)); state.Current.EndProperty(); } else { + Debug.Assert(state.Current.JsonClassInfo != null); + // Handle special case of DataExtensionProperty where we just added a dictionary element to the extension property. // Since the JSON value is not a dictionary element (it's a normal property in JSON) a JsonTokenType.EndObject // encountered here is from the outer object so forward to HandleEndObject(). @@ -114,7 +117,8 @@ private static void HandleEndDictionary(JsonSerializerOptions options, ref ReadS object? value; if (state.Current.TempDictionaryValues != null) { - JsonDictionaryConverter converter = state.Current.JsonPropertyInfo.DictionaryConverter!; + JsonDictionaryConverter? converter = state.Current.JsonPropertyInfo.DictionaryConverter; + Debug.Assert(converter != null); 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 c5c67426333ade..07c81295facd33 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 @@ -28,8 +28,6 @@ private static bool HandleNull(JsonSerializerOptions options, ref Utf8JsonReader return true; } - Debug.Assert(jsonPropertyInfo != null); - if (state.Current.IsProcessingCollectionObject()) { AddNullToCollection(jsonPropertyInfo, ref reader, ref state); @@ -71,7 +69,7 @@ private static bool HandleNull(JsonSerializerOptions options, ref Utf8JsonReader if (!jsonPropertyInfo.IgnoreNullValues) { - state.Current.JsonPropertyInfo!.SetValueAsObject(state.Current.ReturnValue, value: null); + jsonPropertyInfo.SetValueAsObject(state.Current.ReturnValue, value: null); } return 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 5795dc40d982c1..2bb5d5d882aebd 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(); @@ -39,7 +39,7 @@ private static void HandleStartObject(JsonSerializerOptions options, ref ReadSta state.Current.Initialize(objType, options); } - JsonClassInfo classInfo = state.Current.JsonClassInfo; + JsonClassInfo classInfo = state.Current.JsonClassInfo!; if (state.Current.IsProcessingObject(ClassType.Dictionary)) { @@ -72,6 +72,8 @@ private static void HandleStartObject(JsonSerializerOptions options, ref ReadSta private static void HandleEndObject(ref ReadStack state) { + Debug.Assert(state.Current.JsonClassInfo != null); + // Only allow dictionaries to be processed here if this is the DataExtensionProperty. Debug.Assert(!state.Current.IsProcessingDictionary() || state.Current.JsonClassInfo.DataExtensionProperty == state.Current.JsonPropertyInfo); 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 2b96ba518107ff..aa9563e9429005 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; 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 633faf89a5a3f7..38e25cbe6d02b9 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 @@ -2,6 +2,7 @@ // 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.Runtime.CompilerServices; namespace System.Text.Json @@ -18,6 +19,7 @@ private static void HandleValue(JsonTokenType tokenType, JsonSerializerOptions o } JsonPropertyInfo? jsonPropertyInfo = state.Current.JsonPropertyInfo; + Debug.Assert(state.Current.JsonClassInfo != null); if (jsonPropertyInfo == null) { jsonPropertyInfo = state.Current.JsonClassInfo.CreateRootProperty(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 1fe93f7aa77330..c3df564d2df50d 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 @@ -81,6 +81,11 @@ private static bool HandleDictionary( if (options.DictionaryKeyPolicy != null && state.Current.ExtensionDataStatus != ExtensionDataWriteStatus.Writing) { + if (key == null) + { + ThrowHelper.ThrowInvalidOperationException_SerializerDictionaryKeyNull(options.DictionaryKeyPolicy.GetType()); + } + key = options.DictionaryKeyPolicy.ConvertName(key); } @@ -123,7 +128,7 @@ internal static void WriteDictionary( { Debug.Assert(converter != null && current.CollectionEnumerator != null); - string? key; + string key; TProperty value; if (current.CollectionEnumerator is IEnumerator> enumerator) { 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 a0a8a18d6c510b..76844bd608ea24 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 @@ -14,7 +14,7 @@ internal struct ReadStackFrame { // The object (POCO or IEnumerable) that is being populated public object? ReturnValue; - public JsonClassInfo JsonClassInfo; + public JsonClassInfo? JsonClassInfo; // Support Dictionary keys. public string? KeyName; @@ -94,6 +94,7 @@ public bool IsProcessingEnumerable() /// public bool IsProcessingObject(ClassType classTypes) { + Debug.Assert(JsonClassInfo != null); return (JsonClassInfo.ClassType & classTypes) != 0; } @@ -129,6 +130,7 @@ public bool IsProcessingValue() } else if (JsonPropertyInfo == null) { + Debug.Assert(JsonClassInfo != null); classType = JsonClassInfo.ClassType; } else @@ -153,14 +155,14 @@ public void InitializeJsonPropertyInfo() { if (IsProcessingObject(ClassType.Value | ClassType.Enumerable | ClassType.Dictionary)) { - JsonPropertyInfo = JsonClassInfo.PolicyProperty; + JsonPropertyInfo = JsonClassInfo!.PolicyProperty; } } public void Reset() { Drain = false; - JsonClassInfo = null!; + JsonClassInfo = null; PropertyRefCache = null; ReturnValue = null; EndObject(); @@ -273,7 +275,7 @@ public Type GetElementType() if (IsProcessingCollectionObject()) { - return JsonClassInfo.ElementClassInfo!.Type; + return JsonClassInfo!.ElementClassInfo!.Type; } return JsonPropertyInfo.RuntimePropertyType; 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 5ec012d30feca7..c83b95f892653c 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 @@ -95,8 +95,9 @@ public override Action CreateAddDelegate(MethodInfo addMet JsonClassInfo.ConstructorDelegate constructor = (JsonClassInfo.ConstructorDelegate)dynamicMethod.CreateDelegate( typeof(JsonClassInfo.ConstructorDelegate)); - ImmutableCollectionCreator creator = (ImmutableCollectionCreator)constructor()!; + ImmutableCollectionCreator? creator = (ImmutableCollectionCreator?)constructor(); + Debug.Assert(creator != null); creator.RegisterCreatorDelegateFromMethod(createRange); return creator; } @@ -143,8 +144,9 @@ public override Action CreateAddDelegate(MethodInfo addMet JsonClassInfo.ConstructorDelegate constructor = (JsonClassInfo.ConstructorDelegate)dynamicMethod.CreateDelegate( typeof(JsonClassInfo.ConstructorDelegate)); - ImmutableCollectionCreator creator = (ImmutableCollectionCreator)constructor()!; + ImmutableCollectionCreator? creator = (ImmutableCollectionCreator?)constructor(); + Debug.Assert(creator != null); creator.RegisterCreatorDelegateFromMethod(createRange); return creator; } 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 ac2d64dada2423..617db91e177934 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 @@ -132,6 +132,7 @@ public static void ThrowInvalidOperationException_SerializerPropertyNameNull(Typ throw new InvalidOperationException(SR.Format(SR.SerializerPropertyNameNull, parentType, jsonPropertyInfo.PropertyInfo?.Name)); } + [DoesNotReturn] [MethodImpl(MethodImplOptions.NoInlining)] public static void ThrowInvalidOperationException_SerializerDictionaryKeyNull(Type policyType) { @@ -185,7 +186,7 @@ public static void AddExceptionInformation(in ReadStack readStack, in Utf8JsonRe Type? propertyType = readStack.Current.JsonPropertyInfo?.RuntimePropertyType; if (propertyType == null) { - propertyType = readStack.Current.JsonClassInfo.Type; + propertyType = readStack.Current.JsonClassInfo?.Type; } message = SR.Format(SR.DeserializeUnableToConvertValue, propertyType); From de20ef43d2ef41ad00f20abdd247ef5ad99b0f5b Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Mon, 9 Dec 2019 17:58:11 -0800 Subject: [PATCH 14/25] Addressing more feedback --- .../System.Text.Json/ref/System.Text.Json.cs | 3 +- .../Generic/StackExtensions.netstandard.cs | 4 +-- .../Text/Json/Document/JsonDocument.Parse.cs | 6 ++-- .../Document/JsonDocument.StackRowStack.cs | 2 +- .../Document/JsonElement.ArrayEnumerator.cs | 2 +- .../Document/JsonElement.ObjectEnumerator.cs | 2 +- .../JsonSerializer.Write.HandleDictionary.cs | 4 +-- .../JsonSerializerOptions.Converters.cs | 7 ++-- .../CustomConverterTests.BadConverters.cs | 33 +++++++++++++++++++ .../tests/Serialization/PropertyNameTests.cs | 20 +++++++++++ 10 files changed, 66 insertions(+), 17 deletions(-) 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 169c33d0307e8d..a688ca5c321f15 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -231,8 +231,7 @@ public abstract partial class JsonNamingPolicy { protected JsonNamingPolicy() { } public static System.Text.Json.JsonNamingPolicy CamelCase { get { throw null; } } - [return: System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute("name")] - public abstract string? ConvertName(string? name); + public abstract string ConvertName(string name); } public abstract partial class JsonNode { 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 695037bfcb3bb7..7819cddd4a9a9c 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 @@ -19,7 +19,7 @@ public static bool TryPeek(this Stack stack, [MaybeNullWhen(false)] out T return true; } - result = default!; + result = default; return false; } @@ -31,7 +31,7 @@ public static bool TryPop(this Stack stack, [MaybeNullWhen(false)] out T r return true; } - result = default!; + result = default; return false; } } 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 1f680f259e9740..d8b19dddbe1085 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 @@ -119,7 +119,7 @@ public static JsonDocument Parse(Stream utf8Json, JsonDocumentOptions options = } ArraySegment drained = ReadToEnd(utf8Json); - + Debug.Assert(drained.Array != null); try { return Parse(drained.AsMemory(), options.GetReaderOptions(), drained.Array); @@ -128,7 +128,6 @@ public static JsonDocument Parse(Stream utf8Json, JsonDocumentOptions options = { // Holds document content, clear it before returning it. drained.AsSpan().Clear(); - Debug.Assert(drained.Array != null); ArrayPool.Shared.Return(drained.Array); throw; } @@ -169,7 +168,7 @@ private static async Task ParseAsyncCore( CancellationToken cancellationToken = default) { ArraySegment drained = await ReadToEndAsync(utf8Json, cancellationToken).ConfigureAwait(false); - + Debug.Assert(drained.Array != null); try { return Parse(drained.AsMemory(), options.GetReaderOptions(), drained.Array); @@ -178,7 +177,6 @@ private static async Task ParseAsyncCore( { // Holds document content, clear it before returning it. drained.AsSpan().Clear(); - Debug.Assert(drained.Array != null); ArrayPool.Shared.Return(drained.Array); throw; } 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 edcff2c8613a47..83d21fbbb4e38a 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,7 +23,7 @@ internal StackRowStack(int initialSize) public void Dispose() { - byte[]? toReturn = _rentedBuffer; + byte[] toReturn = _rentedBuffer; _rentedBuffer = null!; _topOfStack = 0; 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 f2ead3bcebb62f..5bf085fdc390f8 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 @@ -24,6 +24,7 @@ internal ArrayEnumerator(JsonElement target) { _target = target; _curIdx = -1; + Debug.Assert(target._parent != null); if (target._parent is JsonDocument document) { @@ -33,7 +34,6 @@ internal ArrayEnumerator(JsonElement target) } else { - Debug.Assert(target._parent != null); var jsonArray = (JsonArray)target._parent; _endIdxOrVersion = jsonArray._version; } 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 04d118fa7e193c..ae9f794137bac2 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 @@ -26,6 +26,7 @@ internal ObjectEnumerator(JsonElement target) _target = target; _curIdx = -1; _current = null; + Debug.Assert(target._parent != null); if (target._parent is JsonDocument document) { @@ -34,7 +35,6 @@ internal ObjectEnumerator(JsonElement target) } else { - Debug.Assert(target._parent != null); var jsonObject = (JsonObject)target._parent; _endIdxOrVersion = jsonObject._version; } 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 c3df564d2df50d..d318f5b4d8cba2 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 @@ -81,12 +81,12 @@ private static bool HandleDictionary( if (options.DictionaryKeyPolicy != null && state.Current.ExtensionDataStatus != ExtensionDataWriteStatus.Writing) { + Debug.Assert(key != null); + key = options.DictionaryKeyPolicy.ConvertName(key); if (key == null) { ThrowHelper.ThrowInvalidOperationException_SerializerDictionaryKeyNull(options.DictionaryKeyPolicy.GetType()); } - - key = options.DictionaryKeyPolicy.ConvertName(key); } // An object or another enumerator requires a new stack frame. 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 e4e5caf5d3c423..2b5a5137fbd7c8 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 @@ -163,11 +163,10 @@ private static List GetDefaultConverters() if (converter != null) { - Debug.Assert(converter.TypeToConvert != null); - Type converterTypeToConvert = converter.TypeToConvert; + Type? converterTypeToConvert = converter.TypeToConvert; - if (!converterTypeToConvert.IsAssignableFrom(typeToConvert) && - !typeToConvert.IsAssignableFrom(converterTypeToConvert)) + if (converterTypeToConvert == null || (!converterTypeToConvert.IsAssignableFrom(typeToConvert) && + !typeToConvert.IsAssignableFrom(converterTypeToConvert))) { ThrowHelper.ThrowInvalidOperationException_SerializationConverterNotCompatible(converter.GetType(), typeToConvert); } diff --git a/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests.BadConverters.cs b/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests.BadConverters.cs index 4be8dd20abbe9f..9b047ae32f0046 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests.BadConverters.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests.BadConverters.cs @@ -332,5 +332,38 @@ public static void TypeHasMoreThanOneConverter() Assert.Contains("'System.Text.Json.Serialization.JsonConverterAttribute'", ex.Message); Assert.Contains("'System.Text.Json.Serialization.Tests.CustomConverterTests+PocoWithTwoConverters'", ex.Message); } + + [Fact] + public static void ConverterWithoutDefaultCtor() + { + string json = @"{""MyType"":""ABC""}"; + + InvalidOperationException ex = Assert.Throws(() => JsonSerializer.Deserialize(json)); + Assert.Equal("The converter specified on 'System.Text.Json.Serialization.Tests.CustomConverterTests+ClassWithConverterWithoutPublicEmptyCtor' " + + "does not derive from JsonConverter or have a public parameterless constructor.", ex.Message); + } + + [JsonConverter(typeof(ConverterWithoutPublicEmptyCtor))] + public class ClassWithConverterWithoutPublicEmptyCtor + { + public string MyType { get; set; } + } + + internal class ConverterWithoutPublicEmptyCtor : JsonConverter + { + public ConverterWithoutPublicEmptyCtor(int x) + { + } + + public override ClassWithConverterWithoutPublicEmptyCtor Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + throw new NotImplementedException(); + } + + public override void Write(Utf8JsonWriter writer, ClassWithConverterWithoutPublicEmptyCtor value, JsonSerializerOptions options) + { + throw new NotImplementedException(); + } + } } } diff --git a/src/libraries/System.Text.Json/tests/Serialization/PropertyNameTests.cs b/src/libraries/System.Text.Json/tests/Serialization/PropertyNameTests.cs index c5feea340c20c6..a13f36661798b4 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/PropertyNameTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/PropertyNameTests.cs @@ -430,6 +430,26 @@ public static void LongPropertyNames(int propertyLength, char ch) string jsonRoundTripped = JsonSerializer.Serialize(obj, options); Assert.Equal(json, jsonRoundTripped); } + + [Fact] + public static void BadNamingPolicy_ThrowsInvalidOperation() + { + var options = new JsonSerializerOptions { DictionaryKeyPolicy = new NullNamingPolicy() }; + + var inputPrimitive = new Dictionary + { + { "validKey", 1 } + }; + + Assert.Throws(() => JsonSerializer.Serialize(inputPrimitive, options)); + + var inputClass = new Dictionary + { + { "validKey", new OverridePropertyNameDesignTime_TestClass() } + }; + + Assert.Throws(() => JsonSerializer.Serialize(inputClass, options)); + } } public class OverridePropertyNameDesignTime_TestClass From ee302fb1bc98282d7efe83703e4da3f3fcb18698 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Tue, 10 Dec 2019 14:20:43 -0800 Subject: [PATCH 15/25] Applying more feedback --- .../Converters/JsonValueConverterChar.cs | 7 ++++++- .../Converters/JsonValueConverterKeyValuePair.cs | 4 ++-- .../Converters/JsonValueConverterUri.cs | 2 -- .../System/Text/Json/Serialization/JsonClassInfo.cs | 2 +- .../JsonSerializerOptions.Converters.cs | 2 +- .../Json/Serialization/PooledByteBufferWriter.cs | 4 ++-- .../src/System/Text/Json/ThrowHelper.cs | 5 +++++ .../CustomConverterTests.BadConverters.cs | 3 +-- .../tests/Serialization/Null.ReadTests.cs | 13 +++++++++++++ 9 files changed, 31 insertions(+), 11 deletions(-) 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 101b145ba38ee3..8b74d24f4b8638 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 @@ -10,7 +10,12 @@ internal sealed class JsonConverterChar : JsonConverter { public override char Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions? options) { - return reader.GetString()![0]; + string? str = reader.GetString(); + if (string.IsNullOrEmpty(str) || str.Length > 1) + { + throw ThrowHelper.GetInvalidOperationException_ExpectedChar(reader.TokenType); + } + return str[0]; } public override void Write(Utf8JsonWriter writer, char value, JsonSerializerOptions? options) 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 c148c0fcbcf072..09fb77c1c2cb3d 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 @@ -38,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); @@ -61,7 +61,7 @@ public override KeyValuePair Read(ref Utf8JsonReader reader, Type ThrowHelper.ThrowJsonException(); } - propertyName = reader.GetString(); + propertyName = reader.GetString()!; if (propertyName == ValueName) { v = ReadProperty(ref reader, typeToConvert, options); 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 2d75f1ad0b0689..9688c46338abe7 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,8 +2,6 @@ // 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 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 a83f9d6edbb557..d6ebc20519fc77 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 @@ -584,7 +584,7 @@ public static ClassType GetClassType( return ClassType.Enumerable; } - Debug.Assert(type.FullName! != null); + Debug.Assert(type.FullName != null); if (type.FullName.StartsWith("System.Collections.Generic.IEnumerable`1")) { elementType = type.GetGenericArguments()[0]; 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 2b5a5137fbd7c8..952d13176a286f 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 @@ -211,7 +211,7 @@ private JsonConverter GetConverterFromAttribute(JsonConverterAttribute converter ThrowHelper.ThrowInvalidOperationException_SerializationConverterOnAttributeInvalid(classTypeAttributeIsOn, propertyInfo); } - converter = (JsonConverter?)Activator.CreateInstance(type); + converter = (JsonConverter)Activator.CreateInstance(type)!; } Debug.Assert(converter != null); 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 a94a5544fd0e68..6f6a7ae89d5710 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; @@ -86,7 +86,7 @@ public void Dispose() ClearHelper(); ArrayPool.Shared.Return(_rentedBuffer); - _rentedBuffer = null; + _rentedBuffer = null!; } public void Advance(int count) 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 921268bf06eede..08ca23d0911e05 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 @@ -611,6 +611,11 @@ public static FormatException GetFormatException(DataType dateType) ex.Source = ExceptionSourceValueToRethrowAsJsonException; return ex; } + + public static InvalidOperationException GetInvalidOperationException_ExpectedChar(JsonTokenType tokenType) + { + return GetInvalidOperationException("char", tokenType); + } } internal enum ExceptionResource diff --git a/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests.BadConverters.cs b/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests.BadConverters.cs index 9b047ae32f0046..493e80a5eb520d 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests.BadConverters.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests.BadConverters.cs @@ -339,8 +339,7 @@ public static void ConverterWithoutDefaultCtor() string json = @"{""MyType"":""ABC""}"; InvalidOperationException ex = Assert.Throws(() => JsonSerializer.Deserialize(json)); - Assert.Equal("The converter specified on 'System.Text.Json.Serialization.Tests.CustomConverterTests+ClassWithConverterWithoutPublicEmptyCtor' " + - "does not derive from JsonConverter or have a public parameterless constructor.", ex.Message); + Assert.Contains("'System.Text.Json.Serialization.Tests.CustomConverterTests+ClassWithConverterWithoutPublicEmptyCtor'", ex.Message); } [JsonConverter(typeof(ConverterWithoutPublicEmptyCtor))] diff --git a/src/libraries/System.Text.Json/tests/Serialization/Null.ReadTests.cs b/src/libraries/System.Text.Json/tests/Serialization/Null.ReadTests.cs index d0614cfdbace50..83418a02132159 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/Null.ReadTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/Null.ReadTests.cs @@ -152,5 +152,18 @@ public static void NullAcceptsLeadingAndTrailingTrivia() Assert.Null(obj); } } + + [Fact] + public static void NullReadTestChar() + { + Assert.Throws(() => JsonSerializer.Deserialize("null")); + Assert.Throws(() => JsonSerializer.Deserialize("")); + Assert.Throws(() => JsonSerializer.Deserialize("1234")); + Assert.Throws(() => JsonSerializer.Deserialize("\"stringTooLong\"")); + Assert.Throws(() => JsonSerializer.Deserialize("\"\u0059\"B")); + Assert.Throws(() => JsonSerializer.Deserialize("\"\uD800\uDC00\"")); + Assert.Equal('a', JsonSerializer.Deserialize("\"a\"")); + Assert.Equal('Y', JsonSerializer.Deserialize("\"\u0059\"")); + } } } From cf61bab2bf4eb3ed01dc10f7ccf1ef353d2b0242 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Fri, 13 Dec 2019 12:02:42 -0800 Subject: [PATCH 16/25] Applying feedback, removing IEquatable workaround --- .../System.Text.Json/ref/System.Text.Json.cs | 20 ++---- .../Document/JsonElement.ArrayEnumerator.cs | 2 +- .../Document/JsonElement.ObjectEnumerator.cs | 2 +- .../System/Text/Json/Document/JsonElement.cs | 62 +++++++++---------- .../src/System/Text/Json/Node/JsonBoolean.cs | 5 +- .../src/System/Text/Json/Node/JsonNull.cs | 5 +- .../src/System/Text/Json/Node/JsonNumber.cs | 5 +- .../src/System/Text/Json/Node/JsonString.cs | 5 +- .../Converters/JsonConverterEnum.cs | 2 +- .../Converters/JsonKeyValuePairConverter.cs | 2 +- .../Text/Json/Serialization/JsonClassInfo.cs | 35 ++++++----- .../Serialization/JsonConverterFactory.cs | 4 +- .../Json/Serialization/JsonPropertyInfo.cs | 4 +- .../Serialization/JsonPropertyInfoNullable.cs | 4 +- .../Serialization/JsonStringEnumConverter.cs | 2 +- .../Text/Json/Serialization/WriteStack.cs | 2 +- .../tests/Serialization/ReadValueTests.cs | 17 +++++ 17 files changed, 87 insertions(+), 91 deletions(-) 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 a688ca5c321f15..35a74aba1e20f1 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -65,10 +65,7 @@ public void Dispose() { } public bool MoveNext() { throw null; } void System.Collections.IEnumerator.Reset() { } } - 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 sealed partial class JsonBoolean : System.Text.Json.JsonNode, System.IEquatable { public JsonBoolean() { } public JsonBoolean(bool value) { } @@ -274,10 +271,7 @@ 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, -#nullable disable // to enable use with both T and T? for reference types due to IEquatable being invariant - System.IEquatable -#nullable restore + public sealed partial class JsonNull : System.Text.Json.JsonNode, System.IEquatable { public JsonNull() { } public override System.Text.Json.JsonValueKind ValueKind { get { throw null; } } @@ -289,10 +283,7 @@ public JsonNull() { } 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, -#nullable disable // to enable use with both T and T? for reference types due to IEquatable being invariant - System.IEquatable -#nullable restore + public sealed partial class JsonNumber : System.Text.Json.JsonNode, System.IEquatable { public JsonNumber() { } public JsonNumber(byte value) { } @@ -472,10 +463,7 @@ public JsonSerializerOptions() { } public bool WriteIndented { get { throw null; } set { } } public System.Text.Json.Serialization.JsonConverter? GetConverter(System.Type typeToConvert) { throw null; } } - 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 sealed partial class JsonString : System.Text.Json.JsonNode, System.IEquatable { public JsonString() { } public JsonString(System.DateTime value) { } 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 5bf085fdc390f8..d7bdcb4ed4ce3f 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 @@ -59,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); } } 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 ae9f794137bac2..ca5e4911af06ff 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 @@ -60,7 +60,7 @@ public JsonProperty Current return default; } - var document = (JsonDocument?)_target._parent; + var document = (JsonDocument)_target._parent; return new JsonProperty(new JsonElement(document, _curIdx)); } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonElement.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonElement.cs index e952feaa05fe7e..f4db2eb597725e 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonElement.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonElement.cs @@ -14,10 +14,10 @@ namespace System.Text.Json [DebuggerDisplay("{DebuggerDisplay,nq}")] public readonly partial struct JsonElement { - internal readonly object? _parent; + internal readonly object _parent; private readonly int _idx; - internal JsonElement(JsonDocument? parent, int idx) + internal JsonElement(JsonDocument parent, int idx) { // parent is usually not null, but the Current property // on the enumerators (when initialized as `default`) can @@ -44,7 +44,7 @@ private JsonTokenType TokenType { get { - JsonDocument? document = (JsonDocument?)_parent; + JsonDocument document = (JsonDocument)_parent; return document?.GetJsonTokenType(_idx) ?? JsonTokenType.None; } } @@ -94,7 +94,7 @@ public JsonElement this[int index] return document.GetArrayIndexElement(_idx, index); } - var jsonNode = (JsonNode)_parent!; + var jsonNode = (JsonNode)_parent; if (jsonNode is JsonArray jsonArray) { @@ -124,7 +124,7 @@ public int GetArrayLength() return document.GetArrayLength(_idx); } - var jsonNode = (JsonNode)_parent!; + var jsonNode = (JsonNode)_parent; if (jsonNode is JsonArray jsonArray) { @@ -326,7 +326,7 @@ public bool TryGetProperty(ReadOnlySpan propertyName, out JsonElement valu return document.TryGetNamedPropertyValue(_idx, propertyName, out value); } - var jsonNode = (JsonNode)_parent!; + var jsonNode = (JsonNode)_parent; if (jsonNode is JsonObject jsonObject) { @@ -381,7 +381,7 @@ 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) { @@ -426,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) { @@ -459,7 +459,7 @@ public bool GetBoolean() return document.GetString(_idx, JsonTokenType.String); } - var jsonNode = (JsonNode)_parent!; + var jsonNode = (JsonNode)_parent; if (jsonNode is JsonString jsonString) { @@ -495,7 +495,7 @@ public bool TryGetBytesFromBase64([NotNullWhen(true)] out byte[]? value) return document.TryGetValue(_idx, out value); } - var jsonNode = (JsonNode)_parent!; + var jsonNode = (JsonNode)_parent; if (jsonNode is JsonString jsonString) { @@ -559,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) { @@ -619,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) { @@ -681,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) { @@ -741,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) { @@ -804,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) { @@ -864,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) { @@ -927,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) { @@ -990,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) { @@ -1062,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) { @@ -1141,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) { @@ -1212,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) { @@ -1275,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) { @@ -1338,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) { @@ -1401,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) { @@ -1442,7 +1442,7 @@ internal string GetPropertyName() { CheckValidInstance(); - var document = (JsonDocument)_parent!; + var document = (JsonDocument)_parent; return document.GetNameOfPropertyValue(_idx); } @@ -1467,7 +1467,7 @@ public string GetRawText() return document.GetRawValueAsString(_idx); } - var jsonNode = (JsonNode)_parent!; + var jsonNode = (JsonNode)_parent; return jsonNode.ToJsonString(); } @@ -1475,7 +1475,7 @@ internal string GetPropertyRawText() { CheckValidInstance(); - var document = (JsonDocument)_parent!; + var document = (JsonDocument)_parent; return document.GetPropertyRawValueAsString(_idx); } @@ -1567,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); } @@ -1575,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); } @@ -1607,7 +1607,7 @@ public void WriteTo(Utf8JsonWriter writer) } else { - var jsonNode = (JsonNode)_parent!; + var jsonNode = (JsonNode)_parent; jsonNode.WriteTo(writer); } } @@ -1789,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/Node/JsonBoolean.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonBoolean.cs index 8f36a690b04a85..39ecf336441e1b 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,10 +7,7 @@ namespace System.Text.Json /// /// Represents a mutable boolean JSON value. /// - 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 + public sealed class JsonBoolean : JsonNode, IEquatable { /// /// Initializes a new instance of the class representing the value . 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 efa4fd0d978824..8057e49432ce25 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,10 +7,7 @@ namespace System.Text.Json /// /// Represents the null JSON value. /// - 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 + public sealed class JsonNull : JsonNode, IEquatable { /// /// Initializes a new instance of the class representing the value . 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 1faad281db52f0..8a0146aaf491b7 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,10 +9,7 @@ namespace System.Text.Json /// /// Represents a mutable numeric JSON value. /// - 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 + public sealed class JsonNumber : JsonNode, IEquatable { private string _value = null!; 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 fe841698278faa..bcb72673cfc7fa 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 @@ -12,10 +12,7 @@ namespace System.Text.Json /// /// Represents a mutable text JSON value. /// - 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 + public sealed class JsonString : JsonNode, IEquatable { private string _value = null!; 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 2e7c0c63721c06..e9454e47f10e7a 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,7 +21,7 @@ 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), 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 1678c8ab844e59..75130f3da4ce2e 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]; 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 d6ebc20519fc77..dcc2a92e18dd15 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 @@ -158,7 +158,7 @@ public JsonClassInfo(Type type, JsonSerializerOptions options) 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]; @@ -584,25 +584,28 @@ public static ClassType GetClassType( return ClassType.Enumerable; } - Debug.Assert(type.FullName != null); - if (type.FullName.StartsWith("System.Collections.Generic.IEnumerable`1")) + if (type.FullName != null) { - elementType = type.GetGenericArguments()[0]; - runtimeType = typeof(List<>).MakeGenericType(elementType); - addMethod = default; - return ClassType.Enumerable; - } - else if (type.FullName.StartsWith("System.Collections.Generic.IDictionary`2") || - type.FullName.StartsWith("System.Collections.Generic.IReadOnlyDictionary`2")) - { - Type[] genericTypes = type.GetGenericArguments(); + if (type.FullName.StartsWith("System.Collections.Generic.IEnumerable`1")) + { + elementType = type.GetGenericArguments()[0]; + runtimeType = typeof(List<>).MakeGenericType(elementType); + addMethod = default; + return ClassType.Enumerable; + } + else if (type.FullName.StartsWith("System.Collections.Generic.IDictionary`2") || + type.FullName.StartsWith("System.Collections.Generic.IReadOnlyDictionary`2")) + { + Type[] genericTypes = type.GetGenericArguments(); - elementType = genericTypes[1]; - runtimeType = typeof(Dictionary<,>).MakeGenericType(genericTypes[0], elementType); - addMethod = default; - return ClassType.Dictionary; + elementType = genericTypes[1]; + runtimeType = typeof(Dictionary<,>).MakeGenericType(genericTypes[0], elementType); + addMethod = default; + return ClassType.Dictionary; + } } + { Type? genericIDictionaryType = type.GetInterface("System.Collections.Generic.IDictionary`2") ?? type.GetInterface("System.Collections.Generic.IReadOnlyDictionary`2"); if (genericIDictionaryType != 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 e03b8894419c42..cd4c2c7f40eb64 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/JsonPropertyInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfo.cs index 8f6adfdc6830b0..7807673ce826da 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 @@ -238,9 +238,9 @@ public JsonClassInfo? ElementClassInfo // 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(); 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 1dc66e8dff3644..c5dbac440df0f7 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 @@ -128,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); } } 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 3c0973afdda5b4..28faf547731864 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 @@ -57,7 +57,7 @@ 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), 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 23cc8041800550..b35aa09baa555f 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 @@ -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 { diff --git a/src/libraries/System.Text.Json/tests/Serialization/ReadValueTests.cs b/src/libraries/System.Text.Json/tests/Serialization/ReadValueTests.cs index 1e29cebd8aff4f..0125fb78354092 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/ReadValueTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/ReadValueTests.cs @@ -3,7 +3,9 @@ // See the LICENSE file in the project root for more information. using System.Buffers; +using System.Collections.Generic; using System.IO; +using System.Reflection; using System.Threading.Tasks; using Xunit; @@ -567,4 +569,19 @@ public static void TooLittleJsonForIntArray(string json) Assert.Equal(0, reader.BytesConsumed); } } + + public class FullNameNullTest + { + private static void MyMethod(List param) + { + } + + [Fact] + public static void TypeFullNameNullTest() + { + MethodInfo[] methods = typeof(FullNameNullTest).GetMethods(BindingFlags.Static | BindingFlags.NonPublic); + var parameters = methods[0].GetParameters(); + Assert.Throws(() => JsonSerializer.Deserialize("{}", parameters[0].ParameterType)); + } + } } From 511879017d05b35d28a973e2aabe2696c85b9812 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Fri, 13 Dec 2019 18:24:27 -0800 Subject: [PATCH 17/25] More feedback --- .../src/System/Text/Json/Serialization/JsonPropertyInfo.cs | 2 +- .../System.Text.Json/tests/Serialization/ReadValueTests.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) 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 7807673ce826da..3b890e01aa1f85 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 @@ -355,7 +355,7 @@ 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; } = null!; public PropertyInfo? PropertyInfo { get; private set; } diff --git a/src/libraries/System.Text.Json/tests/Serialization/ReadValueTests.cs b/src/libraries/System.Text.Json/tests/Serialization/ReadValueTests.cs index 0125fb78354092..41e171532069c4 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/ReadValueTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/ReadValueTests.cs @@ -572,7 +572,7 @@ public static void TooLittleJsonForIntArray(string json) public class FullNameNullTest { - private static void MyMethod(List param) + private static void EmptyGenericMethod(List param) { } @@ -580,7 +580,7 @@ private static void MyMethod(List param) public static void TypeFullNameNullTest() { MethodInfo[] methods = typeof(FullNameNullTest).GetMethods(BindingFlags.Static | BindingFlags.NonPublic); - var parameters = methods[0].GetParameters(); + ParameterInfo[] parameters = methods[0].GetParameters(); Assert.Throws(() => JsonSerializer.Deserialize("{}", parameters[0].ParameterType)); } } From af8efe8a34f8bd33d3f39596a880d98c73b4463c Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Mon, 16 Dec 2019 10:22:20 -0800 Subject: [PATCH 18/25] Options not null for Converter.Read/Write --- src/libraries/System.Text.Json/ref/System.Text.Json.cs | 4 ++-- .../Serialization/Converters/JsonValueConverterBoolean.cs | 4 ++-- .../Json/Serialization/Converters/JsonValueConverterByte.cs | 4 ++-- .../Serialization/Converters/JsonValueConverterByteArray.cs | 4 ++-- .../Json/Serialization/Converters/JsonValueConverterChar.cs | 4 ++-- .../Serialization/Converters/JsonValueConverterDateTime.cs | 4 ++-- .../Converters/JsonValueConverterDateTimeOffset.cs | 4 ++-- .../Serialization/Converters/JsonValueConverterDecimal.cs | 4 ++-- .../Json/Serialization/Converters/JsonValueConverterDouble.cs | 4 ++-- .../Json/Serialization/Converters/JsonValueConverterEnum.cs | 4 ++-- .../Json/Serialization/Converters/JsonValueConverterGuid.cs | 4 ++-- .../Json/Serialization/Converters/JsonValueConverterInt16.cs | 4 ++-- .../Json/Serialization/Converters/JsonValueConverterInt32.cs | 4 ++-- .../Json/Serialization/Converters/JsonValueConverterInt64.cs | 4 ++-- .../Serialization/Converters/JsonValueConverterJsonElement.cs | 4 ++-- .../Converters/JsonValueConverterKeyValuePair.cs | 4 ++-- .../Json/Serialization/Converters/JsonValueConverterObject.cs | 4 ++-- .../Json/Serialization/Converters/JsonValueConverterSByte.cs | 4 ++-- .../Json/Serialization/Converters/JsonValueConverterSingle.cs | 4 ++-- .../Json/Serialization/Converters/JsonValueConverterString.cs | 4 ++-- .../Json/Serialization/Converters/JsonValueConverterUInt16.cs | 4 ++-- .../Json/Serialization/Converters/JsonValueConverterUInt64.cs | 4 ++-- .../Json/Serialization/Converters/JsonValueConverterUri.cs | 4 ++-- .../src/System/Text/Json/Serialization/JsonConverterOfT.cs | 4 ++-- 24 files changed, 48 insertions(+), 48 deletions(-) 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 35a74aba1e20f1..7fb71819c879c7 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -746,8 +746,8 @@ public abstract partial class JsonConverter : System.Text.Json.Serialization. { 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 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 0b2fd7705f02d5..755f4a209e61df 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 8dc76d281e2924..b668fe41c237a4 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 300eb8ebc3fc5c..df478133610050 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 8b74d24f4b8638..f225ae40395f46 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,7 +8,7 @@ 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) { string? str = reader.GetString(); if (string.IsNullOrEmpty(str) || str.Length > 1) @@ -18,7 +18,7 @@ public override char Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSer return str[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 e3dafdf5f9c743..cdd837f1ab8e6d 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 785eb41ccf26bc..268c164e907d11 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 72cc177596aedc..f951e39211e7fd 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 d74d65e5ee8e2c..c53708d81e2cba 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 e9750db3c1420d..65f6dbf1980daa 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 @@ -44,7 +44,7 @@ public JsonConverterEnum(EnumConverterOptions options, JsonNamingPolicy? namingP _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; @@ -152,7 +152,7 @@ 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)) 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 563d29b8b84fe5..379fcc33beba94 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 a3587209a92f42..39d844feed31c0 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 72ee7bd349ffa0..fb4e28de1bba97 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 96f14678487070..6f82397be872ed 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 d7c933c97eab29..b8a4da3efca796 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 09fb77c1c2cb3d..384f62e5b798ad 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 @@ -18,7 +18,7 @@ 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) { @@ -92,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; 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 e180ca3e70b9d3..27a361ebae7824 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 22a76d1d0abd56..239dbbd44f83d5 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 5646da702219c5..ba5a3a16965753 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 2aaf3c10c8755b..598b059c8a2b0e 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 @@ -6,12 +6,12 @@ namespace System.Text.Json.Serialization.Converters { 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 2940f2ea906d18..4939aff78b288c 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/JsonValueConverterUInt64.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterUInt64.cs index 4f5d6eb4929440..4bb14140987e44 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 9688c46338abe7..0a8215210640bf 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 @@ -6,7 +6,7 @@ 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)) @@ -18,7 +18,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/JsonConverterOfT.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs index b188b84a1b5e7c..df8577a2d3e6bf 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); } From e30fc73e0499b62032600ed072c4af2365914f8e Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Mon, 16 Dec 2019 10:24:12 -0800 Subject: [PATCH 19/25] One more converter --- .../Json/Serialization/Converters/JsonValueConverterUInt32.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 86a0a8ac5772eb..c9edf4f77889f5 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); } From 599626ad9ad1fc9acad6fba7986507b421dc66ac Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Mon, 16 Dec 2019 16:08:13 -0800 Subject: [PATCH 20/25] Addressing more feedback --- src/libraries/System.Text.Json/ref/System.Text.Json.cs | 4 ++-- .../Text/Json/Serialization/Converters/JsonConverterEnum.cs | 2 +- .../Serialization/Converters/JsonKeyValuePairConverter.cs | 2 +- .../Json/Serialization/JsonSerializerOptions.Converters.cs | 6 +++--- .../Text/Json/Serialization/JsonStringEnumConverter.cs | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) 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 7fb71819c879c7..7ad05358e9f03c 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -740,7 +740,7 @@ public JsonConverterAttribute(System.Type converterType) { } 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 { @@ -770,6 +770,6 @@ public sealed partial class JsonStringEnumConverter : System.Text.Json.Serializa public JsonStringEnumConverter() { } 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/src/System/Text/Json/Serialization/Converters/JsonConverterEnum.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonConverterEnum.cs index e9454e47f10e7a..bbdd499ae62359 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,7 +21,7 @@ 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), 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 75130f3da4ce2e..75032665f60c25 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]; 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 952d13176a286f..161c1345c8af7b 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 @@ -163,10 +163,10 @@ private static List GetDefaultConverters() if (converter != null) { - Type? converterTypeToConvert = converter.TypeToConvert; + Type converterTypeToConvert = converter.TypeToConvert!; - if (converterTypeToConvert == null || (!converterTypeToConvert.IsAssignableFrom(typeToConvert) && - !typeToConvert.IsAssignableFrom(converterTypeToConvert))) + if (!converterTypeToConvert.IsAssignableFrom(typeToConvert) && + !typeToConvert.IsAssignableFrom(converterTypeToConvert)) { ThrowHelper.ThrowInvalidOperationException_SerializationConverterNotCompatible(converter.GetType(), typeToConvert); } 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 28faf547731864..056432c0259cd2 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 @@ -57,7 +57,7 @@ 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), From b5fc1ed96b22d922ca41276f475d60d3f8b86d97 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Mon, 16 Dec 2019 17:57:33 -0800 Subject: [PATCH 21/25] More feedback --- .../System.Text.Json/ref/System.Text.Json.cs | 8 +++---- .../ref/System.Text.Json.csproj | 2 +- .../JsonSerializer.Write.ByteArray.cs | 2 +- .../JsonSerializer.Write.Helpers.cs | 17 ++++++-------- .../JsonSerializer.Write.Stream.cs | 4 ++-- .../JsonSerializer.Write.String.cs | 2 +- .../JsonSerializer.Write.Utf8JsonWriter.cs | 2 +- .../Text/Json/ThrowHelper.Serialization.cs | 14 ++++++++++++ .../src/System/Text/Json/ThrowHelper.cs | 22 +++++++++++++++++++ 9 files changed, 53 insertions(+), 20 deletions(-) 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 7ad05358e9f03c..a9033f5402b467 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -437,11 +437,11 @@ public static partial class JsonSerializer 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 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(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; } 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 c21876c0c5bfea..dd20618e6696fe 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.csproj +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.csproj @@ -1,5 +1,5 @@  - + net461-Debug;net461-Release;$(NetCoreAppCurrent)-Debug;$(NetCoreAppCurrent)-Release;$(NetFrameworkCurrent)-Debug;$(NetFrameworkCurrent)-Release;netstandard2.0-Debug;netstandard2.0-Release enable 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 93efcb45016bef..0639fe0827979a 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 @@ -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.Helpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Helpers.cs index 4016265c271473..56d4be68b924f5 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 @@ -36,14 +36,11 @@ private static void GetRuntimePropertyInfo(object? value, JsonClassInfo jsonClas } } - private static void VerifyValueAndType(object? value, Type? type) + private static void VerifyValueAndType(object? value, Type type) { if (type == null) { - if (value != null) - { - throw new ArgumentNullException(nameof(type)); - } + throw new ArgumentNullException(nameof(type)); } else if (value != null) { @@ -54,7 +51,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 +69,7 @@ private static byte[] WriteCoreBytes(object? value, Type? type, JsonSerializerOp 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 +87,7 @@ private static string WriteCoreString(object? value, Type? type, JsonSerializerO 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 +102,7 @@ private static void WriteValueCore(Utf8JsonWriter writer, object? value, Type? t 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 +110,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); 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 00a08a2d050bc8..d7c1b24500cdb9 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 @@ -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? inputTyp 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 d545d3a29e545e..6464b1c6b7b2d4 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 @@ -32,7 +32,7 @@ public static string Serialize(TValue value, JsonSerializerOptions? opti /// 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 0280b53f51ee71..aa420f900d468a 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 @@ -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/ThrowHelper.Serialization.cs b/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs index 617db91e177934..4036de5a8ca7c4 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 @@ -12,12 +12,14 @@ namespace System.Text.Json { internal static partial class ThrowHelper { + [DoesNotReturn] [MethodImpl(MethodImplOptions.NoInlining)] public static void ThrowArgumentException_DeserializeWrongType(Type? type, object value) { throw new ArgumentException(SR.Format(SR.DeserializeWrongType, type, value.GetType())); } + [DoesNotReturn] [MethodImpl(MethodImplOptions.NoInlining)] public static NotSupportedException GetNotSupportedException_SerializationNotSupportedCollection(Type? propertyType, Type? parentType, MemberInfo? memberInfo) { @@ -29,6 +31,7 @@ public static NotSupportedException GetNotSupportedException_SerializationNotSup return new NotSupportedException(SR.Format(SR.SerializationNotSupportedCollectionType, propertyType)); } + [DoesNotReturn] public static void ThrowInvalidOperationException_SerializerCycleDetected(int maxDepth) { throw new JsonException(SR.Format(SR.SerializerCycleDetected, maxDepth)); @@ -51,12 +54,14 @@ public static void ThrowJsonException_DeserializeUnableToConvertValue(Type? prop throw new JsonException(message, path, null, null, innerException); } + [DoesNotReturn] [MethodImpl(MethodImplOptions.NoInlining)] public static void ThrowJsonException_DepthTooLarge(int currentDepth, JsonSerializerOptions options) { throw new JsonException(SR.Format(SR.DepthTooLarge, currentDepth, options.EffectiveMaxDepth)); } + [DoesNotReturn] [MethodImpl(MethodImplOptions.NoInlining)] public static void ThrowJsonException_SerializationConverterRead(JsonConverter? converter) { @@ -65,6 +70,7 @@ public static void ThrowJsonException_SerializationConverterRead(JsonConverter? throw ex; } + [DoesNotReturn] [MethodImpl(MethodImplOptions.NoInlining)] public static void ThrowJsonException_SerializationConverterWrite(JsonConverter? converter) { @@ -80,6 +86,7 @@ public static void ThrowJsonException() throw new JsonException(); } + [DoesNotReturn] [MethodImpl(MethodImplOptions.NoInlining)] public static void ThrowInvalidOperationException_SerializationConverterNotCompatible(Type? converterType, Type? type) { @@ -113,12 +120,14 @@ public static void ThrowInvalidOperationException_SerializationConverterOnAttrib throw new InvalidOperationException(SR.Format(SR.SerializationConverterOnAttributeNotCompatible, location, typeToConvert)); } + [DoesNotReturn] [MethodImpl(MethodImplOptions.NoInlining)] public static void ThrowInvalidOperationException_SerializerOptionsImmutable() { throw new InvalidOperationException(SR.SerializerOptionsImmutable); } + [DoesNotReturn] [MethodImpl(MethodImplOptions.NoInlining)] public static void ThrowInvalidOperationException_SerializerPropertyNameConflict(JsonClassInfo jsonClassInfo, JsonPropertyInfo jsonPropertyInfo) { @@ -139,6 +148,7 @@ public static void ThrowInvalidOperationException_SerializerDictionaryKeyNull(Ty throw new InvalidOperationException(SR.Format(SR.SerializerDictionaryKeyNull, policyType)); } + [DoesNotReturn] [MethodImpl(MethodImplOptions.NoInlining)] public static void ReThrowWithPath(in ReadStack readStack, JsonReaderException ex) { @@ -159,6 +169,7 @@ public static void ReThrowWithPath(in ReadStack readStack, JsonReaderException e throw new JsonException(message, path, ex.LineNumber, ex.BytePositionInLine, ex); } + [DoesNotReturn] [MethodImpl(MethodImplOptions.NoInlining)] public static void ReThrowWithPath(in ReadStack readStack, in Utf8JsonReader reader, Exception? ex) { @@ -200,6 +211,7 @@ public static void AddExceptionInformation(in ReadStack readStack, in Utf8JsonRe } } + [DoesNotReturn] [MethodImpl(MethodImplOptions.NoInlining)] public static void ReThrowWithPath(in WriteStack writeStack, Exception? ex) { @@ -241,12 +253,14 @@ public static void ThrowInvalidOperationException_SerializationDuplicateAttribut throw new InvalidOperationException(SR.Format(SR.SerializationDuplicateAttribute, attribute, location)); } + [DoesNotReturn] [MethodImpl(MethodImplOptions.NoInlining)] public static void ThrowInvalidOperationException_SerializationDuplicateTypeAttribute(Type? classType, Type? attribute) { throw new InvalidOperationException(SR.Format(SR.SerializationDuplicateTypeAttribute, classType, attribute)); } + [DoesNotReturn] [MethodImpl(MethodImplOptions.NoInlining)] public static void ThrowInvalidOperationException_SerializationDataExtensionPropertyInvalid(JsonClassInfo jsonClassInfo, JsonPropertyInfo jsonPropertyInfo) { 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 08ca23d0911e05..1641a63e3bcc91 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 @@ -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.Text.Json @@ -34,6 +35,7 @@ private static ArgumentException GetArgumentException(string? message) return new ArgumentException(message); } + [DoesNotReturn] public static void ThrowArgumentException(string? message) { throw GetArgumentException(message); @@ -44,26 +46,31 @@ public static InvalidOperationException GetInvalidOperationException_CallFlushFi return GetInvalidOperationException(SR.Format(SR.CallFlushToAvoidDataLoss, _buffered)); } + [DoesNotReturn] public static void ThrowArgumentException_PropertyNameTooLarge(int tokenLength) { throw GetArgumentException(SR.Format(SR.PropertyNameTooLarge, tokenLength)); } + [DoesNotReturn] public static void ThrowArgumentException_ValueTooLarge(int tokenLength) { throw GetArgumentException(SR.Format(SR.ValueTooLarge, tokenLength)); } + [DoesNotReturn] public static void ThrowArgumentException_ValueNotSupported() { throw GetArgumentException(SR.SpecialNumberValuesNotSupported); } + [DoesNotReturn] public static void ThrowInvalidOperationException_NeedLargerSpan() { throw GetInvalidOperationException(SR.FailedToGetLargerSpan); } + [DoesNotReturn] public static void ThrowArgumentException(ReadOnlySpan propertyName, ReadOnlySpan value) { if (propertyName.Length > JsonConstants.MaxUnescapedTokenSize) @@ -77,6 +84,7 @@ public static void ThrowArgumentException(ReadOnlySpan propertyName, ReadO } } + [DoesNotReturn] public static void ThrowArgumentException(ReadOnlySpan propertyName, ReadOnlySpan value) { if (propertyName.Length > JsonConstants.MaxUnescapedTokenSize) @@ -90,6 +98,7 @@ public static void ThrowArgumentException(ReadOnlySpan propertyName, ReadO } } + [DoesNotReturn] public static void ThrowArgumentException(ReadOnlySpan propertyName, ReadOnlySpan value) { if (propertyName.Length > JsonConstants.MaxCharacterTokenSize) @@ -103,6 +112,7 @@ public static void ThrowArgumentException(ReadOnlySpan propertyName, ReadO } } + [DoesNotReturn] public static void ThrowArgumentException(ReadOnlySpan propertyName, ReadOnlySpan value) { if (propertyName.Length > JsonConstants.MaxCharacterTokenSize) @@ -116,6 +126,7 @@ public static void ThrowArgumentException(ReadOnlySpan propertyName, ReadO } } + [DoesNotReturn] public static void ThrowInvalidOperationOrArgumentException(ReadOnlySpan propertyName, int currentDepth) { currentDepth &= JsonConstants.RemoveFlagsBitMask; @@ -130,6 +141,7 @@ public static void ThrowInvalidOperationOrArgumentException(ReadOnlySpan p } } + [DoesNotReturn] public static void ThrowInvalidOperationException(int currentDepth) { currentDepth &= JsonConstants.RemoveFlagsBitMask; @@ -137,6 +149,7 @@ public static void ThrowInvalidOperationException(int currentDepth) ThrowInvalidOperationException(SR.Format(SR.DepthTooLarge, currentDepth, JsonConstants.MaxWriterDepth)); } + [DoesNotReturn] public static void ThrowInvalidOperationException(string? message) { throw GetInvalidOperationException(message); @@ -150,6 +163,7 @@ private static InvalidOperationException GetInvalidOperationException(string? me return ex; } + [DoesNotReturn] public static void ThrowInvalidOperationException_DepthNonZeroOrEmptyJson(int currentDepth) { throw GetInvalidOperationException(currentDepth); @@ -169,6 +183,7 @@ private static InvalidOperationException GetInvalidOperationException(int curren } } + [DoesNotReturn] public static void ThrowInvalidOperationOrArgumentException(ReadOnlySpan propertyName, int currentDepth) { currentDepth &= JsonConstants.RemoveFlagsBitMask; @@ -260,6 +275,7 @@ internal static InvalidOperationException GetJsonElementWrongTypeException( SR.Format(SR.JsonElementHasWrongType, expectedTypeName, actualType)); } + [DoesNotReturn] public static void ThrowJsonReaderException(ref Utf8JsonReader json, ExceptionResource resource, byte nextByte = default, ReadOnlySpan bytes = default) { throw GetJsonReaderException(ref json, resource, nextByte, bytes); @@ -407,16 +423,19 @@ private static string GetResourceString(ref Utf8JsonReader json, ExceptionResour return message; } + [DoesNotReturn] public static void ThrowInvalidOperationException(ExceptionResource resource, int currentDepth, byte token, JsonTokenType tokenType) { throw GetInvalidOperationException(resource, currentDepth, token, tokenType); } + [DoesNotReturn] public static void ThrowArgumentException_InvalidCommentValue() { throw new ArgumentException(SR.CannotWriteCommentWithEmbeddedDelimiter); } + [DoesNotReturn] public static void ThrowArgumentException_InvalidUTF8(ReadOnlySpan value) { var builder = new StringBuilder(); @@ -444,16 +463,19 @@ public static void ThrowArgumentException_InvalidUTF8(ReadOnlySpan value) throw new ArgumentException(SR.Format(SR.CannotEncodeInvalidUTF8, builder)); } + [DoesNotReturn] public static void ThrowArgumentException_InvalidUTF16(int charAsInt) { throw new ArgumentException(SR.Format(SR.CannotEncodeInvalidUTF16, $"0x{charAsInt:X2}")); } + [DoesNotReturn] public static void ThrowInvalidOperationException_ReadInvalidUTF16(int charAsInt) { throw GetInvalidOperationException(SR.Format(SR.CannotReadInvalidUTF16, $"0x{charAsInt:X2}")); } + [DoesNotReturn] public static void ThrowInvalidOperationException_ReadInvalidUTF16() { throw GetInvalidOperationException(SR.CannotReadIncompleteUTF16); From dc33a6bff4533987debd3dafa3fc6410189e04f9 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Tue, 17 Dec 2019 11:26:44 -0800 Subject: [PATCH 22/25] Addressing review comment --- src/libraries/System.Text.Json/ref/System.Text.Json.cs | 6 +++--- .../System/Text/Json/Serialization/JsonConverterFactory.cs | 2 +- .../Text/Json/Serialization/JsonSerializer.Read.Stream.cs | 4 ++-- .../Serialization/JsonSerializer.Write.HandleDictionary.cs | 4 ++-- .../System.Text.Json/tests/Serialization/SpanTests.cs | 3 +-- 5 files changed, 9 insertions(+), 10 deletions(-) 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 a9033f5402b467..c87bb3255315ca 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -432,7 +432,7 @@ 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.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; } @@ -740,7 +740,7 @@ public JsonConverterAttribute(System.Type converterType) { } 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 { @@ -770,6 +770,6 @@ public sealed partial class JsonStringEnumConverter : System.Text.Json.Serializa public JsonStringEnumConverter() { } 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/src/System/Text/Json/Serialization/JsonConverterFactory.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterFactory.cs index cd4c2c7f40eb64..d96ec3574ef2c7 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 @@ -33,6 +33,6 @@ protected JsonConverterFactory() { } /// /// 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/JsonSerializer.Read.Stream.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Stream.cs index bd82cf0f11bfc6..7d0e0541e1966f 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 @@ -57,7 +57,7 @@ public static ValueTask DeserializeAsync( /// the is not compatible with the JSON, /// or when there is remaining data in the Stream. /// - public static ValueTask DeserializeAsync( + public static ValueTask DeserializeAsync( Stream utf8Json, Type returnType, JsonSerializerOptions? options = null, @@ -69,7 +69,7 @@ public static ValueTask DeserializeAsync( if (returnType == null) throw new ArgumentNullException(nameof(returnType)); - return ReadAsync(utf8Json, returnType, options, cancellationToken); + return ReadAsync(utf8Json, returnType, options, cancellationToken); } private static async ValueTask ReadAsync( 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 d318f5b4d8cba2..24bda6dadacdbb 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 @@ -170,11 +170,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/tests/Serialization/SpanTests.cs b/src/libraries/System.Text.Json/tests/Serialization/SpanTests.cs index 6640ea5e3e3d65..2d01d6e67506c0 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/SpanTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/SpanTests.cs @@ -84,8 +84,7 @@ public static void NullObjectOutput() byte[] encodedNull = Encoding.UTF8.GetBytes(@"null"); { - byte[] output = JsonSerializer.SerializeToUtf8Bytes(null, null); - Assert.Equal(encodedNull, output); + Assert.Throws(() => JsonSerializer.SerializeToUtf8Bytes(null, null)); } { From 7bd8f78566cf1854d2adb42273dea823f9e6b672 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Fri, 27 Dec 2019 15:44:07 -0800 Subject: [PATCH 23/25] Addressing feedback --- .../System.Text.Json/ref/System.Text.Json.cs | 3 ++ .../Serialization/JsonPropertyInfoCommon.cs | 4 +-- .../Serialization/JsonSerializer.Read.Span.cs | 2 ++ .../JsonSerializer.Read.String.cs | 2 ++ .../JsonSerializer.Read.Utf8JsonReader.cs | 2 ++ .../Text/Json/ThrowHelper.Serialization.cs | 18 ++++++------ .../src/System/Text/Json/ThrowHelper.cs | 28 +++++++++---------- .../tests/Serialization/Null.ReadTests.cs | 23 +++++++++++++++ 8 files changed, 56 insertions(+), 26 deletions(-) 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 c87bb3255315ca..7b127b1989eb9c 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -434,8 +434,11 @@ public static partial class JsonSerializer 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; } + [return: System.Diagnostics.CodeAnalysis.MaybeNull] public static TValue Deserialize(System.ReadOnlySpan utf8Json, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + [return: System.Diagnostics.CodeAnalysis.MaybeNull] public static TValue Deserialize(string json, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + [return: System.Diagnostics.CodeAnalysis.MaybeNull] 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) { } 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 0b4d73459c1c75..a67879610b5b26 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 @@ -19,8 +19,6 @@ internal abstract class JsonPropertyInfoCommon? Get { get; private set; } public Action? Set { get; private set; } - public Action? AddItemToEnumerable { get; private set; } - public JsonConverter? Converter { get; internal set; } public override void Initialize( @@ -139,7 +137,7 @@ public override bool TryCreateEnumerableAddMethod(object target, [NotNullWhen(tr public override void AddObjectToEnumerableWithReflection(object addMethodDelegate, object? value) { - Debug.Assert((_elementPropertyInfo ?? ElementClassInfo?.PolicyProperty) != null); + Debug.Assert((_elementPropertyInfo ?? ElementClassInfo!.PolicyProperty) != null); (_elementPropertyInfo ?? ElementClassInfo!.PolicyProperty!).AddObjectToParentEnumerable(addMethodDelegate, value); } 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 9fdbd0d6065abe..93a4f5194b1833 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 @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Text.Json { @@ -19,6 +20,7 @@ public static partial class JsonSerializer /// is not compatible with the JSON, /// or when there is remaining data in the Stream. /// + [return: MaybeNull] public static TValue Deserialize(ReadOnlySpan utf8Json, JsonSerializerOptions? options = null) { return (TValue)ParseCore(utf8Json, typeof(TValue), options)!; 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 4e623c017293b4..f5379c748131cc 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 @@ -4,6 +4,7 @@ using System.Buffers; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Text.Json { @@ -26,6 +27,7 @@ public static partial class JsonSerializer /// Using a is not as efficient as using the /// UTF-8 methods since the implementation natively uses UTF-8. /// + [return: MaybeNull] public static TValue Deserialize(string json, JsonSerializerOptions? options = null) { return (TValue)Deserialize(json, typeof(TValue), options)!; 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 056a87f244a753..fc84903a8c5728 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 @@ -4,6 +4,7 @@ using System.Buffers; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Text.Json { @@ -47,6 +48,7 @@ public static partial class JsonSerializer /// Hence, , , are used while reading. /// /// + [return: MaybeNull] public static TValue Deserialize(ref Utf8JsonReader reader, JsonSerializerOptions? options = null) { return (TValue)ReadValueCore(ref reader, typeof(TValue), options)!; 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 4036de5a8ca7c4..64b4c76a0ea004 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 @@ -14,14 +14,14 @@ internal static partial class ThrowHelper { [DoesNotReturn] [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())); } [DoesNotReturn] [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) { @@ -48,7 +48,7 @@ public static void ThrowJsonException_DeserializeUnableToConvertValue(Type? prop [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); @@ -88,7 +88,7 @@ public static void ThrowJsonException() [DoesNotReturn] [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)); } @@ -136,7 +136,7 @@ public static void ThrowInvalidOperationException_SerializerPropertyNameConflict [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)); } @@ -171,7 +171,7 @@ public static void ReThrowWithPath(in ReadStack readStack, JsonReaderException e [DoesNotReturn] [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); @@ -213,7 +213,7 @@ public static void AddExceptionInformation(in ReadStack readStack, in Utf8JsonRe [DoesNotReturn] [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); @@ -242,7 +242,7 @@ 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) @@ -255,7 +255,7 @@ public static void ThrowInvalidOperationException_SerializationDuplicateAttribut [DoesNotReturn] [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)); } 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 1641a63e3bcc91..9dffc288b1a551 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 @@ -13,30 +13,30 @@ 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); } [DoesNotReturn] - public static void ThrowArgumentException(string? message) + public static void ThrowArgumentException(string message) { throw GetArgumentException(message); } @@ -150,13 +150,13 @@ public static void ThrowInvalidOperationException(int currentDepth) } [DoesNotReturn] - 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; @@ -230,7 +230,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)); } @@ -251,7 +251,7 @@ internal static InvalidOperationException GetJsonElementWrongTypeException( [MethodImpl(MethodImplOptions.NoInlining)] internal static InvalidOperationException GetJsonElementWrongTypeException( - string? expectedTypeName, + string expectedTypeName, JsonTokenType actualType) { return GetJsonElementWrongTypeException(expectedTypeName, actualType.ToValueKind()); @@ -268,7 +268,7 @@ internal static InvalidOperationException GetJsonElementWrongTypeException( [MethodImpl(MethodImplOptions.NoInlining)] internal static InvalidOperationException GetJsonElementWrongTypeException( - string? expectedTypeName, + string expectedTypeName, JsonValueKind actualType) { return GetInvalidOperationException( @@ -303,7 +303,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); @@ -481,17 +481,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/tests/Serialization/Null.ReadTests.cs b/src/libraries/System.Text.Json/tests/Serialization/Null.ReadTests.cs index 83418a02132159..847c63be80e545 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/Null.ReadTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/Null.ReadTests.cs @@ -3,7 +3,11 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; +using Newtonsoft.Json; using Xunit; +using Xunit.Sdk; +using System.Threading.Tasks; +using System.IO; namespace System.Text.Json.Serialization.Tests { @@ -165,5 +169,24 @@ public static void NullReadTestChar() Assert.Equal('a', JsonSerializer.Deserialize("\"a\"")); Assert.Equal('Y', JsonSerializer.Deserialize("\"\u0059\"")); } + + [ActiveIssue(1037)] + [Fact] + public static void ParseNullStringToStructShouldThrowJsonException() + { + string nullString = "null"; + Utf8JsonReader reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(nullString)); + + JsonTestHelper.AssertThrows(reader, (reader) => JsonSerializer.Deserialize(ref reader)); + Assert.Throws(() => JsonSerializer.Deserialize(Encoding.UTF8.GetBytes(nullString))); + Assert.Throws(() => JsonSerializer.Deserialize(nullString)); + } + + [ActiveIssue(1037)] + [Fact] + public static async Task AsyncParseNullStringShouldThrowJsonException() + { + await Assert.ThrowsAsync(async () => await JsonSerializer.DeserializeAsync(new MemoryStream(Encoding.UTF8.GetBytes("null")))); + } } } From ba979417ed43a3e3b0ded74d9ea6b54e2d63d2a0 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Fri, 27 Dec 2019 18:45:36 -0800 Subject: [PATCH 24/25] Addressing feedback --- .../tests/BinaryFormatterTestData.cs | 2 +- .../System.Text.Json/ref/System.Text.Json.cs | 2 +- .../src/System/Text/Json/JsonException.cs | 6 ++--- .../Text/Json/Reader/JsonReaderException.cs | 2 +- .../DefaultImmutableDictionaryConverter.cs | 2 +- .../DefaultImmutableEnumerableConverter.cs | 2 +- .../ImmutableCollectionCreator.cs | 17 ++++++------ .../JsonSerializer.Read.HandleObject.cs | 2 +- .../JsonSerializer.Read.Stream.cs | 2 ++ .../Serialization/JsonSerializerOptions.cs | 4 +-- .../Text/Json/Serialization/MemberAccessor.cs | 26 ++++++------------- .../ReflectionEmitMemberAccessor.cs | 18 +++---------- .../Serialization/ReflectionMemberAccessor.cs | 22 +++++----------- .../Text/Json/ThrowHelper.Serialization.cs | 2 +- .../tests/Serialization/Null.ReadTests.cs | 7 +++-- 15 files changed, 46 insertions(+), 70 deletions(-) diff --git a/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs b/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs index 6ff4c7beec3c11..6f18266d87cf19 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs +++ b/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs @@ -492,7 +492,7 @@ public static IEnumerable SerializableObjects() var jsonException = new JsonException("message", path: "path", lineNumber: 1, bytePositionInLine: 2, innerException: exception); yield return new object[] { PopulateException(jsonException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFNTeXN0ZW0uVGV4dC5Kc29uLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Y2M3YjEzZmZjZDJkZGQ1MQUBAAAAHlN5c3RlbS5UZXh0Lkpzb24uSnNvbkV4Y2VwdGlvbhAAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzCkxpbmVOdW1iZXISQnl0ZVBvc2l0aW9uSW5MaW5lBFBhdGgNQWN0dWFsTWVzc2FnZQEBAwMBAQEAAQABBwMDAQEpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgxTeXN0ZW0uSW50NjQMU3lzdGVtLkludDY0AgAAAAYDAAAAHlN5c3RlbS5UZXh0Lkpzb24uSnNvbkV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAkGAAAABgcAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYIAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBgkAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgoAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKCAkBAAAAAAAAAAgJAgAAAAAAAAAGCwAAAARwYXRoCQQAAAAEBQAAAClTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbAMAAAAEaGVhZAd2ZXJzaW9uBWNvdW50AwAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlCAgJDQAAAAIAAAACAAAABAYAAAAQU3lzdGVtLkV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAIGDgAAABBTeXN0ZW0uRXhjZXB0aW9uCQQAAAAJEAAAAAkRAAAACQcAAAAJCAAAAAkJAAAAAAAAAAroAwAACQoAAAAKBA0AAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUDAAAAA2tleQV2YWx1ZQRuZXh0AgIDOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlBhYAAAAGc2VjcmV0CAEBCRcAAAABEAAAAAUAAAAJGAAAAAIAAAACAAAAAREAAAAGAAAACQ4AAAAGGgAAABdJbm5lciBleGNlcHRpb24gbWVzc2FnZQoKCgoKAAAAAAoAFROACgoBFwAAAA0AAAAICAEAAAAGGwAAAANvbmUKARgAAAANAAAACRYAAAAIAQEJHQAAAAEdAAAADQAAAAgIAQAAAAkbAAAACgs=", TargetFrameworkMoniker.netcoreapp30) } }; - var jsonExceptionNulls = new JsonException("message", string.Empty, null, null); + var jsonExceptionNulls = new JsonException("message", null, null, null); yield return new object[] { PopulateException(jsonExceptionNulls), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFNTeXN0ZW0uVGV4dC5Kc29uLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Y2M3YjEzZmZjZDJkZGQ1MQUBAAAAHlN5c3RlbS5UZXh0Lkpzb24uSnNvbkV4Y2VwdGlvbhAAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzCkxpbmVOdW1iZXISQnl0ZVBvc2l0aW9uSW5MaW5lBFBhdGgNQWN0dWFsTWVzc2FnZQEBAwMBAQEAAQABBwMDAQEpU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAm5TeXN0ZW0uTnVsbGFibGVgMVtbU3lzdGVtLkludDY0LCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXW5TeXN0ZW0uTnVsbGFibGVgMVtbU3lzdGVtLkludDY0LCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQIAAAAGAwAAAB5TeXN0ZW0uVGV4dC5Kc29uLkpzb25FeGNlcHRpb24GBAAAAAdtZXNzYWdlCQUAAAAKBgYAAAAZaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbQYHAAAAFFN0YWNrVHJhY2Ugc3RyaW5nLi4uBggAAAAbUmVtb3RlIFN0YWNrVHJhY2Ugc3RyaW5nLi4uAAAAAAroAwAABgkAAAAXRXhjZXB0aW9uX0NsYXNzX1NhbXBsZXMKCgoKCQQAAAAEBQAAAClTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbAMAAAAEaGVhZAd2ZXJzaW9uBWNvdW50AwAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlCAgJCwAAAAIAAAACAAAABAsAAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUDAAAAA2tleQV2YWx1ZQRuZXh0AgIDOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlBgwAAAAGc2VjcmV0CAEBCQ0AAAABDQAAAAsAAAAICAEAAAAGDgAAAANvbmUKCw==", TargetFrameworkMoniker.netcoreapp30) } }; // The JsonReaderException is internal. 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 7b127b1989eb9c..c43f9c9a5f55cf 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -221,7 +221,7 @@ public JsonException(string? message, string path, long? lineNumber, long? byteP 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 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 9117cbe7caaa1e..787f35f1b2e288 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 @@ -45,7 +45,7 @@ public JsonException(string? message, string path, long? lineNumber, long? byteP /// /// 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; @@ -89,7 +89,7 @@ protected JsonException(SerializationInfo info, StreamingContext context) : base { LineNumber = (long?)info.GetValue("LineNumber", typeof(long?)); BytePositionInLine = (long?)info.GetValue("BytePositionInLine", typeof(long?)); - Path = info.GetString("Path") ?? string.Empty; + Path = info.GetString("Path"); SetMessage(info.GetString("ActualMessage")); } @@ -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; } = string.Empty; + public string? Path { get; internal set; } /// /// Gets a message that describes the current exception. diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderException.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderException.cs index 32ba306190389c..2fa33d96b1db40 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderException.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderException.cs @@ -10,7 +10,7 @@ namespace System.Text.Json [Serializable] internal sealed class JsonReaderException : JsonException { - public JsonReaderException(string message, long lineNumber, long bytePositionInLine) : base(message, path: string.Empty, lineNumber, bytePositionInLine) + public JsonReaderException(string message, long lineNumber, long bytePositionInLine) : base(message, path: null, lineNumber, bytePositionInLine) { } 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 b43a636e21f768..e19a5f51d75473 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 @@ -31,7 +31,7 @@ public static void RegisterImmutableDictionary(Type immutableCollectionType, Typ Type constructingType = underlyingType.Assembly.GetType(constructingTypeName)!; // Create a delegate which will point to the CreateRange method. - ImmutableCollectionCreator? createRangeDelegate = options.MemberAccessorStrategy.ImmutableDictionaryCreateRange(constructingType, immutableCollectionType, elementType); + ImmutableCollectionCreator createRangeDelegate = options.MemberAccessorStrategy.ImmutableDictionaryCreateRange(constructingType, immutableCollectionType, elementType); // Cache the delegate options.TryAddCreateRangeDelegate(delegateKey, createRangeDelegate); 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 fbf50b081a16c7..b347bb59ea1bdf 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 @@ -95,7 +95,7 @@ public static void RegisterImmutableCollection(Type immutableCollectionType, Typ Type constructingType = underlyingType.Assembly.GetType(constructingTypeName)!; // Create a delegate which will point to the CreateRange method. - ImmutableCollectionCreator? createRangeDelegate = options.MemberAccessorStrategy.ImmutableCollectionCreateRange(constructingType, immutableCollectionType, elementType); + ImmutableCollectionCreator createRangeDelegate = options.MemberAccessorStrategy.ImmutableCollectionCreateRange(constructingType, immutableCollectionType, elementType); // Cache the delegate options.TryAddCreateRangeDelegate(delegateKey, createRangeDelegate); 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 559dde962aa1f3..8c093f0f54fed0 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 @@ -28,14 +28,14 @@ public override void RegisterCreatorDelegateFromMethod(MethodInfo creator) _creatorDelegate = (Func, TCollection>)creator.CreateDelegate(typeof(Func, TCollection>)); } - public override bool CreateImmutableEnumerable(IList items, out IEnumerable collection) + public override bool CreateImmutableEnumerable(IList items, [NotNullWhen(true)] out IEnumerable collection) { Debug.Assert(_creatorDelegate != null); collection = _creatorDelegate(CreateGenericTElementIEnumerable(items)); return true; } - public override bool CreateImmutableDictionary(IDictionary items, out IDictionary? collection) + public override bool CreateImmutableDictionary(IDictionary items, [NotNullWhen(true)] out IDictionary? collection) { // Shouldn't be calling this method for immutable dictionaries. collection = default; @@ -63,14 +63,14 @@ public override void RegisterCreatorDelegateFromMethod(MethodInfo creator) typeof(Func>, TCollection>)); } - public override bool CreateImmutableEnumerable(IList items, out IEnumerable? collection) + public override bool CreateImmutableEnumerable(IList items, [NotNullWhen(true)] out IEnumerable? collection) { // Shouldn't be calling this method for immutable non-dictionaries. collection = default; return false; } - public override bool CreateImmutableDictionary(IDictionary items, out IDictionary collection) + public override bool CreateImmutableDictionary(IDictionary items, [NotNullWhen(true)] out IDictionary collection) { Debug.Assert(_creatorDelegate != null); collection = (IDictionary)_creatorDelegate(CreateGenericTElementIDictionary(items)); @@ -79,11 +79,12 @@ 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 + foreach (DictionaryEntry? item in sourceDictionary) { - yield return new KeyValuePair((string)item.Key, (TElement)item.Value!); + if (item.HasValue) + { + yield return new KeyValuePair((string)item.Value.Key, (TElement)item.Value.Value!); + } } } } 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 2bb5d5d882aebd..9d351b873ac87d 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(); 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 7d0e0541e1966f..8c5ef840cb284a 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 @@ -4,6 +4,7 @@ using System.Buffers; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Threading; using System.Threading.Tasks; @@ -27,6 +28,7 @@ public static partial class JsonSerializer /// is not compatible with the JSON, /// or when there is remaining data in the Stream. /// + [return: MaybeNull] public static ValueTask DeserializeAsync( Stream utf8Json, JsonSerializerOptions? options = null, 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 c4568ed3c6e70f..edbde98fbe3921 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 @@ -20,7 +20,7 @@ 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 static readonly ConcurrentDictionary s_createRangeDelegates = new ConcurrentDictionary(); private MemberAccessor? _memberAccessorStrategy; private JsonNamingPolicy? _dictionayKeyPolicy; private JsonNamingPolicy? _jsonPropertyNamingPolicy; @@ -360,7 +360,7 @@ internal bool TryGetCreateRangeDelegate(string delegateKey, [NotNullWhen(true)] 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/MemberAccessor.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/MemberAccessor.cs index ca9eaa3e41e3f4..1f34061f1f0021 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 @@ -13,35 +13,25 @@ internal abstract class MemberAccessor 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); - - if (createRangeMethod == null) - { - return null; - } + MethodInfo createRangeMethod = FindImmutableCreateRangeMethod(constructingType); return createRangeMethod.MakeGenericMethod(elementType); } - protected MethodInfo? ImmutableDictionaryCreateRangeMethod(Type constructingType, Type elementType) + protected MethodInfo ImmutableDictionaryCreateRangeMethod(Type constructingType, Type elementType) { - MethodInfo? createRangeMethod = FindImmutableCreateRangeMethod(constructingType); - - if (createRangeMethod == null) - { - return null; - } + MethodInfo createRangeMethod = FindImmutableCreateRangeMethod(constructingType); return createRangeMethod.MakeGenericMethod(typeof(string), elementType); } - private MethodInfo? FindImmutableCreateRangeMethod(Type constructingType) + private MethodInfo FindImmutableCreateRangeMethod(Type constructingType) { MethodInfo[] constructingTypeMethods = constructingType.GetMethods(); @@ -57,7 +47,7 @@ internal abstract class MemberAccessor // a CreateRange method. `null` being returned here will cause a JsonException to be // thrown when the desired CreateRange delegate is about to be invoked. Debug.Fail("Could not create the appropriate CreateRange method."); - return null; + return null!; } public abstract Func CreatePropertyGetter(PropertyInfo propertyInfo); 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 c83b95f892653c..cd5135ea7959c6 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 @@ -62,14 +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); - - if (createRange == null) - { - return null; - } + MethodInfo createRange = ImmutableCollectionCreateRangeMethod(constructingType, elementType); Type creatorType = typeof(ImmutableEnumerableCreator<,>).MakeGenericType(elementType, collectionType); @@ -103,7 +98,7 @@ public override Action CreateAddDelegate(MethodInfo addMet } [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); @@ -113,12 +108,7 @@ public override Action CreateAddDelegate(MethodInfo addMet throw ThrowHelper.GetNotSupportedException_SerializationNotSupportedCollection(collectionType, parentType: null, memberInfo: null); } - MethodInfo? createRange = ImmutableDictionaryCreateRangeMethod(constructingType, elementType); - - if (createRange == null) - { - return null; - } + MethodInfo createRange = ImmutableDictionaryCreateRangeMethod(constructingType, elementType); Type creatorType = typeof(ImmutableDictionaryCreator<,>).MakeGenericType(elementType, collectionType); 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 7cdcf07575d729..0560db9adfe5ce 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 @@ -49,14 +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); - - if (createRange == null) - { - return null; - } + MethodInfo createRange = ImmutableCollectionCreateRangeMethod(constructingType, elementType); Type creatorType = typeof(ImmutableEnumerableCreator<,>).MakeGenericType(elementType, collectionType); ConstructorInfo constructor = creatorType.GetConstructor( @@ -72,7 +67,7 @@ public override Action CreateAddDelegate(MethodInfo addMet } [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,12 +77,7 @@ public override Action CreateAddDelegate(MethodInfo addMet throw ThrowHelper.GetNotSupportedException_SerializationNotSupportedCollection(collectionType, parentType: null, memberInfo: null); } - MethodInfo? createRange = ImmutableDictionaryCreateRangeMethod(constructingType, elementType); - - if (createRange == null) - { - return null; - } + MethodInfo createRange = ImmutableDictionaryCreateRangeMethod(constructingType, elementType); Type creatorType = typeof(ImmutableDictionaryCreator<,>).MakeGenericType(elementType, collectionType); ConstructorInfo constructor = creatorType.GetConstructor( @@ -129,8 +119,8 @@ public override Action CreateAddDelegate(MethodInfo addMet if (typeof(TClass).IsValueType) { - var factory = CreateDelegate>(s_createStructPropertySetterMethod.MakeGenericMethod(typeof(TClass), typeof(TProperty))); - var propertySetter = CreateDelegate>(setMethodInfo); + SetPropertyByRefFactory factory = CreateDelegate>(s_createStructPropertySetterMethod.MakeGenericMethod(typeof(TClass), typeof(TProperty))); + SetPropertyByRef propertySetter = CreateDelegate>(setMethodInfo); return factory(propertySetter); } 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 64b4c76a0ea004..4e9bca3fa3c9c5 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 @@ -39,7 +39,7 @@ public static void ThrowInvalidOperationException_SerializerCycleDetected(int ma [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; diff --git a/src/libraries/System.Text.Json/tests/Serialization/Null.ReadTests.cs b/src/libraries/System.Text.Json/tests/Serialization/Null.ReadTests.cs index 847c63be80e545..3068a3e6ac6417 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/Null.ReadTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/Null.ReadTests.cs @@ -184,9 +184,12 @@ public static void ParseNullStringToStructShouldThrowJsonException() [ActiveIssue(1037)] [Fact] - public static async Task AsyncParseNullStringShouldThrowJsonException() + public static async Task ParseNullStringShouldThrowJsonExceptionAsync() { - await Assert.ThrowsAsync(async () => await JsonSerializer.DeserializeAsync(new MemoryStream(Encoding.UTF8.GetBytes("null")))); + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes("null"))) + { + await Assert.ThrowsAsync(async () => await JsonSerializer.DeserializeAsync(stream)); + } } } } From e10f73225e69f1b42cce0fbaca425a6b804a6fc8 Mon Sep 17 00:00:00 2001 From: buyaa-n Date: Mon, 30 Dec 2019 18:09:01 -0800 Subject: [PATCH 25/25] Update src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Stream.cs Remove not needed attribute --- .../System/Text/Json/Serialization/JsonSerializer.Read.Stream.cs | 1 - 1 file changed, 1 deletion(-) 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 8c5ef840cb284a..67151485123c15 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 @@ -28,7 +28,6 @@ public static partial class JsonSerializer /// is not compatible with the JSON, /// or when there is remaining data in the Stream. /// - [return: MaybeNull] public static ValueTask DeserializeAsync( Stream utf8Json, JsonSerializerOptions? options = null,