Nullable: System.Text (#23708)
authorKrzysztof Wicher <mordotymoja@gmail.com>
Sat, 6 Apr 2019 03:32:16 +0000 (20:32 -0700)
committerStephen Toub <stoub@microsoft.com>
Sat, 6 Apr 2019 03:32:16 +0000 (23:32 -0400)
* Nullable: System.Text

* apply feedback

* simplify second enc.Clone() call

40 files changed:
src/System.Private.CoreLib/shared/System/Number.Formatting.cs
src/System.Private.CoreLib/shared/System/Text/ASCIIEncoding.cs
src/System.Private.CoreLib/shared/System/Text/ASCIIUtility.cs
src/System.Private.CoreLib/shared/System/Text/CodePageDataItem.cs
src/System.Private.CoreLib/shared/System/Text/Decoder.cs
src/System.Private.CoreLib/shared/System/Text/DecoderBestFitFallback.cs
src/System.Private.CoreLib/shared/System/Text/DecoderExceptionFallback.cs
src/System.Private.CoreLib/shared/System/Text/DecoderFallback.cs
src/System.Private.CoreLib/shared/System/Text/DecoderNLS.cs
src/System.Private.CoreLib/shared/System/Text/DecoderReplacementFallback.cs
src/System.Private.CoreLib/shared/System/Text/Encoder.cs
src/System.Private.CoreLib/shared/System/Text/EncoderBestFitFallback.cs
src/System.Private.CoreLib/shared/System/Text/EncoderExceptionFallback.cs
src/System.Private.CoreLib/shared/System/Text/EncoderFallback.cs
src/System.Private.CoreLib/shared/System/Text/EncoderNLS.cs
src/System.Private.CoreLib/shared/System/Text/EncoderReplacementFallback.cs
src/System.Private.CoreLib/shared/System/Text/Encoding.Internal.cs
src/System.Private.CoreLib/shared/System/Text/Encoding.cs
src/System.Private.CoreLib/shared/System/Text/EncodingData.cs
src/System.Private.CoreLib/shared/System/Text/EncodingInfo.cs
src/System.Private.CoreLib/shared/System/Text/EncodingNLS.cs
src/System.Private.CoreLib/shared/System/Text/EncodingProvider.cs
src/System.Private.CoreLib/shared/System/Text/EncodingTable.cs
src/System.Private.CoreLib/shared/System/Text/Latin1Encoding.cs
src/System.Private.CoreLib/shared/System/Text/Rune.cs
src/System.Private.CoreLib/shared/System/Text/SpanRuneEnumerator.cs
src/System.Private.CoreLib/shared/System/Text/StringBuilder.Debug.cs
src/System.Private.CoreLib/shared/System/Text/StringBuilder.cs
src/System.Private.CoreLib/shared/System/Text/StringBuilderCache.cs
src/System.Private.CoreLib/shared/System/Text/StringRuneEnumerator.cs
src/System.Private.CoreLib/shared/System/Text/UTF32Encoding.cs
src/System.Private.CoreLib/shared/System/Text/UTF7Encoding.cs
src/System.Private.CoreLib/shared/System/Text/UTF8Encoding.cs
src/System.Private.CoreLib/shared/System/Text/Unicode/Utf8.cs
src/System.Private.CoreLib/shared/System/Text/Unicode/Utf8Utility.cs
src/System.Private.CoreLib/shared/System/Text/UnicodeDebug.cs
src/System.Private.CoreLib/shared/System/Text/UnicodeEncoding.cs
src/System.Private.CoreLib/shared/System/Text/UnicodeUtility.cs
src/System.Private.CoreLib/shared/System/Text/Utf16Utility.cs
src/System.Private.CoreLib/shared/System/Text/ValueStringBuilder.cs

index 6f2fb50..378832e 100644 (file)
@@ -2218,6 +2218,7 @@ namespace System
 
             if (nMaxDigits > 0)
             {
+                Debug.Assert(sDecimal != null);
                 sb.Append(sDecimal);
                 if ((digPos < 0) && (nMaxDigits > 0))
                 {
index 8cf1f57..b254a09 100644 (file)
@@ -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.
 
+#nullable enable
 using System.Buffers;
 using System.Diagnostics;
 using System.Runtime.CompilerServices;
@@ -90,7 +91,7 @@ namespace System.Text
                 ThrowHelper.ThrowArgumentOutOfRangeException((index < 0) ? ExceptionArgument.index : ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
             }
 
-            if (chars.Length - index < count)
+            if (chars!.Length - index < count)
             {
                 ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.chars, ExceptionResource.ArgumentOutOfRange_IndexCountBuffer);
             }
@@ -117,7 +118,7 @@ namespace System.Text
 
             fixed (char* pChars = chars)
             {
-                return GetByteCountCommon(pChars, chars.Length);
+                return GetByteCountCommon(pChars, chars!.Length);
             }
         }
 
@@ -183,7 +184,7 @@ namespace System.Text
         }
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)] // called directly by GetByteCountCommon
-        private protected sealed override unsafe int GetByteCountFast(char* pChars, int charsLength, EncoderFallback fallback, out int charsConsumed)
+        private protected sealed override unsafe int GetByteCountFast(char* pChars, int charsLength, EncoderFallback? fallback, out int charsConsumed)
         {
             // First: Can we short-circuit the entire calculation?
             // If an EncoderReplacementFallback is in use, all non-ASCII chars
@@ -230,12 +231,12 @@ namespace System.Text
                     resource: ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
             }
 
-            if (chars.Length - charIndex < charCount)
+            if (chars!.Length - charIndex < charCount)
             {
                 ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.chars, ExceptionResource.ArgumentOutOfRange_IndexCount);
             }
 
-            if ((uint)byteIndex > bytes.Length)
+            if ((uint)byteIndex > bytes!.Length)
             {
                 ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.byteIndex, ExceptionResource.ArgumentOutOfRange_Index);
             }
@@ -280,12 +281,12 @@ namespace System.Text
                     resource: ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
             }
 
-            if (chars.Length - charIndex < charCount)
+            if (chars!.Length - charIndex < charCount)
             {
                 ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.chars, ExceptionResource.ArgumentOutOfRange_IndexCount);
             }
 
-            if ((uint)byteIndex > bytes.Length)
+            if ((uint)byteIndex > bytes!.Length)
             {
                 ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.byteIndex, ExceptionResource.ArgumentOutOfRange_Index);
             }
@@ -372,7 +373,7 @@ namespace System.Text
             return bytesWritten;
         }
 
-        private protected sealed override unsafe int GetBytesWithFallback(ReadOnlySpan<char> chars, int originalCharsLength, Span<byte> bytes, int originalBytesLength, EncoderNLS encoder)
+        private protected sealed override unsafe int GetBytesWithFallback(ReadOnlySpan<char> chars, int originalCharsLength, Span<byte> bytes, int originalBytesLength, EncoderNLS? encoder)
         {
             // We special-case EncoderReplacementFallback if it's telling us to write a single ASCII char,
             // since we believe this to be relatively common and we can handle it more efficiently than
@@ -447,7 +448,7 @@ namespace System.Text
                 ThrowHelper.ThrowArgumentOutOfRangeException((index < 0) ? ExceptionArgument.index : ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
             }
 
-            if (bytes.Length - index < count)
+            if (bytes!.Length - index < count)
             {
                 ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.bytes, ExceptionResource.ArgumentOutOfRange_IndexCountBuffer);
             }
@@ -520,7 +521,7 @@ namespace System.Text
         }
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)] // called directly by GetCharCountCommon
-        private protected sealed override unsafe int GetCharCountFast(byte* pBytes, int bytesLength, DecoderFallback fallback, out int bytesConsumed)
+        private protected sealed override unsafe int GetCharCountFast(byte* pBytes, int bytesLength, DecoderFallback? fallback, out int bytesConsumed)
         {
             // First: Can we short-circuit the entire calculation?
             // If a DecoderReplacementFallback is in use, all non-ASCII bytes are replaced with
@@ -564,12 +565,12 @@ namespace System.Text
                     resource: ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
             }
 
-            if (bytes.Length - byteIndex < byteCount)
+            if (bytes!.Length - byteIndex < byteCount)
             {
                 ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.bytes, ExceptionResource.ArgumentOutOfRange_IndexCountBuffer);
             }
 
-            if ((uint)charIndex > (uint)chars.Length)
+            if ((uint)charIndex > (uint)chars!.Length)
             {
                 ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.charIndex, ExceptionResource.ArgumentOutOfRange_Index);
             }
@@ -656,7 +657,7 @@ namespace System.Text
             return charsWritten;
         }
 
-        private protected sealed override unsafe int GetCharsWithFallback(ReadOnlySpan<byte> bytes, int originalBytesLength, Span<char> chars, int originalCharsLength, DecoderNLS decoder)
+        private protected sealed override unsafe int GetCharsWithFallback(ReadOnlySpan<byte> bytes, int originalBytesLength, Span<char> chars, int originalCharsLength, DecoderNLS? decoder)
         {
             // We special-case DecoderReplacementFallback if it's telling us to write a single BMP char,
             // since we believe this to be relatively common and we can handle it more efficiently than
@@ -732,7 +733,7 @@ namespace System.Text
                     resource: ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
             }
 
-            if (bytes.Length - byteIndex < byteCount)
+            if (bytes!.Length - byteIndex < byteCount)
             {
                 ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.bytes, ExceptionResource.ArgumentOutOfRange_IndexCountBuffer);
             }
index 755f925..07c94ae 100644 (file)
@@ -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.
 
+#nullable enable
 using System.Diagnostics;
 using System.Numerics;
 using System.Runtime.CompilerServices;
index e4b8d4d..cb796ff 100644 (file)
@@ -2,25 +2,26 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+#nullable enable
 namespace System.Text
 {
     internal class CodePageDataItem
     {
         public int CodePage { get; }
         public int UIFamilyCodePage { get; }
-        public string WebName { get; }
-        public string HeaderName { get; }
-        public string BodyName { get; }
-        public string DisplayName { get; }
+        public string? WebName { get; }
+        public string? HeaderName { get; }
+        public string? BodyName { get; }
+        public string? DisplayName { get; }
         public uint Flags { get; }
 
         internal CodePageDataItem(
             int codePage,
             int uiFamilyCodePage,
-            string webName,
-            string headerName,
-            string bodyName,
-            string displayName,
+            string? webName,
+            string? headerName,
+            string? bodyName,
+            string? displayName,
             uint flags)
         {
             CodePage = codePage;
index b4a7575..9197e4c 100644 (file)
@@ -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.
 
+#nullable enable
 using System.Text;
 using System;
 using System.Diagnostics;
@@ -22,16 +23,16 @@ namespace System.Text
     //
     public abstract class Decoder
     {
-        internal DecoderFallback _fallback = null;
+        internal DecoderFallback? _fallback = null;
 
-        internal DecoderFallbackBuffer _fallbackBuffer = null;
+        internal DecoderFallbackBuffer? _fallbackBuffer = null;
 
         protected Decoder()
         {
             // We don't call default reset because default reset probably isn't good if we aren't initialized.
         }
 
-        public DecoderFallback Fallback
+        public DecoderFallback? Fallback
         {
             get
             {
index d94554c..3387a09 100644 (file)
@@ -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.
 
+#nullable enable
 //
 // This is used internally to create best fit behavior as per the original windows best fit behavior.
 //
@@ -14,8 +15,8 @@ namespace System.Text
     internal sealed class InternalDecoderBestFitFallback : DecoderFallback
     {
         // Our variables
-        internal Encoding _encoding = null;
-        internal char[] _arrayBestFit = null;
+        internal Encoding _encoding;
+        internal char[]? _arrayBestFit = null;
         internal char _cReplacement = '?';
 
         internal InternalDecoderBestFitFallback(Encoding encoding)
@@ -38,13 +39,13 @@ namespace System.Text
             }
         }
 
-        public override bool Equals(object value)
+        public override bool Equals(object? value)
         {
             if (value is InternalDecoderBestFitFallback that)
             {
-                return (_encoding.CodePage == that._encoding.CodePage);
+                return _encoding.CodePage == that._encoding.CodePage;
             }
-            return (false);
+            return false;
         }
 
         public override int GetHashCode()
@@ -62,7 +63,7 @@ namespace System.Text
         private InternalDecoderBestFitFallback _oFallback;
 
         // Private object for locking instead of locking on a public type for SQL reliability work.
-        private static object s_InternalSyncObject;
+        private static object? s_InternalSyncObject;
         private static object InternalSyncObject
         {
             get
@@ -70,9 +71,9 @@ namespace System.Text
                 if (s_InternalSyncObject == null)
                 {
                     object o = new object();
-                    Interlocked.CompareExchange<object>(ref s_InternalSyncObject, o, null);
+                    Interlocked.CompareExchange<object?>(ref s_InternalSyncObject, o, null);
                 }
-                return s_InternalSyncObject;
+                return s_InternalSyncObject!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
             }
         }
 
@@ -172,6 +173,7 @@ namespace System.Text
         {
             // Need to figure out our best fit character, low is beginning of array, high is 1 AFTER end of array
             int lowBound = 0;
+            Debug.Assert(_oFallback._arrayBestFit != null);
             int highBound = _oFallback._arrayBestFit.Length;
             int index;
             char cCheck;
index 0525861..450ba32 100644 (file)
@@ -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.
 
+#nullable enable
 using System;
 using System.Globalization;
 using System.Runtime.Serialization;
@@ -29,7 +30,7 @@ namespace System.Text
             }
         }
 
-        public override bool Equals(object value)
+        public override bool Equals(object? value)
         {
             if (value is DecoderExceptionFallback that)
             {
@@ -75,6 +76,8 @@ namespace System.Text
 
         private void Throw(byte[] bytesUnknown, int index)
         {
+            bytesUnknown = bytesUnknown ?? Array.Empty<byte>();
+
             // Create a string representation of our bytes.            
             StringBuilder strBytes = new StringBuilder(bytesUnknown.Length * 3);
 
@@ -102,7 +105,7 @@ namespace System.Text
     [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
     public sealed class DecoderFallbackException : ArgumentException
     {
-        private byte[] _bytesUnknown = null;
+        private byte[]? _bytesUnknown = null;
         private int _index = 0;
 
         public DecoderFallbackException()
@@ -111,19 +114,19 @@ namespace System.Text
             HResult = HResults.COR_E_ARGUMENT;
         }
 
-        public DecoderFallbackException(string message)
+        public DecoderFallbackException(string? message)
             : base(message)
         {
             HResult = HResults.COR_E_ARGUMENT;
         }
 
-        public DecoderFallbackException(string message, Exception innerException)
+        public DecoderFallbackException(string? message, Exception? innerException)
             : base(message, innerException)
         {
             HResult = HResults.COR_E_ARGUMENT;
         }
 
-        public DecoderFallbackException(string message, byte[] bytesUnknown, int index)
+        public DecoderFallbackException(string? message, byte[]? bytesUnknown, int index)
             : base(message)
         {
             _bytesUnknown = bytesUnknown;
@@ -135,11 +138,11 @@ namespace System.Text
         {
         }
 
-        public byte[] BytesUnknown
+        public byte[]? BytesUnknown
         {
             get
             {
-                return (_bytesUnknown);
+                return _bytesUnknown;
             }
         }
 
index d5782d5..77730c2 100644 (file)
@@ -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.
 
+#nullable enable
 using System.Diagnostics;
 using System.Globalization;
 using System.Threading;
@@ -10,15 +11,15 @@ namespace System.Text
 {
     public abstract class DecoderFallback
     {
-        private static DecoderFallback s_replacementFallback; // Default fallback, uses no best fit & "?"
-        private static DecoderFallback s_exceptionFallback;
+        private static DecoderFallback? s_replacementFallback; // Default fallback, uses no best fit & "?"
+        private static DecoderFallback? s_exceptionFallback;
 
         public static DecoderFallback ReplacementFallback =>
-            s_replacementFallback ?? Interlocked.CompareExchange(ref s_replacementFallback, new DecoderReplacementFallback(), null) ?? s_replacementFallback;        
+            s_replacementFallback ?? Interlocked.CompareExchange(ref s_replacementFallback, new DecoderReplacementFallback(), null) ?? s_replacementFallback!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
 
 
         public static DecoderFallback ExceptionFallback =>
-            s_exceptionFallback ?? Interlocked.CompareExchange<DecoderFallback>(ref s_exceptionFallback, new DecoderExceptionFallback(), null) ?? s_exceptionFallback;
+            s_exceptionFallback ?? Interlocked.CompareExchange<DecoderFallback?>(ref s_exceptionFallback, new DecoderExceptionFallback(), null) ?? s_exceptionFallback!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
 
         // Fallback
         //
@@ -67,8 +68,8 @@ namespace System.Text
         internal unsafe byte* byteStart;
         internal unsafe char* charEnd;
 
-        internal Encoding _encoding;
-        internal DecoderNLS _decoder;
+        internal Encoding? _encoding;
+        internal DecoderNLS? _decoder;
         private int _originalByteCount;
 
         // Internal Reset
@@ -86,7 +87,7 @@ namespace System.Text
             this.charEnd = charEnd;
         }
 
-        internal static DecoderFallbackBuffer CreateAndInitialize(Encoding encoding, DecoderNLS decoder, int originalByteCount)
+        internal static DecoderFallbackBuffer CreateAndInitialize(Encoding encoding, DecoderNLS? decoder, int originalByteCount)
         {
             // The original byte count is only used for keeping track of what 'index' value needs
             // to be passed to the abstract Fallback method. The index value is calculated by subtracting
@@ -298,6 +299,8 @@ namespace System.Text
         // private helper methods
         internal void ThrowLastBytesRecursive(byte[] bytesUnknown)
         {
+            bytesUnknown = bytesUnknown ?? Array.Empty<byte>();
+
             // Create a string representation of our bytes.
             StringBuilder strBytes = new StringBuilder(bytesUnknown.Length * 3);
             int i;
index 9040a94..bca541a 100644 (file)
@@ -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.
 
+#nullable enable
 using System.Buffers;
 using System.Diagnostics;
 using System.Runtime.InteropServices;
@@ -36,13 +37,6 @@ namespace System.Text
             this.Reset();
         }
 
-        // This is used by our child deserializers
-        internal DecoderNLS()
-        {
-            _encoding = null;
-            this.Reset();
-        }
-
         public override void Reset()
         {
             ClearLeftoverData();
@@ -90,6 +84,7 @@ namespace System.Text
             _throwOnOverflow = true;
 
             // By default just call the encoding version, no flush by default
+            Debug.Assert(_encoding != null);
             return _encoding.GetCharCount(bytes, count, this);
         }
 
@@ -146,6 +141,7 @@ namespace System.Text
             _throwOnOverflow = true;
 
             // By default just call the encodings version
+            Debug.Assert(_encoding != null);
             return _encoding.GetChars(bytes, byteCount, chars, charCount, this);
         }
 
@@ -208,6 +204,7 @@ namespace System.Text
             _bytesUsed = 0;
 
             // Do conversion
+            Debug.Assert(_encoding != null);
             charsUsed = _encoding.GetChars(bytes, byteCount, chars, charCount, this);
             bytesUsed = _bytesUsed;
 
@@ -274,6 +271,7 @@ namespace System.Text
             combinedBuffer = combinedBuffer.Slice(0, ConcatInto(GetLeftoverData(), bytes, combinedBuffer));
             int charCount = 0;
 
+            Debug.Assert(_encoding != null);
             switch (_encoding.DecodeFirstRune(combinedBuffer, out Rune value, out int combinedBufferBytesConsumed))
             {
                 case OperationStatus.Done:
@@ -302,7 +300,7 @@ namespace System.Text
 
             if (FallbackBuffer.Fallback(combinedBuffer.Slice(0, combinedBufferBytesConsumed).ToArray(), index: 0))
             {
-                charCount = _fallbackBuffer.DrainRemainingDataForGetCharCount();
+                charCount = _fallbackBuffer!.DrainRemainingDataForGetCharCount();
                 Debug.Assert(charCount >= 0, "Fallback buffer shouldn't have returned a negative char count.");
             }
 
@@ -329,6 +327,7 @@ namespace System.Text
 
             bool persistNewCombinedBuffer = false;
 
+            Debug.Assert(_encoding != null);
             switch (_encoding.DecodeFirstRune(combinedBuffer, out Rune value, out int combinedBufferBytesConsumed))
             {
                 case OperationStatus.Done:
@@ -363,7 +362,7 @@ namespace System.Text
             // Couldn't decode the buffer. Fallback the buffer instead.
 
             if (FallbackBuffer.Fallback(combinedBuffer.Slice(0, combinedBufferBytesConsumed).ToArray(), index: 0)
-                && !_fallbackBuffer.TryDrainRemainingDataForGetChars(chars, out charsWritten))
+                && !_fallbackBuffer!.TryDrainRemainingDataForGetChars(chars, out charsWritten))
             {
                 goto DestinationTooSmall;
             }
@@ -391,7 +390,8 @@ namespace System.Text
             // opportunity for any code before us to make forward progress, so we must fail immediately.
 
             _encoding.ThrowCharsOverflow(this, nothingDecoded: true);
-            throw null; // will never reach this point
+            // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538
+            throw null!; // will never reach this point
         }
 
         /// <summary>
index 2af0d12..2bfb4b0 100644 (file)
@@ -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.
 
+#nullable enable
 using System.Diagnostics;
 
 namespace System.Text
@@ -82,13 +83,13 @@ namespace System.Text
             }
         }
 
-        public override bool Equals(object value)
+        public override bool Equals(object? value)
         {
             if (value is DecoderReplacementFallback that)
             {
-                return (_strDefault == that._strDefault);
+                return _strDefault == that._strDefault;
             }
-            return (false);
+            return false;
         }
 
         public override int GetHashCode()
@@ -109,6 +110,7 @@ namespace System.Text
         // Construction
         public DecoderReplacementFallbackBuffer(DecoderReplacementFallback fallback)
         {
+            // TODO-NULLABLE: NullReferenceException (fallback)
             _strDefault = fallback.DefaultString;
         }
 
index df7d512..77874ce 100644 (file)
@@ -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.
 
+#nullable enable
 using System.Text;
 using System;
 using System.Diagnostics;
@@ -22,16 +23,16 @@ namespace System.Text
     //
     public abstract class Encoder
     {
-        internal EncoderFallback _fallback = null;
+        internal EncoderFallback? _fallback = null;
 
-        internal EncoderFallbackBuffer _fallbackBuffer = null;
+        internal EncoderFallbackBuffer? _fallbackBuffer = null;
 
         protected Encoder()
         {
             // We don't call default reset because default reset probably isn't good if we aren't initialized.
         }
 
-        public EncoderFallback Fallback
+        public EncoderFallback? Fallback
         {
             get
             {
index c3d07c9..363dd5e 100644 (file)
@@ -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.
 
+#nullable enable
 //
 // This is used internally to create best fit behavior as per the original windows best fit behavior.
 //
@@ -15,8 +16,8 @@ namespace System.Text
     internal class InternalEncoderBestFitFallback : EncoderFallback
     {
         // Our variables
-        internal Encoding _encoding = null;
-        internal char[] _arrayBestFit = null;
+        internal Encoding _encoding;
+        internal char[]? _arrayBestFit = null;
 
         internal InternalEncoderBestFitFallback(Encoding encoding)
         {
@@ -38,13 +39,13 @@ namespace System.Text
             }
         }
 
-        public override bool Equals(object value)
+        public override bool Equals(object? value)
         {
             if (value is InternalEncoderBestFitFallback that)
             {
-                return (_encoding.CodePage == that._encoding.CodePage);
+                return _encoding.CodePage == that._encoding.CodePage;
             }
-            return (false);
+            return false;
         }
 
         public override int GetHashCode()
@@ -62,7 +63,7 @@ namespace System.Text
         private int _iSize;
 
         // Private object for locking instead of locking on a public type for SQL reliability work.
-        private static object s_InternalSyncObject;
+        private static object? s_InternalSyncObject;
         private static object InternalSyncObject
         {
             get
@@ -70,9 +71,9 @@ namespace System.Text
                 if (s_InternalSyncObject == null)
                 {
                     object o = new object();
-                    Interlocked.CompareExchange<object>(ref s_InternalSyncObject, o, null);
+                    Interlocked.CompareExchange<object?>(ref s_InternalSyncObject, o, null);
                 }
-                return s_InternalSyncObject;
+                return s_InternalSyncObject!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
             }
         }
 
@@ -190,6 +191,7 @@ namespace System.Text
         {
             // Need to figure out our best fit character, low is beginning of array, high is 1 AFTER end of array
             int lowBound = 0;
+            Debug.Assert(_oFallback._arrayBestFit != null);
             int highBound = _oFallback._arrayBestFit.Length;
             int index;
 
index 077d927..37df576 100644 (file)
@@ -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.
 
+#nullable enable
 using System;
 using System.Runtime.Serialization;
 
@@ -28,13 +29,13 @@ namespace System.Text
             }
         }
 
-        public override bool Equals(object value)
+        public override bool Equals(object? value)
         {
             if (value is EncoderExceptionFallback that)
             {
-                return (true);
+                return true;
             }
-            return (false);
+            return false;
         }
 
         public override int GetHashCode()
@@ -110,20 +111,20 @@ namespace System.Text
             HResult = HResults.COR_E_ARGUMENT;
         }
 
-        public EncoderFallbackException(string message)
+        public EncoderFallbackException(string? message)
             : base(message)
         {
             HResult = HResults.COR_E_ARGUMENT;
         }
 
-        public EncoderFallbackException(string message, Exception innerException)
+        public EncoderFallbackException(string? message, Exception? innerException)
             : base(message, innerException)
         {
             HResult = HResults.COR_E_ARGUMENT;
         }
 
         internal EncoderFallbackException(
-            string message, char charUnknown, int index) : base(message)
+            string? message, char charUnknown, int index) : base(message)
         {
             _charUnknown = charUnknown;
             _index = index;
@@ -157,7 +158,7 @@ namespace System.Text
         {
             get
             {
-                return (_charUnknown);
+                return _charUnknown;
             }
         }
 
@@ -165,7 +166,7 @@ namespace System.Text
         {
             get
             {
-                return (_charUnknownHigh);
+                return _charUnknownHigh;
             }
         }
 
@@ -173,7 +174,7 @@ namespace System.Text
         {
             get
             {
-                return (_charUnknownLow);
+                return _charUnknownLow;
             }
         }
 
@@ -188,7 +189,7 @@ namespace System.Text
         // Return true if the unknown character is a surrogate pair.
         public bool IsUnknownSurrogate()
         {
-            return (_charUnknownHigh != '\0');
+            return _charUnknownHigh != '\0';
         }
     }
 }
index ff895d6..b1c1127 100644 (file)
@@ -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.
 
+#nullable enable
 using System.Buffers;
 using System.Diagnostics;
 using System.Threading;
@@ -10,8 +11,8 @@ namespace System.Text
 {
     public abstract class EncoderFallback
     {
-        private static EncoderFallback s_replacementFallback; // Default fallback, uses no best fit & "?"
-        private static EncoderFallback s_exceptionFallback;
+        private static EncoderFallback? s_replacementFallback; // Default fallback, uses no best fit & "?"
+        private static EncoderFallback? s_exceptionFallback;
 
         // Get each of our generic fallbacks.
 
@@ -20,9 +21,9 @@ namespace System.Text
             get
             {
                 if (s_replacementFallback == null)
-                    Interlocked.CompareExchange<EncoderFallback>(ref s_replacementFallback, new EncoderReplacementFallback(), null);
+                    Interlocked.CompareExchange<EncoderFallback?>(ref s_replacementFallback, new EncoderReplacementFallback(), null);
 
-                return s_replacementFallback;
+                return s_replacementFallback!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
             }
         }
 
@@ -32,9 +33,9 @@ namespace System.Text
             get
             {
                 if (s_exceptionFallback == null)
-                    Interlocked.CompareExchange<EncoderFallback>(ref s_exceptionFallback, new EncoderExceptionFallback(), null);
+                    Interlocked.CompareExchange<EncoderFallback?>(ref s_exceptionFallback, new EncoderExceptionFallback(), null);
 
-                return s_exceptionFallback;
+                return s_exceptionFallback!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
             }
         }
 
@@ -87,13 +88,13 @@ namespace System.Text
         // These help us with our performance and messages internally
         internal unsafe char* charStart;
         internal unsafe char* charEnd;
-        internal EncoderNLS encoder; // TODO: MAKE ME PRIVATE
+        internal EncoderNLS? encoder; // TODO: MAKE ME PRIVATE
         internal bool setEncoder;
         internal bool bUsedEncoder;
         internal bool bFallingBack = false;
         internal int iRecursionCount = 0;
         private const int iMaxRecursion = 250;
-        private Encoding encoding;
+        private Encoding? encoding;
         private int originalCharCount;
 
         // Internal Reset
@@ -108,7 +109,7 @@ namespace System.Text
 
         // Set the above values
         // This can't be part of the constructor because EncoderFallbacks would have to know how to implement these.
-        internal unsafe void InternalInitialize(char* charStart, char* charEnd, EncoderNLS encoder, bool setEncoder)
+        internal unsafe void InternalInitialize(char* charStart, char* charEnd, EncoderNLS? encoder, bool setEncoder)
         {
             this.charStart = charStart;
             this.charEnd = charEnd;
@@ -119,7 +120,7 @@ namespace System.Text
             this.iRecursionCount = 0;
         }
 
-        internal static EncoderFallbackBuffer CreateAndInitialize(Encoding encoding, EncoderNLS encoder, int originalCharCount)
+        internal static EncoderFallbackBuffer CreateAndInitialize(Encoding encoding, EncoderNLS? encoder, int originalCharCount)
         {
             // The original char count is only used for keeping track of what 'index' value needs
             // to be passed to the abstract Fallback method. The index value is calculated by subtracting
@@ -218,6 +219,7 @@ namespace System.Text
         {
             int originalBytesLength = bytes.Length;
 
+            Debug.Assert(encoding != null);
             Rune thisRune;
             while ((thisRune = GetNextRune()).Value != 0)
             {
@@ -267,6 +269,7 @@ namespace System.Text
         {
             int totalByteCount = 0;
 
+            Debug.Assert(encoding != null);
             Rune thisRune;
             while ((thisRune = GetNextRune()).Value != 0)
             {
index 2901fc3..41a2494 100644 (file)
@@ -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.
 
+#nullable enable
 using System.Buffers;
 using System.Diagnostics;
 using System.Runtime.InteropServices;
@@ -36,12 +37,6 @@ namespace System.Text
             this.Reset();
         }
 
-        internal EncoderNLS()
-        {
-            _encoding = null;
-            this.Reset();
-        }
-
         public override void Reset()
         {
             _charLeftOver = (char)0;
@@ -86,6 +81,7 @@ namespace System.Text
 
             _mustFlush = flush;
             _throwOnOverflow = true;
+            Debug.Assert(_encoding != null);
             return _encoding.GetByteCount(chars, count, this);
         }
 
@@ -133,6 +129,7 @@ namespace System.Text
 
             _mustFlush = flush;
             _throwOnOverflow = true;
+            Debug.Assert(_encoding != null);
             return _encoding.GetBytes(chars, charCount, bytes, byteCount, this);
         }
 
@@ -194,6 +191,7 @@ namespace System.Text
             _charsUsed = 0;
 
             // Do conversion
+            Debug.Assert(_encoding != null);
             bytesUsed = _encoding.GetBytes(chars, charCount, bytes, byteCount, this);
             charsUsed = _charsUsed;
 
@@ -212,6 +210,7 @@ namespace System.Text
         {
             get
             {
+                Debug.Assert(_encoding != null);
                 return _encoding;
             }
         }
@@ -296,6 +295,7 @@ namespace System.Text
                 {
                     charsConsumed = 1; // consumed the leftover high surrogate + the first char in the input buffer
 
+                    Debug.Assert(_encoding != null);
                     if (_encoding.TryGetByteCount(rune, out int byteCount))
                     {
                         Debug.Assert(byteCount >= 0, "Encoding shouldn't have returned a negative byte count.");
@@ -312,7 +312,7 @@ namespace System.Text
                 }
 
                 // Now tally the number of bytes that would've been emitted as part of fallback.
-
+                Debug.Assert(_fallbackBuffer != null);
                 return _fallbackBuffer.DrainRemainingDataForGetByteCount();
             }
         }
@@ -355,6 +355,7 @@ namespace System.Text
                 if (Rune.TryCreate(_charLeftOver, secondChar, out Rune rune))
                 {
                     charsConsumed = 1; // at the very least, we consumed 1 char from the input
+                    Debug.Assert(_encoding != null);
                     switch (_encoding.EncodeRune(rune, bytes, out bytesWritten))
                     {
                         case OperationStatus.Done:
index cfce410..10e844b 100644 (file)
@@ -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.
 
+#nullable enable
 using System;
 using System.Runtime;
 using System.Diagnostics;
@@ -85,13 +86,13 @@ namespace System.Text
             }
         }
 
-        public override bool Equals(object value)
+        public override bool Equals(object? value)
         {
             if (value is EncoderReplacementFallback that)
             {
-                return (_strDefault == that._strDefault);
+                return _strDefault == that._strDefault;
             }
-            return (false);
+            return false;
         }
 
         public override int GetHashCode()
@@ -100,8 +101,6 @@ namespace System.Text
         }
     }
 
-
-
     public sealed class EncoderReplacementFallbackBuffer : EncoderFallbackBuffer
     {
         // Store our default string
@@ -112,6 +111,7 @@ namespace System.Text
         // Construction
         public EncoderReplacementFallbackBuffer(EncoderReplacementFallback fallback)
         {
+            // TODO-NULLABLE: NullReferenceException
             // 2X in case we're a surrogate pair
             _strDefault = fallback.DefaultString + fallback.DefaultString;
         }
index 0e32167..7255213 100644 (file)
@@ -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.
 
+#nullable enable
 using System.Buffers;
 using System.Diagnostics;
 using System.Runtime.CompilerServices;
@@ -120,7 +121,7 @@ namespace System.Text
         /// <summary>
         /// Entry point from <see cref="EncoderNLS.GetByteCount"/>.
         /// </summary>
-        internal virtual unsafe int GetByteCount(char* pChars, int charCount, EncoderNLS encoder)
+        internal virtual unsafe int GetByteCount(char* pChars, int charCount, EncoderNLS? encoder)
         {
             Debug.Assert(encoder != null, "This code path should only be called from EncoderNLS.");
             Debug.Assert(charCount >= 0, "Caller should've checked this condition.");
@@ -173,7 +174,7 @@ namespace System.Text
         /// The implementation should not attempt to perform any sort of fallback behavior.
         /// If custom fallback behavior is necessary, override <see cref="GetByteCountWithFallback"/>.
         /// </remarks>
-        private protected virtual unsafe int GetByteCountFast(char* pChars, int charsLength, EncoderFallback fallback, out int charsConsumed)
+        private protected virtual unsafe int GetByteCountFast(char* pChars, int charsLength, EncoderFallback? fallback, out int charsConsumed)
         {
             // Any production-quality type would override this method and provide a real
             // implementation, so we won't provide a base implementation. However, a
@@ -309,7 +310,7 @@ namespace System.Text
         /// If the resulting byte count is greater than <see cref="int.MaxValue"/>.
         /// (Implementation should call <see cref="ThrowConversionOverflow"/>.)
         /// </exception>
-        private protected virtual unsafe int GetByteCountWithFallback(ReadOnlySpan<char> chars, int originalCharsLength, EncoderNLS encoder)
+        private protected virtual unsafe int GetByteCountWithFallback(ReadOnlySpan<char> chars, int originalCharsLength, EncoderNLS? encoder)
         {
             Debug.Assert(!chars.IsEmpty, "Caller shouldn't invoke this method with an empty input buffer.");
             Debug.Assert(originalCharsLength >= 0, "Caller provided invalid parameter.");
@@ -397,7 +398,7 @@ namespace System.Text
         /// <summary>
         /// Entry point from <see cref="EncoderNLS.GetBytes"/> and <see cref="EncoderNLS.Convert"/>.
         /// </summary>
-        internal virtual unsafe int GetBytes(char* pChars, int charCount, byte* pBytes, int byteCount, EncoderNLS encoder)
+        internal virtual unsafe int GetBytes(char* pChars, int charCount, byte* pBytes, int byteCount, EncoderNLS? encoder)
         {
             Debug.Assert(encoder != null, "This code path should only be called from EncoderNLS.");
             Debug.Assert(charCount >= 0, "Caller should've checked this condition.");
@@ -584,7 +585,7 @@ namespace System.Text
         /// implementation, deferring to the base implementation if needed. This method calls <see cref="ThrowBytesOverflow"/>
         /// if necessary.
         /// </remarks>
-        private protected virtual unsafe int GetBytesWithFallback(ReadOnlySpan<char> chars, int originalCharsLength, Span<byte> bytes, int originalBytesLength, EncoderNLS encoder)
+        private protected virtual unsafe int GetBytesWithFallback(ReadOnlySpan<char> chars, int originalCharsLength, Span<byte> bytes, int originalBytesLength, EncoderNLS? encoder)
         {
             Debug.Assert(!chars.IsEmpty, "Caller shouldn't invoke this method with an empty input buffer.");
             Debug.Assert(originalCharsLength >= 0, "Caller provided invalid parameter.");
@@ -705,7 +706,7 @@ namespace System.Text
         /// <summary>
         /// Entry point from <see cref="DecoderNLS.GetCharCount"/>.
         /// </summary>
-        internal virtual unsafe int GetCharCount(byte* pBytes, int byteCount, DecoderNLS decoder)
+        internal virtual unsafe int GetCharCount(byte* pBytes, int byteCount, DecoderNLS? decoder)
         {
             Debug.Assert(decoder != null, "This code path should only be called from DecoderNLS.");
             Debug.Assert(byteCount >= 0, "Caller should've checked this condition.");
@@ -760,7 +761,7 @@ namespace System.Text
         /// The implementation should not attempt to perform any sort of fallback behavior.
         /// If custom fallback behavior is necessary, override <see cref="GetCharCountWithFallback"/>.
         /// </remarks>
-        private protected virtual unsafe int GetCharCountFast(byte* pBytes, int bytesLength, DecoderFallback fallback, out int bytesConsumed)
+        private protected virtual unsafe int GetCharCountFast(byte* pBytes, int bytesLength, DecoderFallback? fallback, out int bytesConsumed)
         {
             // Any production-quality type would override this method and provide a real
             // implementation, so we won't provide a base implementation. However, a
@@ -895,7 +896,7 @@ namespace System.Text
         /// If the resulting char count is greater than <see cref="int.MaxValue"/>.
         /// (Implementation should call <see cref="ThrowConversionOverflow"/>.)
         /// </exception>
-        private unsafe int GetCharCountWithFallback(ReadOnlySpan<byte> bytes, int originalBytesLength, DecoderNLS decoder)
+        private unsafe int GetCharCountWithFallback(ReadOnlySpan<byte> bytes, int originalBytesLength, DecoderNLS? decoder)
         {
             Debug.Assert(!bytes.IsEmpty, "Caller shouldn't invoke this method with an empty input buffer.");
             Debug.Assert(originalBytesLength >= 0, "Caller provided invalid parameter.");
@@ -979,7 +980,7 @@ namespace System.Text
         /// <summary>
         /// Entry point from <see cref="DecoderNLS.GetChars"/> and <see cref="DecoderNLS.Convert"/>.
         /// </summary>
-        internal virtual unsafe int GetChars(byte* pBytes, int byteCount, char* pChars, int charCount, DecoderNLS decoder)
+        internal virtual unsafe int GetChars(byte* pBytes, int byteCount, char* pChars, int charCount, DecoderNLS? decoder)
         {
             Debug.Assert(decoder != null, "This code path should only be called from DecoderNLS.");
             Debug.Assert(byteCount >= 0, "Caller should've checked this condition.");
@@ -1166,7 +1167,7 @@ namespace System.Text
         /// implementation, deferring to the base implementation if needed. This method calls <see cref="ThrowCharsOverflow"/>
         /// if necessary.
         /// </remarks>
-        private protected virtual unsafe int GetCharsWithFallback(ReadOnlySpan<byte> bytes, int originalBytesLength, Span<char> chars, int originalCharsLength, DecoderNLS decoder)
+        private protected virtual unsafe int GetCharsWithFallback(ReadOnlySpan<byte> bytes, int originalBytesLength, Span<char> chars, int originalCharsLength, DecoderNLS? decoder)
         {
             Debug.Assert(!bytes.IsEmpty, "Caller shouldn't invoke this method with an empty input buffer.");
             Debug.Assert(originalBytesLength >= 0, "Caller provided invalid parameter.");
index 8947b7f..fee129b 100644 (file)
@@ -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.
 
+#nullable enable
 using System.Diagnostics;
 using System.Runtime.InteropServices;
 using System.Runtime.Serialization;
@@ -153,15 +154,15 @@ namespace System.Text
 
         internal int _codePage = 0;
 
-        internal CodePageDataItem _dataItem = null;
+        internal CodePageDataItem? _dataItem = null;
 
         // Because of encoders we may be read only
         [OptionalField(VersionAdded = 2)]
         private bool _isReadOnly = true;
 
         // Encoding (encoder) fallback
-        internal EncoderFallback encoderFallback = null;
-        internal DecoderFallback decoderFallback = null;
+        internal EncoderFallback encoderFallback = null!;
+        internal DecoderFallback decoderFallback = null!;
 
         protected Encoding() : this(0)
         {
@@ -186,7 +187,7 @@ namespace System.Text
         // This constructor is needed to allow any sub-classing implementation to provide encoder/decoder fallback objects 
         // because the encoding object is always created as read-only object and don't allow setting encoder/decoder fallback 
         // after the creation is done. 
-        protected Encoding(int codePage, EncoderFallback encoderFallback, DecoderFallback decoderFallback)
+        protected Encoding(int codePage, EncoderFallback? encoderFallback, DecoderFallback? decoderFallback)
         {
             // Validate code page
             if (codePage < 0)
@@ -254,7 +255,7 @@ namespace System.Text
 
         public static Encoding GetEncoding(int codepage)
         {
-            Encoding result = EncodingProvider.GetEncodingFromProvider(codepage);
+            Encoding? result = EncodingProvider.GetEncodingFromProvider(codepage);
             if (result != null)
                 return result;
 
@@ -290,7 +291,7 @@ namespace System.Text
         public static Encoding GetEncoding(int codepage,
             EncoderFallback encoderFallback, DecoderFallback decoderFallback)
         {
-            Encoding baseEncoding = EncodingProvider.GetEncodingFromProvider(codepage, encoderFallback, decoderFallback);
+            Encoding? baseEncoding = EncodingProvider.GetEncodingFromProvider(codepage, encoderFallback, decoderFallback);
 
             if (baseEncoding != null)
                 return baseEncoding;
@@ -310,7 +311,7 @@ namespace System.Text
         //
         public static Encoding GetEncoding(string name)
         {
-            Encoding baseEncoding = EncodingProvider.GetEncodingFromProvider(name);
+            Encoding? baseEncoding = EncodingProvider.GetEncodingFromProvider(name);
             if (baseEncoding != null)
                 return baseEncoding;
 
@@ -328,7 +329,7 @@ namespace System.Text
         public static Encoding GetEncoding(string name,
             EncoderFallback encoderFallback, DecoderFallback decoderFallback)
         {
-            Encoding baseEncoding = EncodingProvider.GetEncodingFromProvider(name, encoderFallback, decoderFallback);
+            Encoding? baseEncoding = EncodingProvider.GetEncodingFromProvider(name, encoderFallback, decoderFallback);
             if (baseEncoding != null)
                 return baseEncoding;
 
@@ -338,7 +339,7 @@ namespace System.Text
             // Otherwise, the code below will throw exception when trying to call
             // EncodingTable.GetCodePageFromName().
             //
-            return (GetEncoding(EncodingTable.GetCodePageFromName(name), encoderFallback, decoderFallback));
+            return GetEncoding(EncodingTable.GetCodePageFromName(name), encoderFallback, decoderFallback);
         }
 
         // Return a list of all EncodingInfo objects describing all of our encodings
@@ -369,7 +370,7 @@ namespace System.Text
         // Returns the name for this encoding that can be used with mail agent body tags.
         // If the encoding may not be used, the string is empty.
 
-        public virtual string BodyName
+        public virtual string? BodyName
         {
             get
             {
@@ -377,12 +378,12 @@ namespace System.Text
                 {
                     GetDataItem();
                 }
-                return (_dataItem.BodyName);
+                return _dataItem!.BodyName;
             }
         }
 
         // Returns the human-readable description of the encoding ( e.g. Hebrew (DOS)).
-        public virtual string EncodingName
+        public virtual string? EncodingName
         {
             get
             {
@@ -391,14 +392,14 @@ namespace System.Text
                     GetDataItem();
                 }
                 
-                return _dataItem.DisplayName;
+                return _dataItem!.DisplayName;
             }
         }
 
         // Returns the name for this encoding that can be used with mail agent header
         // tags.  If the encoding may not be used, the string is empty.
 
-        public virtual string HeaderName
+        public virtual string? HeaderName
         {
             get
             {
@@ -406,12 +407,12 @@ namespace System.Text
                 {
                     GetDataItem();
                 }
-                return (_dataItem.HeaderName);
+                return _dataItem!.HeaderName;
             }
         }
 
         // Returns the IANA preferred name for this encoding.
-        public virtual string WebName
+        public virtual string? WebName
         {
             get
             {
@@ -419,7 +420,7 @@ namespace System.Text
                 {
                     GetDataItem();
                 }
-                return (_dataItem.WebName);
+                return _dataItem!.WebName;
             }
         }
 
@@ -433,7 +434,7 @@ namespace System.Text
                 {
                     GetDataItem();
                 }
-                return (_dataItem.UIFamilyCodePage);
+                return _dataItem!.UIFamilyCodePage;
             }
         }
 
@@ -448,7 +449,7 @@ namespace System.Text
                 {
                     GetDataItem();
                 }
-                return ((_dataItem.Flags & MIMECONTF_BROWSER) != 0);
+                return (_dataItem!.Flags & MIMECONTF_BROWSER) != 0;
             }
         }
 
@@ -462,7 +463,7 @@ namespace System.Text
                 {
                     GetDataItem();
                 }
-                return ((_dataItem.Flags & MIMECONTF_SAVABLE_BROWSER) != 0);
+                return (_dataItem!.Flags & MIMECONTF_SAVABLE_BROWSER) != 0;
             }
         }
 
@@ -476,7 +477,7 @@ namespace System.Text
                 {
                     GetDataItem();
                 }
-                return ((_dataItem.Flags & MIMECONTF_MAILNEWS) != 0);
+                return (_dataItem!.Flags & MIMECONTF_MAILNEWS) != 0;
             }
         }
 
@@ -492,7 +493,7 @@ namespace System.Text
                 {
                     GetDataItem();
                 }
-                return ((_dataItem.Flags & MIMECONTF_SAVABLE_MAILNEWS) != 0);
+                return (_dataItem!.Flags & MIMECONTF_SAVABLE_MAILNEWS) != 0;
             }
         }
 
@@ -1154,7 +1155,7 @@ namespace System.Text
 
         private static Encoding BigEndianUTF32 => UTF32Encoding.s_bigEndianDefault;
 
-        public override bool Equals(object value)
+        public override bool Equals(object? value)
         {
             if (value is Encoding that)
                 return (_codePage == that._codePage) &&
@@ -1189,7 +1190,7 @@ namespace System.Text
                 SR.Format(SR.Argument_EncodingConversionOverflowBytes, EncodingName, EncoderFallback.GetType()), "bytes");
         }
 
-        internal void ThrowBytesOverflow(EncoderNLS encoder, bool nothingEncoded)
+        internal void ThrowBytesOverflow(EncoderNLS? encoder, bool nothingEncoded)
         {
             if (encoder == null || encoder._throwOnOverflow || nothingEncoded)
             {
@@ -1201,7 +1202,7 @@ namespace System.Text
             }
 
             // If we didn't throw, we are in convert and have to remember our flushing
-            encoder.ClearMustFlush();
+            encoder!.ClearMustFlush();
         }
 
         [StackTraceHidden]
@@ -1218,7 +1219,7 @@ namespace System.Text
                 SR.Format(SR.Argument_EncodingConversionOverflowChars, EncodingName, DecoderFallback.GetType()), "chars");
         }
 
-        internal void ThrowCharsOverflow(DecoderNLS decoder, bool nothingDecoded)
+        internal void ThrowCharsOverflow(DecoderNLS? decoder, bool nothingDecoded)
         {
             if (decoder == null || decoder._throwOnOverflow || nothingDecoded)
             {
@@ -1231,7 +1232,7 @@ namespace System.Text
             }
 
             // If we didn't throw, we are in convert and have to remember our flushing
-            decoder.ClearMustFlush();
+            decoder!.ClearMustFlush();
         }
 
         internal sealed class DefaultEncoder : Encoder, IObjectReference
@@ -1380,13 +1381,13 @@ namespace System.Text
             private unsafe char* _charEnd;
             private int _charCountResult = 0;
             private Encoding _enc;
-            private DecoderNLS _decoder;
+            private DecoderNLS? _decoder;
             private unsafe byte* _byteStart;
             private unsafe byte* _byteEnd;
             private unsafe byte* _bytes;
             private DecoderFallbackBuffer _fallbackBuffer;
 
-            internal unsafe EncodingCharBuffer(Encoding enc, DecoderNLS decoder, char* charStart, int charCount,
+            internal unsafe EncodingCharBuffer(Encoding enc, DecoderNLS? decoder, char* charStart, int charCount,
                                                     byte* byteStart, int byteCount)
             {
                 _enc = enc;
@@ -1556,10 +1557,10 @@ namespace System.Text
             private unsafe char* _charEnd;
             private int _byteCountResult = 0;
             private Encoding _enc;
-            private EncoderNLS _encoder;
+            private EncoderNLS? _encoder;
             internal EncoderFallbackBuffer fallbackBuffer;
 
-            internal unsafe EncodingByteBuffer(Encoding inEncoding, EncoderNLS inEncoder,
+            internal unsafe EncodingByteBuffer(Encoding inEncoding, EncoderNLS? inEncoder,
                         byte* inByteStart, int inByteCount, char* inCharStart, int inCharCount)
             {
                 _enc = inEncoding;
@@ -1582,7 +1583,7 @@ namespace System.Text
                     if (_encoder._throwOnOverflow && _encoder.InternalHasFallbackBuffer &&
                         this.fallbackBuffer.Remaining > 0)
                         throw new ArgumentException(SR.Format(SR.Argument_EncoderFallbackNotEmpty,
-                            _encoder.Encoding.EncodingName, _encoder.Fallback.GetType()));
+                            _encoder.Encoding.EncodingName, _encoder.Fallback!.GetType()));
                 }
                 fallbackBuffer.InternalInitialize(_chars, _charEnd, _encoder, _bytes != null);
             }
@@ -1607,17 +1608,17 @@ namespace System.Text
 
             internal bool AddByte(byte b1)
             {
-                return (AddByte(b1, 0));
+                return AddByte(b1, 0);
             }
 
             internal bool AddByte(byte b1, byte b2)
             {
-                return (AddByte(b1, b2, 0));
+                return AddByte(b1, b2, 0);
             }
 
             internal bool AddByte(byte b1, byte b2, int moreBytesExpected)
             {
-                return (AddByte(b1, 1 + moreBytesExpected) && AddByte(b2, moreBytesExpected));
+                return AddByte(b1, 1 + moreBytesExpected) && AddByte(b2, moreBytesExpected);
             }
 
             internal bool AddByte(byte b1, byte b2, byte b3)
@@ -1627,17 +1628,17 @@ namespace System.Text
 
             internal bool AddByte(byte b1, byte b2, byte b3, int moreBytesExpected)
             {
-                return (AddByte(b1, 2 + moreBytesExpected) &&
+                return AddByte(b1, 2 + moreBytesExpected) &&
                         AddByte(b2, 1 + moreBytesExpected) &&
-                        AddByte(b3, moreBytesExpected));
+                        AddByte(b3, moreBytesExpected);
             }
 
             internal bool AddByte(byte b1, byte b2, byte b3, byte b4)
             {
-                return (AddByte(b1, 3) &&
+                return AddByte(b1, 3) &&
                         AddByte(b2, 2) &&
                         AddByte(b3, 1) &&
-                        AddByte(b4, 0));
+                        AddByte(b4, 0);
             }
 
             internal unsafe void MovePrevious(bool bThrow)
@@ -1668,7 +1669,7 @@ namespace System.Text
                 get
                 {
                     // See if fallbackBuffer is not empty or if there's data left in chars buffer.
-                    return ((fallbackBuffer.Remaining > 0) || (_chars < _charEnd));
+                    return (fallbackBuffer.Remaining > 0) || (_chars < _charEnd);
                 }
             }
 
index 01837fc..a1b7c92 100644 (file)
@@ -6,6 +6,8 @@
 // https://github.com/dotnet/buildtools/blob/6736870b84e06b75e7df32bb84d442db1b2afa10/src/Microsoft.DotNet.Build.Tasks/PackageFiles/encoding.targets
 //
 
+// TODO-NULLABLE: We should edit original source instead: https://github.com/dotnet/buildtools/blob/master/src/Microsoft.DotNet.Build.Tasks/GenerateEncodingTable.cs#L235
+#nullable enable
 namespace System.Text
 {
     internal static partial class EncodingTable
index 002d9ef..cfffd3c 100644 (file)
@@ -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.
 
+#nullable enable
 namespace System.Text
 {
     public sealed class EncodingInfo
@@ -22,7 +23,7 @@ namespace System.Text
             return Encoding.GetEncoding(CodePage);
         }
 
-        public override bool Equals(object value)
+        public override bool Equals(object? value)
         {
             if (value is EncodingInfo that)
             {
index 51d0e66..0df2975 100644 (file)
@@ -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.
 
+#nullable enable
 using System;
 using System.Collections;
 using System.Diagnostics;
@@ -66,7 +67,7 @@ namespace System.Text
         public override unsafe int GetByteCount(string s)
         {
             // Validate input
-            if (s==null)
+            if (s == null)
                 throw new ArgumentNullException(nameof(s));
 
             fixed (char* pChars = s)
index 22ce52c..47b7636 100644 (file)
@@ -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.
 
+#nullable enable
 using System;
 using System.Collections;
 using System.Collections.Generic;
@@ -11,16 +12,16 @@ namespace System.Text
     public abstract class EncodingProvider
     {
         public EncodingProvider() { }
-        public abstract Encoding GetEncoding(string name);
-        public abstract Encoding GetEncoding(int codepage);
+        public abstract Encoding? GetEncoding(string name);
+        public abstract Encoding? GetEncoding(int codepage);
 
         // GetEncoding should return either valid encoding or null. shouldn't throw any exception except on null name
-        public virtual Encoding GetEncoding(string name, EncoderFallback encoderFallback, DecoderFallback decoderFallback)
+        public virtual Encoding? GetEncoding(string name, EncoderFallback encoderFallback, DecoderFallback decoderFallback)
         {
-            Encoding enc = GetEncoding(name);
+            Encoding? enc = GetEncoding(name);
             if (enc != null)
             {
-                enc = (Encoding)GetEncoding(name).Clone();
+                enc = (Encoding)enc.Clone();
                 enc.EncoderFallback = encoderFallback;
                 enc.DecoderFallback = decoderFallback;
             }
@@ -28,12 +29,12 @@ namespace System.Text
             return enc;
         }
 
-        public virtual Encoding GetEncoding(int codepage, EncoderFallback encoderFallback, DecoderFallback decoderFallback)
+        public virtual Encoding? GetEncoding(int codepage, EncoderFallback encoderFallback, DecoderFallback decoderFallback)
         {
-            Encoding enc = GetEncoding(codepage);
+            Encoding? enc = GetEncoding(codepage);
             if (enc != null)
             {
-                enc = (Encoding)GetEncoding(codepage).Clone();
+                enc = (Encoding)enc.Clone();
                 enc.EncoderFallback = encoderFallback;
                 enc.DecoderFallback = decoderFallback;
             }
@@ -66,7 +67,7 @@ namespace System.Text
             }
         }
 
-        internal static Encoding GetEncodingFromProvider(int codepage)
+        internal static Encoding? GetEncodingFromProvider(int codepage)
         {
             if (s_providers == null)
                 return null;
@@ -74,7 +75,7 @@ namespace System.Text
             EncodingProvider[] providers = s_providers;
             foreach (EncodingProvider provider in providers)
             {
-                Encoding enc = provider.GetEncoding(codepage);
+                Encoding? enc = provider.GetEncoding(codepage);
                 if (enc != null)
                     return enc;
             }
@@ -82,7 +83,7 @@ namespace System.Text
             return null;
         }
 
-        internal static Encoding GetEncodingFromProvider(string encodingName)
+        internal static Encoding? GetEncodingFromProvider(string encodingName)
         {
             if (s_providers == null)
                 return null;
@@ -90,7 +91,7 @@ namespace System.Text
             EncodingProvider[] providers = s_providers;
             foreach (EncodingProvider provider in providers)
             {
-                Encoding enc = provider.GetEncoding(encodingName);
+                Encoding? enc = provider.GetEncoding(encodingName);
                 if (enc != null)
                     return enc;
             }
@@ -98,7 +99,7 @@ namespace System.Text
             return null;
         }
 
-        internal static Encoding GetEncodingFromProvider(int codepage, EncoderFallback enc, DecoderFallback dec)
+        internal static Encoding? GetEncodingFromProvider(int codepage, EncoderFallback enc, DecoderFallback dec)
         {
             if (s_providers == null)
                 return null;
@@ -106,15 +107,15 @@ namespace System.Text
             EncodingProvider[] providers = s_providers;
             foreach (EncodingProvider provider in providers)
             {
-                Encoding encing = provider.GetEncoding(codepage, enc, dec);
-                if (encing != null)
-                    return encing;
+                Encoding? encoding = provider.GetEncoding(codepage, enc, dec);
+                if (encoding != null)
+                    return encoding;
             }
 
             return null;
         }
 
-        internal static Encoding GetEncodingFromProvider(string encodingName, EncoderFallback enc, DecoderFallback dec)
+        internal static Encoding? GetEncodingFromProvider(string encodingName, EncoderFallback enc, DecoderFallback dec)
         {
             if (s_providers == null)
                 return null;
@@ -122,7 +123,7 @@ namespace System.Text
             EncodingProvider[] providers = s_providers;
             foreach (EncodingProvider provider in providers)
             {
-                Encoding encoding = provider.GetEncoding(encodingName, enc, dec);
+                Encoding? encoding = provider.GetEncoding(encodingName, enc, dec);
                 if (encoding != null)
                     return encoding;
             }
@@ -131,6 +132,6 @@ namespace System.Text
         }
 
         private static object s_InternalSyncObject = new object();
-        private static volatile EncodingProvider[] s_providers;
+        private static volatile EncodingProvider[]? s_providers;
     }
 }
index 38f32e2..0133be5 100644 (file)
@@ -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.
 
+#nullable enable
 using System.Collections;
 using System.Diagnostics;
 using System.Threading;
@@ -16,7 +17,7 @@ namespace System.Text
     internal static partial class EncodingTable
     {
         private static readonly Hashtable s_nameToCodePage = Hashtable.Synchronized(new Hashtable(StringComparer.OrdinalIgnoreCase));
-        private static CodePageDataItem[] s_codePageToCodePageData;
+        private static CodePageDataItem?[]? s_codePageToCodePageData;
 
         /*=================================GetCodePageFromName==========================
         **Action: Given a encoding name, return the correct code page number for this encoding.
@@ -120,11 +121,11 @@ namespace System.Text
             return arrayEncodingInfo;
         }
 
-        internal static CodePageDataItem GetCodePageDataItem(int codePage)
+        internal static CodePageDataItem? GetCodePageDataItem(int codePage)
         {
             if (s_codePageToCodePageData == null)
             {
-                Interlocked.CompareExchange(ref s_codePageToCodePageData, new CodePageDataItem[s_mappedCodePages.Length], null);
+                Interlocked.CompareExchange<CodePageDataItem?[]?>(ref s_codePageToCodePageData, new CodePageDataItem[s_mappedCodePages.Length], null);
             }
 
             // Keep in sync with s_mappedCodePages
@@ -159,10 +160,10 @@ namespace System.Text
                     return null;
             }
 
-            CodePageDataItem data = s_codePageToCodePageData[index];
+            CodePageDataItem? data = s_codePageToCodePageData![index]; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
             if (data == null)
             {
-                Interlocked.CompareExchange(ref s_codePageToCodePageData[index], InternalGetCodePageDataItem(codePage, index), null);
+                Interlocked.CompareExchange<CodePageDataItem?>(ref s_codePageToCodePageData[index], InternalGetCodePageDataItem(codePage, index), null);
                 data = s_codePageToCodePageData[index];
             }
 
index 736fff5..672348b 100644 (file)
@@ -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.
 
+#nullable enable
 using System;
 using System.Diagnostics;
 
@@ -25,7 +26,7 @@ namespace System.Text
         // GetByteCount
         // Note: We start by assuming that the output will be the same as count.  Having
         // an encoder or fallback may change that assumption
-        internal override unsafe int GetByteCount(char* chars, int charCount, EncoderNLS encoder)
+        internal override unsafe int GetByteCount(char* chars, int charCount, EncoderNLS? encoder)
         {
             // Just need to ASSERT, this is called by something else internal that checked parameters already
             Debug.Assert(charCount >= 0, "[Latin1Encoding.GetByteCount]count is negative");
@@ -38,7 +39,7 @@ namespace System.Text
 
             // If we have an encoder AND we aren't using default fallback,
             // then we may have a complicated count.
-            EncoderReplacementFallback fallback;
+            EncoderReplacementFallback? fallback;
             if (encoder != null)
             {
                 charLeftOver = encoder._charLeftOver;
@@ -79,7 +80,7 @@ namespace System.Text
             char* charEnd = chars + charCount;
 
             // For fallback we may need a fallback buffer, we know we aren't default fallback.
-            EncoderFallbackBuffer fallbackBuffer = null;
+            EncoderFallbackBuffer? fallbackBuffer = null;
             char* charsForFallback;
 
             // We may have a left over character from last time, try and process it.
@@ -146,7 +147,7 @@ namespace System.Text
         }
 
         internal override unsafe int GetBytes(char* chars, int charCount,
-                                                byte* bytes, int byteCount, EncoderNLS encoder)
+                                                byte* bytes, int byteCount, EncoderNLS? encoder)
         {
             // Just need to ASSERT, this is called by something else internal that checked parameters already
             Debug.Assert(bytes != null, "[Latin1Encoding.GetBytes]bytes is null");
@@ -159,7 +160,7 @@ namespace System.Text
 
             // Get any left over characters & check fast or slower fallback type
             char charLeftOver = (char)0;
-            EncoderReplacementFallback fallback = null;
+            EncoderReplacementFallback? fallback = null;
             if (encoder != null)
             {
                 charLeftOver = encoder._charLeftOver;
@@ -244,7 +245,7 @@ namespace System.Text
             byte* byteEnd = bytes + byteCount;
 
             // For fallback we may need a fallback buffer, we know we aren't default fallback, create & init it
-            EncoderFallbackBuffer fallbackBuffer = null;
+            EncoderFallbackBuffer? fallbackBuffer = null;
             char* charsForFallback;
 
             // We may have a left over character from last time, try and process it.
@@ -365,7 +366,7 @@ namespace System.Text
         }
 
         // This is internal and called by something else,
-        internal override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS decoder)
+        internal override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS? decoder)
         {
             // Just assert, we're called internally so these should be safe, checked already
             Debug.Assert(bytes != null, "[Latin1Encoding.GetCharCount]bytes is null");
@@ -377,7 +378,7 @@ namespace System.Text
         }
 
         internal override unsafe int GetChars(byte* bytes, int byteCount,
-                                                char* chars, int charCount, DecoderNLS decoder)
+                                                char* chars, int charCount, DecoderNLS? decoder)
         {
             // Just need to ASSERT, this is called by something else internal that checked parameters already
             Debug.Assert(bytes != null, "[Latin1Encoding.GetChars]bytes is null");
index a91c0fc..c1289c7 100644 (file)
@@ -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.
 
+#nullable enable
 using System.Buffers;
 using System.Diagnostics;
 using System.Globalization;
@@ -738,7 +739,7 @@ namespace System.Text
             return bytesWritten;
         }
 
-        public override bool Equals(object obj) => (obj is Rune other) && this.Equals(other);
+        public override bool Equals(object? obj) => (obj is Rune other) && this.Equals(other);
 
         public bool Equals(Rune other) => (this == other);
 
@@ -821,7 +822,7 @@ namespace System.Text
                 ThrowHelper.ThrowArgumentNullException(ExceptionArgument.input);
             }
 
-            if ((uint)index >= (uint)input.Length)
+            if ((uint)index >= (uint)input!.Length)
             {
                 ThrowHelper.ThrowArgumentOutOfRange_IndexException();
             }
@@ -1210,7 +1211,7 @@ namespace System.Text
             }
             else
             {
-                return (GetUnicodeCategoryNonAscii(value) == UnicodeCategory.DecimalDigitNumber);
+                return GetUnicodeCategoryNonAscii(value) == UnicodeCategory.DecimalDigitNumber;
             }
         }
 
@@ -1246,7 +1247,7 @@ namespace System.Text
             }
             else
             {
-                return (GetUnicodeCategoryNonAscii(value) == UnicodeCategory.LowercaseLetter);
+                return GetUnicodeCategoryNonAscii(value) == UnicodeCategory.LowercaseLetter;
             }
         }
 
@@ -1285,7 +1286,7 @@ namespace System.Text
             }
             else
             {
-                return (GetUnicodeCategoryNonAscii(value) == UnicodeCategory.UppercaseLetter);
+                return GetUnicodeCategoryNonAscii(value) == UnicodeCategory.UppercaseLetter;
             }
         }
 
@@ -1324,7 +1325,7 @@ namespace System.Text
                 return ToLowerInvariant(value);
             }
 
-            return ChangeCaseCultureAware(value, culture.TextInfo, toUpper: false);
+            return ChangeCaseCultureAware(value, culture!.TextInfo, toUpper: false);
         }
 
         public static Rune ToLowerInvariant(Rune value)
@@ -1367,7 +1368,7 @@ namespace System.Text
                 return ToUpperInvariant(value);
             }
 
-            return ChangeCaseCultureAware(value, culture.TextInfo, toUpper: true);
+            return ChangeCaseCultureAware(value, culture!.TextInfo, toUpper: true);
         }
 
         public static Rune ToUpperInvariant(Rune value)
index 082a510..d650eb9 100644 (file)
@@ -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.
 
+#nullable enable
 namespace System.Text
 {
     // An enumerator for retrieving System.Text.Rune instances from a ROS<char>.
index a62c477..a7681d0 100644 (file)
@@ -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.
 
+#nullable enable
 using System.Diagnostics;
 
 namespace System.Text
@@ -11,7 +12,9 @@ namespace System.Text
         private void ShowChunks(int maxChunksToShow = 10)
         {
             int count = 0;
-            StringBuilder head = this, current = this;
+            StringBuilder head = this;
+            StringBuilder? current = this;
+
             while (current != null)
             {
                 if (count < maxChunksToShow)
@@ -20,17 +23,21 @@ namespace System.Text
                 }
                 else
                 {
+                    Debug.Assert(head.m_ChunkPrevious != null);
                     head = head.m_ChunkPrevious;
                 }
                 current = current.m_ChunkPrevious;
             }
+
             current = head;
             string[] chunks = new string[count];
             for (int i = count; i > 0; i--)
             {
                 chunks[i - 1] = new string(current.m_ChunkChars).Replace('\0', '.');
+                Debug.Assert(current.m_ChunkPrevious != null);
                 current = current.m_ChunkPrevious;
             }
+
             Debug.WriteLine('|' + string.Join('|', chunks) + '|');
         }
     }
index cd88d21..4197175 100644 (file)
@@ -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.
 
+#nullable enable
 using System.Text;
 using System.Runtime;
 using System.Runtime.Serialization;
@@ -41,7 +42,7 @@ namespace System.Text
         /// <summary>
         /// The chunk that logically precedes this chunk.
         /// </summary>
-        internal StringBuilder m_ChunkPrevious;
+        internal StringBuilder? m_ChunkPrevious;
 
         /// <summary>
         /// The number of characters in this chunk.
@@ -98,7 +99,7 @@ namespace System.Text
         /// Initializes a new instance of the <see cref="StringBuilder"/> class.
         /// </summary>
         /// <param name="value">The initial contents of this builder.</param>
-        public StringBuilder(string value)
+        public StringBuilder(string? value)
             : this(value, DefaultCapacity)
         {
         }
@@ -108,7 +109,7 @@ namespace System.Text
         /// </summary>
         /// <param name="value">The initial contents of this builder.</param>
         /// <param name="capacity">The initial capacity of this builder.</param>
-        public StringBuilder(string value, int capacity)
+        public StringBuilder(string? value, int capacity)
             : this(value, 0, value?.Length ?? 0, capacity)
         {
         }
@@ -120,7 +121,7 @@ namespace System.Text
         /// <param name="startIndex">The index to start in <paramref name="value"/>.</param>
         /// <param name="length">The number of characters to read in <paramref name="value"/>.</param>
         /// <param name="capacity">The initial capacity of this builder.</param>
-        public StringBuilder(string value, int startIndex, int length, int capacity)
+        public StringBuilder(string? value, int startIndex, int length, int capacity)
         {
             if (capacity < 0)
             {
@@ -200,7 +201,7 @@ namespace System.Text
             }
 
             int persistedCapacity = 0;
-            string persistedString = null;
+            string? persistedString = null;
             int persistedMaxCapacity = int.MaxValue;
             bool capacityPresent = false;
 
@@ -288,7 +289,7 @@ namespace System.Text
                 Debug.Assert(currentBlock.m_ChunkLength >= 0);
                 Debug.Assert(currentBlock.m_ChunkOffset >= 0);
 
-                StringBuilder prevBlock = currentBlock.m_ChunkPrevious;
+                StringBuilder? prevBlock = currentBlock.m_ChunkPrevious;
                 if (prevBlock == null)
                 {
                     Debug.Assert(currentBlock.m_ChunkOffset == 0);
@@ -363,7 +364,7 @@ namespace System.Text
             }
 
             string result = string.FastAllocateString(Length);
-            StringBuilder chunk = this;
+            StringBuilder? chunk = this;
             unsafe
             {
                 fixed (char* destinationPtr = result)
@@ -514,7 +515,7 @@ namespace System.Text
         {
             get
             {
-                StringBuilder chunk = this;
+                StringBuilder? chunk = this;
                 for (;;)
                 {
                     int indexInBlock = index - chunk.m_ChunkOffset;
@@ -535,7 +536,7 @@ namespace System.Text
             }
             set
             {
-                StringBuilder chunk = this;
+                StringBuilder? chunk = this;
                 for (;;)
                 {
                     int indexInBlock = index - chunk.m_ChunkOffset;
@@ -595,8 +596,8 @@ namespace System.Text
         public struct ChunkEnumerator
         {
             private readonly StringBuilder _firstChunk; // The first Stringbuilder chunk (which is the end of the logical string)
-            private StringBuilder _currentChunk;        // The chunk that this enumerator is currently returning (Current).  
-            private readonly ManyChunkInfo _manyChunks; // Only used for long string builders with many chunks (see constructor)
+            private StringBuilder? _currentChunk;        // The chunk that this enumerator is currently returning (Current).  
+            private readonly ManyChunkInfo? _manyChunks; // Only used for long string builders with many chunks (see constructor)
 
             /// <summary>
             /// Implement IEnumerable.GetEnumerator() to return  'this' as the IEnumerator  
@@ -617,7 +618,10 @@ namespace System.Text
 
                 StringBuilder next = _firstChunk;
                 while (next.m_ChunkPrevious != _currentChunk)
+                {
+                    Debug.Assert(next.m_ChunkPrevious != null);
                     next = next.m_ChunkPrevious;
+                }
                 _currentChunk = next;
                 return true;
             }
@@ -625,7 +629,7 @@ namespace System.Text
             /// <summary>
             /// Implements the IEnumerator pattern.
             /// </summary>
-            public ReadOnlyMemory<char> Current => new ReadOnlyMemory<char>(_currentChunk.m_ChunkChars, 0, _currentChunk.m_ChunkLength);
+            public ReadOnlyMemory<char> Current => new ReadOnlyMemory<char>(_currentChunk!.m_ChunkChars, 0, _currentChunk.m_ChunkLength); // TODO-NULLABLE: NullReferenceException if called before calling MoveNext
 
             #region private
             internal ChunkEnumerator(StringBuilder stringBuilder)
@@ -646,7 +650,7 @@ namespace System.Text
                     _manyChunks = new ManyChunkInfo(stringBuilder, chunkCount);
             }
 
-            private static int ChunkCount(StringBuilder stringBuilder)
+            private static int ChunkCount(StringBuilder? stringBuilder)
             {
                 int ret = 0;
                 while (stringBuilder != null)
@@ -665,7 +669,7 @@ namespace System.Text
                 private readonly StringBuilder[] _chunks;    // These are in normal order (first chunk first) 
                 private int _chunkPos;
 
-                public bool MoveNext(ref StringBuilder current)
+                public bool MoveNext(ref StringBuilder? current)
                 {
                     int pos = ++_chunkPos;
                     if (_chunks.Length <= pos)
@@ -674,7 +678,7 @@ namespace System.Text
                     return true;
                 }
 
-                public ManyChunkInfo(StringBuilder stringBuilder, int chunkCount)
+                public ManyChunkInfo(StringBuilder? stringBuilder, int chunkCount)
                 {
                     _chunks = new StringBuilder[chunkCount];
                     while (0 <= --chunkCount)
@@ -742,7 +746,7 @@ namespace System.Text
         /// <param name="value">The characters to append.</param>
         /// <param name="startIndex">The index to start in <paramref name="value"/>.</param>
         /// <param name="charCount">The number of characters to read in <paramref name="value"/>.</param>
-        public StringBuilder Append(char[] value, int startIndex, int charCount)
+        public StringBuilder Append(char[]? value, int startIndex, int charCount)
         {
             if (startIndex < 0)
             {
@@ -787,7 +791,7 @@ namespace System.Text
         /// Appends a string to the end of this builder.
         /// </summary>
         /// <param name="value">The string to append.</param>
-        public StringBuilder Append(string value)
+        public StringBuilder Append(string? value)
         {
             if (value != null)
             {
@@ -848,7 +852,7 @@ namespace System.Text
         /// <param name="value">The string to append.</param>
         /// <param name="startIndex">The index to start in <paramref name="value"/>.</param>
         /// <param name="count">The number of characters to read in <paramref name="value"/>.</param>
-        public StringBuilder Append(string value, int startIndex, int count)
+        public StringBuilder Append(string? value, int startIndex, int count)
         {
             if (startIndex < 0)
             {
@@ -888,7 +892,7 @@ namespace System.Text
             }
         }
 
-        public StringBuilder Append(StringBuilder value)
+        public StringBuilder Append(StringBuilder? value)
         {
             if (value != null && value.Length != 0)
             {
@@ -897,7 +901,7 @@ namespace System.Text
             return this;
         }
 
-        public StringBuilder Append(StringBuilder value, int startIndex, int count)
+        public StringBuilder Append(StringBuilder? value, int startIndex, int count)
         {
             if (startIndex < 0)
             {
@@ -963,7 +967,7 @@ namespace System.Text
 
         public StringBuilder AppendLine() => Append(Environment.NewLine);
 
-        public StringBuilder AppendLine(string value)
+        public StringBuilder AppendLine(string? value)
         {
             Append(value);
             return Append(Environment.NewLine);
@@ -1008,11 +1012,12 @@ namespace System.Text
 
             AssertInvariants();
 
-            StringBuilder chunk = this;
+            StringBuilder? chunk = this;
             int sourceEndIndex = sourceIndex + count;
             int curDestIndex = count;
             while (count > 0)
             {
+                Debug.Assert(chunk != null);
                 int chunkEndIndex = sourceEndIndex - chunk.m_ChunkOffset;
                 if (chunkEndIndex >= 0)
                 {
@@ -1042,7 +1047,7 @@ namespace System.Text
         /// <param name="index">The index to insert in this builder.</param>
         /// <param name="value">The string to insert.</param>
         /// <param name="count">The number of times to insert the string.</param>
-        public StringBuilder Insert(int index, string value, int count)
+        public StringBuilder Insert(int index, string? value, int count)
         {
             if (count < 0)
             {
@@ -1179,7 +1184,7 @@ namespace System.Text
             return Append(value.ToString());
         }
 
-        internal StringBuilder AppendSpanFormattable<T>(T value, string format, IFormatProvider provider) where T : ISpanFormattable, IFormattable
+        internal StringBuilder AppendSpanFormattable<T>(T value, string? format, IFormatProvider? provider) where T : ISpanFormattable, IFormattable
         {
             if (value.TryFormat(RemainingCurrentChunk, out int charsWritten, format, provider))
             {
@@ -1190,9 +1195,9 @@ namespace System.Text
             return Append(value.ToString(format, provider));
         }
 
-        public StringBuilder Append(object value) => (value == null) ? this : Append(value.ToString());
+        public StringBuilder Append(object? value) => (value == null) ? this : Append(value.ToString());
 
-        public StringBuilder Append(char[] value)
+        public StringBuilder Append(char[]? value)
         {
             if (value?.Length > 0)
             {
@@ -1226,7 +1231,7 @@ namespace System.Text
 
         #region AppendJoin
 
-        public unsafe StringBuilder AppendJoin(string separator, params object[] values)
+        public unsafe StringBuilder AppendJoin(string? separator, params object?[] values)
         {
             separator = separator ?? string.Empty;
             fixed (char* pSeparator = separator)
@@ -1235,7 +1240,7 @@ namespace System.Text
             }
         }
 
-        public unsafe StringBuilder AppendJoin<T>(string separator, IEnumerable<T> values)
+        public unsafe StringBuilder AppendJoin<T>(string? separator, IEnumerable<T> values)
         {
             separator = separator ?? string.Empty;
             fixed (char* pSeparator = separator)
@@ -1244,7 +1249,7 @@ namespace System.Text
             }
         }
 
-        public unsafe StringBuilder AppendJoin(string separator, params string[] values)
+        public unsafe StringBuilder AppendJoin(string? separator, params string?[] values)
         {
             separator = separator ?? string.Empty;
             fixed (char* pSeparator = separator)
@@ -1253,7 +1258,7 @@ namespace System.Text
             }
         }
 
-        public unsafe StringBuilder AppendJoin(char separator, params object[] values)
+        public unsafe StringBuilder AppendJoin(char separator, params object?[] values)
         {
             return AppendJoinCore(&separator, 1, values);
         }
@@ -1263,7 +1268,7 @@ namespace System.Text
             return AppendJoinCore(&separator, 1, values);
         }
 
-        public unsafe StringBuilder AppendJoin(char separator, params string[] values)
+        public unsafe StringBuilder AppendJoin(char separator, params string?[] values)
         {
             return AppendJoinCore(&separator, 1, values);
         }
@@ -1278,6 +1283,7 @@ namespace System.Text
                 ThrowHelper.ThrowArgumentNullException(ExceptionArgument.values);
             }
 
+            Debug.Assert(values != null);
             using (IEnumerator<T> en = values.GetEnumerator())
             {
                 if (!en.MoveNext())
@@ -1311,6 +1317,7 @@ namespace System.Text
                 ThrowHelper.ThrowArgumentNullException(ExceptionArgument.values);
             }
 
+            Debug.Assert(values != null);
             if (values.Length == 0)
             {
                 return this;
@@ -1318,7 +1325,7 @@ namespace System.Text
 
             if (values[0] != null)
             {
-                Append(values[0].ToString());
+                Append(values[0]!.ToString()); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/34644
             }
 
             for (int i = 1; i < values.Length; i++)
@@ -1326,7 +1333,7 @@ namespace System.Text
                 Append(separator, separatorLength);
                 if (values[i] != null)
                 {
-                    Append(values[i].ToString());
+                    Append(values[i]!.ToString()); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/34644
                 }
             }
             return this;
@@ -1334,7 +1341,7 @@ namespace System.Text
 
         #endregion
 
-        public StringBuilder Insert(int index, string value)
+        public StringBuilder Insert(int index, string? value)
         {
             if ((uint)index > (uint)Length)
             {
@@ -1370,7 +1377,7 @@ namespace System.Text
             return this;
         }
 
-        public StringBuilder Insert(int index, char[] value)
+        public StringBuilder Insert(int index, char[]? value)
         {
             if ((uint)index > (uint)Length)
             {
@@ -1382,7 +1389,7 @@ namespace System.Text
             return this;
         }
 
-        public StringBuilder Insert(int index, char[] value, int startIndex, int charCount)
+        public StringBuilder Insert(int index, char[]? value, int startIndex, int charCount)
         {
             int currentLength = Length;
             if ((uint)index > (uint)currentLength)
@@ -1444,7 +1451,7 @@ namespace System.Text
         [CLSCompliant(false)]
         public StringBuilder Insert(int index, ulong value) => Insert(index, value.ToString(), 1);
 
-        public StringBuilder Insert(int index, object value) => (value == null) ? this : Insert(index, value.ToString(), 1);
+        public StringBuilder Insert(int index, object? value) => (value == null) ? this : Insert(index, value.ToString(), 1);
 
         public StringBuilder Insert(int index, ReadOnlySpan<char> value)
         {
@@ -1464,13 +1471,13 @@ namespace System.Text
             return this;
         }
 
-        public StringBuilder AppendFormat(string format, object arg0) => AppendFormatHelper(null, format, new ParamsArray(arg0));
+        public StringBuilder AppendFormat(string format, object? arg0) => AppendFormatHelper(null, format, new ParamsArray(arg0));
 
-        public StringBuilder AppendFormat(string format, object arg0, object arg1) => AppendFormatHelper(null, format, new ParamsArray(arg0, arg1));
+        public StringBuilder AppendFormat(string format, object? arg0, object? arg1) => AppendFormatHelper(null, format, new ParamsArray(arg0, arg1));
 
-        public StringBuilder AppendFormat(string format, object arg0, object arg1, object arg2) => AppendFormatHelper(null, format, new ParamsArray(arg0, arg1, arg2));
+        public StringBuilder AppendFormat(string format, object? arg0, object? arg1, object? arg2) => AppendFormatHelper(null, format, new ParamsArray(arg0, arg1, arg2));
 
-        public StringBuilder AppendFormat(string format, params object[] args)
+        public StringBuilder AppendFormat(string format, params object?[] args)
         {
             if (args == null)
             {
@@ -1483,13 +1490,13 @@ namespace System.Text
             return AppendFormatHelper(null, format, new ParamsArray(args));
         }
 
-        public StringBuilder AppendFormat(IFormatProvider provider, string format, object arg0) => AppendFormatHelper(provider, format, new ParamsArray(arg0));
+        public StringBuilder AppendFormat(IFormatProvider provider, string format, object? arg0) => AppendFormatHelper(provider, format, new ParamsArray(arg0));
 
-        public StringBuilder AppendFormat(IFormatProvider provider, string format, object arg0, object arg1) => AppendFormatHelper(provider, format, new ParamsArray(arg0, arg1));
+        public StringBuilder AppendFormat(IFormatProvider provider, string format, object? arg0, object? arg1) => AppendFormatHelper(provider, format, new ParamsArray(arg0, arg1));
 
-        public StringBuilder AppendFormat(IFormatProvider provider, string format, object arg0, object arg1, object arg2) => AppendFormatHelper(provider, format, new ParamsArray(arg0, arg1, arg2));
+        public StringBuilder AppendFormat(IFormatProvider provider, string format, object? arg0, object? arg1, object? arg2) => AppendFormatHelper(provider, format, new ParamsArray(arg0, arg1, arg2));
 
-        public StringBuilder AppendFormat(IFormatProvider provider, string format, params object[] args)
+        public StringBuilder AppendFormat(IFormatProvider provider, string format, params object?[] args)
         {
             if (args == null)
             {
@@ -1511,7 +1518,7 @@ namespace System.Text
         private const int IndexLimit = 1000000; // Note:            0 <= ArgIndex < IndexLimit
         private const int WidthLimit = 1000000; // Note:  -WidthLimit <  ArgAlign < WidthLimit
 
-        internal StringBuilder AppendFormatHelper(IFormatProvider provider, string format, ParamsArray args)
+        internal StringBuilder AppendFormatHelper(IFormatProvider? provider, string format, ParamsArray args)
         {
             if (format == null)
             {
@@ -1521,9 +1528,9 @@ namespace System.Text
             int pos = 0;
             int len = format.Length;
             char ch = '\x0';
-            StringBuilder unescapedItemFormat = null;
+            StringBuilder? unescapedItemFormat = null;
 
-            ICustomFormatter cf = null;
+            ICustomFormatter? cf = null;
             if (provider != null)
             {
                 cf = (ICustomFormatter)provider.GetFormat(typeof(ICustomFormatter));
@@ -1648,7 +1655,7 @@ namespace System.Text
                 // Start of parsing of optional formatting parameter.
                 //
                 object arg = args[index];
-                string itemFormat = null;
+                string? itemFormat = null;
                 ReadOnlySpan<char> itemFormatSpan = default; // used if itemFormat is null
                 // Is current character a colon? which indicates start of formatting parameter.
                 if (ch == ':')
@@ -1718,7 +1725,7 @@ namespace System.Text
                 if (ch != '}') FormatError();
                 // Construct the output for this arg hole.
                 pos++;
-                string s = null;
+                string? s = null;
                 if (cf != null)
                 {
                     if (itemFormatSpan.Length != 0 && itemFormat == null)
@@ -1780,13 +1787,13 @@ namespace System.Text
         /// If <paramref name="newValue"/> is <c>null</c>, instances of <paramref name="oldValue"/>
         /// are removed from this builder.
         /// </remarks>
-        public StringBuilder Replace(string oldValue, string newValue) => Replace(oldValue, newValue, 0, Length);
+        public StringBuilder Replace(string oldValue, string? newValue) => Replace(oldValue, newValue, 0, Length);
 
         /// <summary>
         /// Determines if the contents of this builder are equal to the contents of another builder.
         /// </summary>
         /// <param name="sb">The other builder.</param>
-        public bool Equals(StringBuilder sb)
+        public bool Equals(StringBuilder? sb)
         {
             if (sb == null)
                 return false;
@@ -1795,9 +1802,9 @@ namespace System.Text
             if (sb == this)
                 return true;
 
-            StringBuilder thisChunk = this;
+            StringBuilder? thisChunk = this;
             int thisChunkIndex = thisChunk.m_ChunkLength;
-            StringBuilder sbChunk = sb;
+            StringBuilder? sbChunk = sb;
             int sbChunkIndex = sbChunk.m_ChunkLength;
             for (;;)
             {
@@ -1824,6 +1831,8 @@ namespace System.Text
                     return sbChunkIndex < 0;
                 if (sbChunkIndex < 0)
                     return false;
+
+                Debug.Assert(thisChunk != null && sbChunk != null);
                 if (thisChunk.m_ChunkChars[thisChunkIndex] != sbChunk.m_ChunkChars[sbChunkIndex])
                     return false;
             }
@@ -1851,6 +1860,7 @@ namespace System.Text
                 if (!chunk.EqualsOrdinal(span.Slice(span.Length - offset, chunk_length)))
                     return false;
 
+                Debug.Assert(sbChunk.m_ChunkPrevious != null);
                 sbChunk = sbChunk.m_ChunkPrevious;
             } while (sbChunk != null);
 
@@ -1869,7 +1879,7 @@ namespace System.Text
         /// If <paramref name="newValue"/> is <c>null</c>, instances of <paramref name="oldValue"/>
         /// are removed from this builder.
         /// </remarks>
-        public StringBuilder Replace(string oldValue, string newValue, int startIndex, int count)
+        public StringBuilder Replace(string oldValue, string? newValue, int startIndex, int count)
         {
             int currentLength = Length;
             if ((uint)startIndex > (uint)currentLength)
@@ -1893,7 +1903,7 @@ namespace System.Text
 
             int deltaLength = newValue.Length - oldValue.Length;
 
-            int[] replacements = null; // A list of replacement positions in a chunk to apply
+            int[]? replacements = null; // A list of replacement positions in a chunk to apply
             int replacementsCount = 0;
 
             // Find the chunk, indexInChunk for the starting point
@@ -1901,6 +1911,7 @@ namespace System.Text
             int indexInChunk = startIndex - chunk.m_ChunkOffset;
             while (count > 0)
             {
+                Debug.Assert(chunk != null);
                 // Look for a match in the chunk,indexInChunk pointer
                 if (StartsWith(chunk, indexInChunk, count, oldValue))
                 {
@@ -1932,6 +1943,7 @@ namespace System.Text
                     int indexBeforeAdjustment = index;
 
                     // See if we accumulated any replacements, if so apply them.
+                    Debug.Assert(replacements != null);
                     ReplaceAllInChunk(replacements, replacementsCount, chunk, oldValue.Length, newValue);
                     // The replacement has affected the logical index.  Adjust it.
                     index += ((newValue.Length - oldValue.Length) * replacementsCount);
@@ -1997,6 +2009,8 @@ namespace System.Text
                 }
                 if (startIndexInChunk >= 0)
                     break;
+
+                Debug.Assert(chunk.m_ChunkPrevious != null);
                 chunk = chunk.m_ChunkPrevious;
             }
 
@@ -2167,7 +2181,7 @@ namespace System.Text
 
                 if (indexInChunk >= chunk.m_ChunkLength)
                 {
-                    chunk = Next(chunk);
+                    chunk = Next(chunk)!;
                     if (chunk == null)
                         return false;
                     indexInChunk = 0;
@@ -2215,7 +2229,9 @@ namespace System.Text
                     indexInChunk += lengthToCopy;
                     if (indexInChunk >= chunk.m_ChunkLength)
                     {
-                        chunk = Next(chunk);
+                        StringBuilder? nextChunk = Next(chunk);
+                        Debug.Assert(nextChunk != null, "we should never get past last chunk because range should already be validated before calling");
+                        chunk = nextChunk;
                         indexInChunk = 0;
                     }
                     count -= lengthToCopy;
@@ -2283,6 +2299,7 @@ namespace System.Text
             StringBuilder result = this;
             while (result.m_ChunkOffset > index)
             {
+                Debug.Assert(result.m_ChunkPrevious != null);
                 result = result.m_ChunkPrevious;
             }
 
@@ -2301,6 +2318,7 @@ namespace System.Text
             StringBuilder result = this;
             while (result.m_ChunkOffset * sizeof(char) > byteIndex)
             {
+                Debug.Assert(result.m_ChunkPrevious != null);
                 result = result.m_ChunkPrevious;
             }
 
@@ -2325,7 +2343,7 @@ namespace System.Text
         /// way down until it finds the specified chunk (which is O(n)). Thus, it is more expensive than
         /// a field fetch.
         /// </remarks>
-        private StringBuilder Next(StringBuilder chunk) => chunk == this ? null : FindChunkForIndex(chunk.m_ChunkOffset + chunk.m_ChunkLength);
+        private StringBuilder? Next(StringBuilder chunk) => chunk == this ? null : FindChunkForIndex(chunk.m_ChunkOffset + chunk.m_ChunkLength);
 
         /// <summary>
         /// Transfers the character buffer from this chunk to a new chunk, and allocates a new buffer with a minimum size for this chunk.
@@ -2438,6 +2456,7 @@ namespace System.Text
             while (chunk.m_ChunkOffset > index)
             {
                 chunk.m_ChunkOffset += count;
+                Debug.Assert(chunk.m_ChunkPrevious != null);
                 chunk = chunk.m_ChunkPrevious;
             }
             indexInChunk = index - chunk.m_ChunkOffset;
@@ -2498,7 +2517,7 @@ namespace System.Text
         /// <param name="size">The size of the character buffer for this chunk.</param>
         /// <param name="maxCapacity">The maximum capacity, to be stored in this chunk.</param>
         /// <param name="previousBlock">The predecessor of this chunk.</param>
-        private StringBuilder(int size, int maxCapacity, StringBuilder previousBlock)
+        private StringBuilder(int size, int maxCapacity, StringBuilder? previousBlock)
         {
             Debug.Assert(size > 0);
             Debug.Assert(maxCapacity > 0);
@@ -2532,7 +2551,7 @@ namespace System.Text
 
             // Find the chunks for the start and end of the block to delete.
             chunk = this;
-            StringBuilder endChunk = null;
+            StringBuilder? endChunk = null;
             int endIndexInChunk = 0;
             for (;;)
             {
@@ -2553,6 +2572,8 @@ namespace System.Text
                 {
                     chunk.m_ChunkOffset -= count;
                 }
+
+                Debug.Assert(chunk.m_ChunkPrevious != null);
                 chunk = chunk.m_ChunkPrevious;
             }
             Debug.Assert(chunk != null, "We fell off the beginning of the string!");
index e699cc2..ebffbe4 100644 (file)
@@ -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.
 
+#nullable enable
 namespace System.Text
 {
     /// <summary>Provide a cached reusable instance of stringbuilder per thread.</summary>
@@ -18,7 +19,7 @@ namespace System.Text
         // Please do not change the type, the name, or the semantic usage of this member without understanding the implication for tools. 
         // Get in touch with the diagnostics team if you have questions.
         [ThreadStatic]
-        private static StringBuilder t_cachedInstance;
+        private static StringBuilder? t_cachedInstance;
 
         /// <summary>Get a StringBuilder for the specified capacity.</summary>
         /// <remarks>If a StringBuilder of an appropriate size is cached, it will be returned and the cache emptied.</remarks>
@@ -26,7 +27,7 @@ namespace System.Text
         {
             if (capacity <= MaxBuilderSize)
             {
-                StringBuilder sb = t_cachedInstance;
+                StringBuilder? sb = t_cachedInstance;
                 if (sb != null)
                 {
                     // Avoid stringbuilder block fragmentation by getting a new StringBuilder
@@ -39,6 +40,7 @@ namespace System.Text
                     }
                 }
             }
+
             return new StringBuilder(capacity);
         }
 
index fe12dfa..8abb989 100644 (file)
@@ -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.
 
+#nullable enable
 using System.Collections;
 using System.Collections.Generic;
 
index 02f3167..1b81f17 100644 (file)
@@ -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.
 
+#nullable enable
 //
 // Don't override IsAlwaysNormalized because it is just a Unicode Transformation and could be confused.
 //
@@ -125,7 +126,7 @@ namespace System.Text
         public override unsafe int GetByteCount(string s)
         {
             // Validate input
-            if (s==null)
+            if (s == null)
                 throw new ArgumentNullException(nameof(s));
 
             fixed (char* pChars = s)
@@ -362,8 +363,7 @@ namespace System.Text
         //
         // End of standard methods copied from EncodingNLS.cs
         //
-
-        internal override unsafe int GetByteCount(char* chars, int count, EncoderNLS encoder)
+        internal override unsafe int GetByteCount(char* chars, int count, EncoderNLS? encoder)
         {
             Debug.Assert(chars != null, "[UTF32Encoding.GetByteCount]chars!=null");
             Debug.Assert(count >= 0, "[UTF32Encoding.GetByteCount]count >=0");
@@ -375,7 +375,7 @@ namespace System.Text
             char highSurrogate = '\0';
 
             // For fallback we may need a fallback buffer
-            EncoderFallbackBuffer fallbackBuffer = null;
+            EncoderFallbackBuffer? fallbackBuffer = null;
             char* charsForFallback;
 
             if (encoder != null)
@@ -385,7 +385,7 @@ namespace System.Text
 
                 // We mustn't have left over fallback data when counting
                 if (fallbackBuffer.Remaining > 0)
-                    throw new ArgumentException(SR.Format(SR.Argument_EncoderFallbackNotEmpty, this.EncodingName, encoder.Fallback.GetType()));
+                    throw new ArgumentException(SR.Format(SR.Argument_EncoderFallbackNotEmpty, this.EncodingName, encoder.Fallback?.GetType().ToString() ?? string.Empty));
             }
             else
             {
@@ -495,7 +495,7 @@ namespace System.Text
         }
 
         internal override unsafe int GetBytes(char* chars, int charCount,
-                                                 byte* bytes, int byteCount, EncoderNLS encoder)
+                                                 byte* bytes, int byteCount, EncoderNLS? encoder)
         {
             Debug.Assert(chars != null, "[UTF32Encoding.GetBytes]chars!=null");
             Debug.Assert(bytes != null, "[UTF32Encoding.GetBytes]bytes!=null");
@@ -510,7 +510,7 @@ namespace System.Text
             char highSurrogate = '\0';
 
             // For fallback we may need a fallback buffer
-            EncoderFallbackBuffer fallbackBuffer = null;
+            EncoderFallbackBuffer? fallbackBuffer = null;
             char* charsForFallback;
 
             if (encoder != null)
@@ -520,7 +520,7 @@ namespace System.Text
 
                 // We mustn't have left over fallback data when not converting
                 if (encoder._throwOnOverflow && fallbackBuffer.Remaining > 0)
-                    throw new ArgumentException(SR.Format(SR.Argument_EncoderFallbackNotEmpty, this.EncodingName, encoder.Fallback.GetType()));
+                    throw new ArgumentException(SR.Format(SR.Argument_EncoderFallbackNotEmpty, this.EncodingName, encoder.Fallback!.GetType())); // TODO-NULLABLE: NullReferenceException
             }
             else
             {
@@ -696,12 +696,12 @@ namespace System.Text
             return (int)(bytes - byteStart);
         }
 
-        internal override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS baseDecoder)
+        internal override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS? baseDecoder)
         {
             Debug.Assert(bytes != null, "[UTF32Encoding.GetCharCount]bytes!=null");
             Debug.Assert(count >= 0, "[UTF32Encoding.GetCharCount]count >=0");
 
-            UTF32Decoder decoder = (UTF32Decoder)baseDecoder;
+            UTF32Decoder? decoder = (UTF32Decoder?)baseDecoder;
 
             // None so far!
             int charCount = 0;
@@ -713,7 +713,7 @@ namespace System.Text
             uint iChar = 0;
 
             // For fallback we may need a fallback buffer
-            DecoderFallbackBuffer fallbackBuffer = null;
+            DecoderFallbackBuffer? fallbackBuffer = null;
 
             // See if there's anything in our decoder
             if (decoder != null)
@@ -839,14 +839,14 @@ namespace System.Text
         }
 
         internal override unsafe int GetChars(byte* bytes, int byteCount,
-                                                char* chars, int charCount, DecoderNLS baseDecoder)
+                                                char* chars, int charCount, DecoderNLS? baseDecoder)
         {
             Debug.Assert(chars != null, "[UTF32Encoding.GetChars]chars!=null");
             Debug.Assert(bytes != null, "[UTF32Encoding.GetChars]bytes!=null");
             Debug.Assert(byteCount >= 0, "[UTF32Encoding.GetChars]byteCount >=0");
             Debug.Assert(charCount >= 0, "[UTF32Encoding.GetChars]charCount >=0");
 
-            UTF32Decoder decoder = (UTF32Decoder)baseDecoder;
+            UTF32Decoder? decoder = (UTF32Decoder?)baseDecoder;
 
             // None so far!
             char* charStart = chars;
@@ -860,7 +860,7 @@ namespace System.Text
             uint iChar = 0;
 
             // For fallback we may need a fallback buffer
-            DecoderFallbackBuffer fallbackBuffer = null;
+            DecoderFallbackBuffer? fallbackBuffer = null;
             char* charsForFallback;
 
             // See if there's anything in our decoder
@@ -868,6 +868,7 @@ namespace System.Text
             {
                 readCount = decoder.readByteCount;
                 iChar = (uint)decoder.iChar;
+                Debug.Assert(baseDecoder != null);
                 fallbackBuffer = baseDecoder.FallbackBuffer;
 
                 // Shouldn't have anything in fallback buffer for GetChars
@@ -1157,7 +1158,7 @@ namespace System.Text
             _bigEndian ? (ReadOnlySpan<byte>)new byte[4] { 0x00, 0x00, 0xFE, 0xFF } : // uses C# compiler's optimization for static byte[] data
             (ReadOnlySpan<byte>)new byte[4] { 0xFF, 0xFE, 0x00, 0x00 };      
 
-        public override bool Equals(object value)
+        public override bool Equals(object? value)
         {
             if (value is UTF32Encoding that)
             {
@@ -1166,7 +1167,8 @@ namespace System.Text
                        (EncoderFallback.Equals(that.EncoderFallback)) &&
                        (DecoderFallback.Equals(that.DecoderFallback));
             }
-            return (false);
+
+            return false;
         }
 
 
index a932778..d398aec 100644 (file)
@@ -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.
 
+#nullable enable
 //
 // Don't override IsAlwaysNormalized because it is just a Unicode Transformation and could be confused.
 //
@@ -32,15 +33,15 @@ namespace System.Text
         internal static readonly UTF7Encoding s_default = new UTF7Encoding();
 
         // The set of base 64 characters.
-        private byte[] _base64Bytes;
+        private byte[] _base64Bytes = null!;
         // The decoded bits for every base64 values. This array has a size of 128 elements.
         // The index is the code point value of the base 64 characters.  The value is -1 if
         // the code point is not a valid base 64 character.  Otherwise, the value is a value
         // from 0 ~ 63.
-        private sbyte[] _base64Values;
+        private sbyte[] _base64Values = null!;
         // The array to decide if a Unicode code point below 0x80 can be directly encoded in UTF7.
         // This array has a size of 128.
-        private bool[] _directEncode;
+        private bool[] _directEncode = null!;
 
         private bool _allowOptionals;
 
@@ -97,7 +98,7 @@ namespace System.Text
             this.decoderFallback = new DecoderUTF7Fallback();
         }
 
-        public override bool Equals(object value)
+        public override bool Equals(object? value)
         {
             if (value is UTF7Encoding that)
             {
@@ -105,7 +106,7 @@ namespace System.Text
                        (EncoderFallback.Equals(that.EncoderFallback)) &&
                        (DecoderFallback.Equals(that.DecoderFallback));
             }
-            return (false);
+            return false;
         }
 
         // Compared to all the other encodings, variations of UTF7 are unlikely
@@ -157,7 +158,7 @@ namespace System.Text
         public override unsafe int GetByteCount(string s)
         {
             // Validate input
-            if (s==null)
+            if (s == null)
                 throw new ArgumentNullException(nameof(s));
 
             fixed (char* pChars = s)
@@ -394,8 +395,7 @@ namespace System.Text
         //
         // End of standard methods copied from EncodingNLS.cs
         //
-
-        internal sealed override unsafe int GetByteCount(char* chars, int count, EncoderNLS baseEncoder)
+        internal sealed override unsafe int GetByteCount(char* chars, int count, EncoderNLS? baseEncoder)
         {
             Debug.Assert(chars != null, "[UTF7Encoding.GetByteCount]chars!=null");
             Debug.Assert(count >= 0, "[UTF7Encoding.GetByteCount]count >=0");
@@ -405,14 +405,14 @@ namespace System.Text
         }
 
         internal sealed override unsafe int GetBytes(
-            char* chars, int charCount, byte* bytes, int byteCount, EncoderNLS baseEncoder)
+            char* chars, int charCount, byte* bytes, int byteCount, EncoderNLS? baseEncoder)
         {
             Debug.Assert(byteCount >= 0, "[UTF7Encoding.GetBytes]byteCount >=0");
             Debug.Assert(chars != null, "[UTF7Encoding.GetBytes]chars!=null");
             Debug.Assert(charCount >= 0, "[UTF7Encoding.GetBytes]charCount >=0");
 
             // Get encoder info
-            UTF7Encoding.Encoder encoder = (UTF7Encoding.Encoder)baseEncoder;
+            UTF7Encoding.Encoder? encoder = (UTF7Encoding.Encoder?)baseEncoder;
 
             // Default bits & count
             int bits = 0;
@@ -544,7 +544,7 @@ namespace System.Text
             return buffer.Count;
         }
 
-        internal sealed override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS baseDecoder)
+        internal sealed override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS? baseDecoder)
         {
             Debug.Assert(count >= 0, "[UTF7Encoding.GetCharCount]count >=0");
             Debug.Assert(bytes != null, "[UTF7Encoding.GetCharCount]bytes!=null");
@@ -554,14 +554,14 @@ namespace System.Text
         }
 
         internal sealed override unsafe int GetChars(
-            byte* bytes, int byteCount, char* chars, int charCount, DecoderNLS baseDecoder)
+            byte* bytes, int byteCount, char* chars, int charCount, DecoderNLS? baseDecoder)
         {
             Debug.Assert(byteCount >= 0, "[UTF7Encoding.GetChars]byteCount >=0");
             Debug.Assert(bytes != null, "[UTF7Encoding.GetChars]bytes!=null");
             Debug.Assert(charCount >= 0, "[UTF7Encoding.GetChars]charCount >=0");
 
             // Might use a decoder
-            UTF7Encoding.Decoder decoder = (UTF7Encoding.Decoder)baseDecoder;
+            UTF7Encoding.Decoder? decoder = (UTF7Encoding.Decoder?)baseDecoder;
 
             // Get our output buffer info.
             Encoding.EncodingCharBuffer buffer = new Encoding.EncodingCharBuffer(
@@ -843,7 +843,7 @@ namespace System.Text
             {
                 get
                 {
-                    return (this.bits != 0 || this.bitCount != -1);
+                    return this.bits != 0 || this.bitCount != -1;
                 }
             }
         }
@@ -872,14 +872,14 @@ namespace System.Text
                 }
             }
 
-            public override bool Equals(object value)
+            public override bool Equals(object? value)
             {
-                DecoderUTF7Fallback that = value as DecoderUTF7Fallback;
+                DecoderUTF7Fallback? that = value as DecoderUTF7Fallback;
                 if (that != null)
                 {
                     return true;
                 }
-                return (false);
+                return false;
             }
 
             public override int GetHashCode()
@@ -938,7 +938,7 @@ namespace System.Text
                 }
 
                 // return true if we were allowed to do this
-                return (iCount >= 0 && iCount <= iSize);
+                return iCount >= 0 && iCount <= iSize;
             }
 
             // Return # of chars left in this fallback
index aaac975..dc88b1f 100644 (file)
@@ -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.
 
+#nullable enable
 // The worker functions in this file was optimized for performance. If you make changes
 // you should use care to consider all of the interesting cases.
 
@@ -155,8 +156,8 @@ namespace System.Text
         public override unsafe int GetByteCount(string chars)
         {
             // Validate input
-            if (chars==null)
-                throw new ArgumentNullException("s");
+            if (chars == null)
+                throw new ArgumentNullException(nameof(chars));
 
             fixed (char* pChars = chars)
                 return GetByteCount(pChars, chars.Length, null);
@@ -429,11 +430,11 @@ namespace System.Text
 
         // To simplify maintenance, the structure of GetByteCount and GetBytes should be
         // kept the same as much as possible
-        internal sealed override unsafe int GetByteCount(char* chars, int count, EncoderNLS baseEncoder)
+        internal sealed override unsafe int GetByteCount(char* chars, int count, EncoderNLS? baseEncoder)
         {
             // For fallback we may need a fallback buffer.
             // We wait to initialize it though in case we don't have any broken input unicode
-            EncoderFallbackBuffer fallbackBuffer = null;
+            EncoderFallbackBuffer? fallbackBuffer = null;
             char* pSrcForFallback;
 
             char* pSrc = chars;
@@ -454,7 +455,7 @@ namespace System.Text
                 {
                     fallbackBuffer = encoder.FallbackBuffer;
                     if (fallbackBuffer.Remaining > 0)
-                        throw new ArgumentException(SR.Format(SR.Argument_EncoderFallbackNotEmpty, this.EncodingName, encoder.Fallback.GetType()));
+                        throw new ArgumentException(SR.Format(SR.Argument_EncoderFallbackNotEmpty, this.EncodingName, encoder.Fallback!.GetType())); // TODO-NULLABLE: NullReferenceException
 
                     // Set our internal fallback interesting things.
                     fallbackBuffer.InternalInitialize(chars, pEnd, encoder, false);
@@ -839,18 +840,18 @@ namespace System.Text
         // Our workhorse
         // Note:  We ignore mismatched surrogates, unless the exception flag is set in which case we throw
         internal sealed override unsafe int GetBytes(
-            char* chars, int charCount, byte* bytes, int byteCount, EncoderNLS baseEncoder)
+            char* chars, int charCount, byte* bytes, int byteCount, EncoderNLS? baseEncoder)
         {
             Debug.Assert(chars != null, "[UTF8Encoding.GetBytes]chars!=null");
             Debug.Assert(byteCount >= 0, "[UTF8Encoding.GetBytes]byteCount >=0");
             Debug.Assert(charCount >= 0, "[UTF8Encoding.GetBytes]charCount >=0");
             Debug.Assert(bytes != null, "[UTF8Encoding.GetBytes]bytes!=null");
 
-            UTF8Encoder encoder = null;
+            UTF8Encoder? encoder = null;
 
             // For fallback we may need a fallback buffer.
             // We wait to initialize it though in case we don't have any broken input unicode
-            EncoderFallbackBuffer fallbackBuffer = null;
+            EncoderFallbackBuffer? fallbackBuffer = null;
             char* pSrcForFallback;
 
             char* pSrc = chars;
@@ -874,7 +875,7 @@ namespace System.Text
                     // We always need the fallback buffer in get bytes so we can flush any remaining ones if necessary
                     fallbackBuffer = encoder.FallbackBuffer;
                     if (fallbackBuffer.Remaining > 0 && encoder._throwOnOverflow)
-                        throw new ArgumentException(SR.Format(SR.Argument_EncoderFallbackNotEmpty, this.EncodingName, encoder.Fallback.GetType()));
+                        throw new ArgumentException(SR.Format(SR.Argument_EncoderFallbackNotEmpty, this.EncodingName, encoder.Fallback!.GetType())); // TODO-NULLABLE: NullReferenceException
 
                     // Set our internal fallback interesting things.
                     fallbackBuffer.InternalInitialize(chars, pEnd, encoder, true);
@@ -1327,7 +1328,7 @@ namespace System.Text
         //
         // To simplify maintenance, the structure of GetCharCount and GetChars should be
         // kept the same as much as possible
-        internal sealed override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS baseDecoder)
+        internal sealed override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS? baseDecoder)
         {
             Debug.Assert(count >= 0, "[UTF8Encoding.GetCharCount]count >=0");
             Debug.Assert(bytes != null, "[UTF8Encoding.GetCharCount]bytes!=null");
@@ -1340,7 +1341,7 @@ namespace System.Text
             // for the character being decoded
             int charCount = count;
             int ch = 0;
-            DecoderFallbackBuffer fallback = null;
+            DecoderFallbackBuffer? fallback = null;
 
             if (baseDecoder != null)
             {
@@ -1766,7 +1767,7 @@ namespace System.Text
         // To simplify maintenance, the structure of GetCharCount and GetChars should be
         // kept the same as much as possible
         internal sealed override unsafe int GetChars(
-            byte* bytes, int byteCount, char* chars, int charCount, DecoderNLS baseDecoder)
+            byte* bytes, int byteCount, char* chars, int charCount, DecoderNLS? baseDecoder)
         {
             Debug.Assert(chars != null, "[UTF8Encoding.GetChars]chars!=null");
             Debug.Assert(byteCount >= 0, "[UTF8Encoding.GetChars]count >=0");
@@ -1781,7 +1782,7 @@ namespace System.Text
 
             int ch = 0;
 
-            DecoderFallbackBuffer fallback = null;
+            DecoderFallbackBuffer? fallback = null;
             byte* pSrcForFallback;
             char* pTargetForFallback;
             if (baseDecoder != null)
@@ -2413,7 +2414,7 @@ namespace System.Text
         private unsafe byte[] GetBytesUnknown(ref byte* pSrc, int ch)
         {
             // Get our byte[]
-            byte[] bytesUnknown = null;
+            byte[] bytesUnknown;
 
             // See if it was a plain char
             // (have to check >= 0 because we have all sorts of wierd bit flags)
@@ -2553,7 +2554,7 @@ namespace System.Text
             _emitUTF8Identifier ? PreambleSpan :
             default;
 
-        public override bool Equals(object value)
+        public override bool Equals(object? value)
         {
             if (value is UTF8Encoding that)
             {
@@ -2561,7 +2562,7 @@ namespace System.Text
                        (EncoderFallback.Equals(that.EncoderFallback)) &&
                        (DecoderFallback.Equals(that.DecoderFallback));
             }
-            return (false);
+            return false;
         }
 
 
@@ -2596,7 +2597,7 @@ namespace System.Text
             {
                 get
                 {
-                    return (this.surrogateChar != 0);
+                    return this.surrogateChar != 0;
                 }
             }
         }
@@ -2624,7 +2625,7 @@ namespace System.Text
             {
                 get
                 {
-                    return (this.bits != 0);
+                    return this.bits != 0;
                 }
             }
         }
index 6c8197d..d3ae31c 100644 (file)
@@ -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.
 
+#nullable enable
 using System.Buffers;
 using System.Diagnostics;
 
index 6ee9ca0..ae2f8e2 100644 (file)
@@ -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.
 
+#nullable enable
 using System.Buffers;
 using System.Diagnostics;
 using System.IO;
@@ -58,7 +59,7 @@ namespace System.Text.Unicode
         /// <paramref name="value"/> but where all invalid UTF-8 sequences have been replaced
         /// with U+FFD.
         /// </summary>
-        public static Utf8String ValidateAndFixupUtf8String(Utf8String value)
+        public static Utf8String? ValidateAndFixupUtf8String(Utf8String? value)
         {
             if (Utf8String.IsNullOrEmpty(value))
             {
index dedfbe2..be99921 100644 (file)
@@ -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.
 
+#nullable enable
 using System.Diagnostics;
 using System.Runtime.InteropServices;
 
index 870962c..a652033 100644 (file)
@@ -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.
 
+#nullable enable
 //
 // Don't override IsAlwaysNormalized because it is just a Unicode Transformation and could be confused.
 //
@@ -116,7 +117,7 @@ namespace System.Text
         public override unsafe int GetByteCount(string s)
         {
             // Validate input
-            if (s==null)
+            if (s == null)
                 throw new ArgumentNullException(nameof(s));
 
             fixed (char* pChars = s)
@@ -150,10 +151,10 @@ namespace System.Text
                                               byte[] bytes, int byteIndex)
         {
             if (s == null || bytes == null)
-                throw new ArgumentNullException((s == null ? nameof(s) : nameof(bytes)), SR.ArgumentNull_Array);
+                throw new ArgumentNullException(s == null ? nameof(s) : nameof(bytes), SR.ArgumentNull_Array);
 
             if (charIndex < 0 || charCount < 0)
-                throw new ArgumentOutOfRangeException((charIndex < 0 ? nameof(charIndex) : nameof(charCount)), SR.ArgumentOutOfRange_NeedNonNegNum);
+                throw new ArgumentOutOfRangeException(charIndex < 0 ? nameof(charIndex) : nameof(charCount), SR.ArgumentOutOfRange_NeedNonNegNum);
 
             if (s.Length - charIndex < charCount)
                 throw new ArgumentOutOfRangeException(nameof(s), SR.ArgumentOutOfRange_IndexCount);
@@ -353,8 +354,7 @@ namespace System.Text
         //
         // End of standard methods copied from EncodingNLS.cs
         //
-
-        internal sealed override unsafe int GetByteCount(char* chars, int count, EncoderNLS encoder)
+        internal sealed override unsafe int GetByteCount(char* chars, int count, EncoderNLS? encoder)
         {
             Debug.Assert(chars != null, "[UnicodeEncoding.GetByteCount]chars!=null");
             Debug.Assert(count >= 0, "[UnicodeEncoding.GetByteCount]count >=0");
@@ -375,7 +375,7 @@ namespace System.Text
             bool wasHereBefore = false;
 
             // For fallback we may need a fallback buffer
-            EncoderFallbackBuffer fallbackBuffer = null;
+            EncoderFallbackBuffer? fallbackBuffer = null;
             char* charsForFallback;
 
             if (encoder != null)
@@ -391,7 +391,7 @@ namespace System.Text
                 {
                     fallbackBuffer = encoder.FallbackBuffer;
                     if (fallbackBuffer.Remaining > 0)
-                        throw new ArgumentException(SR.Format(SR.Argument_EncoderFallbackNotEmpty, this.EncodingName, encoder.Fallback.GetType()));
+                        throw new ArgumentException(SR.Format(SR.Argument_EncoderFallbackNotEmpty, this.EncodingName, encoder.Fallback!.GetType())); // TODO-NULLABLE: NullReferenceException
 
                     // Set our internal fallback interesting things.
                     fallbackBuffer.InternalInitialize(charStart, charEnd, encoder, false);
@@ -648,7 +648,7 @@ namespace System.Text
         }
 
         internal sealed override unsafe int GetBytes(
-            char* chars, int charCount, byte* bytes, int byteCount, EncoderNLS encoder)
+            char* chars, int charCount, byte* bytes, int byteCount, EncoderNLS? encoder)
         {
             Debug.Assert(chars != null, "[UnicodeEncoding.GetBytes]chars!=null");
             Debug.Assert(byteCount >= 0, "[UnicodeEncoding.GetBytes]byteCount >=0");
@@ -666,7 +666,7 @@ namespace System.Text
             char* charStart = chars;
 
             // For fallback we may need a fallback buffer
-            EncoderFallbackBuffer fallbackBuffer = null;
+            EncoderFallbackBuffer? fallbackBuffer = null;
             char* charsForFallback;
 
             // Get our encoder, but don't clear it yet.
@@ -680,7 +680,7 @@ namespace System.Text
                     // We always need the fallback buffer in get bytes so we can flush any remaining ones if necessary
                     fallbackBuffer = encoder.FallbackBuffer;
                     if (fallbackBuffer.Remaining > 0 && encoder._throwOnOverflow)
-                        throw new ArgumentException(SR.Format(SR.Argument_EncoderFallbackNotEmpty, this.EncodingName, encoder.Fallback.GetType()));
+                        throw new ArgumentException(SR.Format(SR.Argument_EncoderFallbackNotEmpty, this.EncodingName, encoder.Fallback!.GetType())); // TODO-NULLABLE: NullReferenceException
 
                     // Set our internal fallback interesting things.
                     fallbackBuffer.InternalInitialize(charStart, charEnd, encoder, false);
@@ -1004,12 +1004,12 @@ namespace System.Text
             return (int)(bytes - byteStart);
         }
 
-        internal sealed override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS baseDecoder)
+        internal sealed override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS? baseDecoder)
         {
             Debug.Assert(bytes != null, "[UnicodeEncoding.GetCharCount]bytes!=null");
             Debug.Assert(count >= 0, "[UnicodeEncoding.GetCharCount]count >=0");
 
-            UnicodeEncoding.Decoder decoder = (UnicodeEncoding.Decoder)baseDecoder;
+            UnicodeEncoding.Decoder? decoder = (UnicodeEncoding.Decoder?)baseDecoder;
 
             byte* byteEnd = bytes + count;
             byte* byteStart = bytes;
@@ -1022,7 +1022,7 @@ namespace System.Text
             int charCount = count >> 1;
 
             // For fallback we may need a fallback buffer
-            DecoderFallbackBuffer fallbackBuffer = null;
+            DecoderFallbackBuffer? fallbackBuffer = null;
 
             if (decoder != null)
             {
@@ -1152,7 +1152,7 @@ namespace System.Text
 
                             // Get fallback for previous high surrogate
                             // Note we have to reconstruct bytes because some may have been in decoder
-                            byte[] byteBuffer = null;
+                            byte[]? byteBuffer = null;
                             if (bigEndian)
                             {
                                 byteBuffer = new byte[]
@@ -1193,7 +1193,7 @@ namespace System.Text
 
                         // Get fallback for this low surrogate
                         // Note we have to reconstruct bytes because some may have been in decoder
-                        byte[] byteBuffer = null;
+                        byte[]? byteBuffer = null;
                         if (bigEndian)
                         {
                             byteBuffer = new byte[]
@@ -1232,7 +1232,7 @@ namespace System.Text
                     charCount--;
 
                     // fall back the high surrogate.
-                    byte[] byteBuffer = null;
+                    byte[]? byteBuffer = null;
                     if (bigEndian)
                     {
                         byteBuffer = new byte[]
@@ -1272,7 +1272,7 @@ namespace System.Text
                 {
                     // No hanging high surrogates allowed, do fallback and remove count for it
                     charCount--;
-                    byte[] byteBuffer = null;
+                    byte[]? byteBuffer = null;
                     if (bigEndian)
                     {
                         byteBuffer = new byte[]
@@ -1332,14 +1332,14 @@ namespace System.Text
         }
 
         internal sealed override unsafe int GetChars(
-            byte* bytes, int byteCount, char* chars, int charCount, DecoderNLS baseDecoder)
+            byte* bytes, int byteCount, char* chars, int charCount, DecoderNLS? baseDecoder)
         {
             Debug.Assert(chars != null, "[UnicodeEncoding.GetChars]chars!=null");
             Debug.Assert(byteCount >= 0, "[UnicodeEncoding.GetChars]byteCount >=0");
             Debug.Assert(charCount >= 0, "[UnicodeEncoding.GetChars]charCount >=0");
             Debug.Assert(bytes != null, "[UnicodeEncoding.GetChars]bytes!=null");
 
-            UnicodeEncoding.Decoder decoder = (UnicodeEncoding.Decoder)baseDecoder;
+            UnicodeEncoding.Decoder? decoder = (UnicodeEncoding.Decoder?)baseDecoder;
 
             // Need last vars
             int lastByte = -1;
@@ -1358,7 +1358,7 @@ namespace System.Text
             }
 
             // For fallback we may need a fallback buffer
-            DecoderFallbackBuffer fallbackBuffer = null;
+            DecoderFallbackBuffer? fallbackBuffer = null;
             char* charsForFallback;
 
             byte* byteEnd = bytes + byteCount;
@@ -1477,7 +1477,7 @@ namespace System.Text
                         {
                             // Get fallback for previous high surrogate
                             // Note we have to reconstruct bytes because some may have been in decoder
-                            byte[] byteBuffer = null;
+                            byte[]? byteBuffer = null;
                             if (bigEndian)
                             {
                                 byteBuffer = new byte[]
@@ -1529,7 +1529,7 @@ namespace System.Text
                         // Expected a previous high surrogate
                         // Get fallback for this low surrogate
                         // Note we have to reconstruct bytes because some may have been in decoder
-                        byte[] byteBuffer = null;
+                        byte[]? byteBuffer = null;
                         if (bigEndian)
                         {
                             byteBuffer = new byte[]
@@ -1591,7 +1591,7 @@ namespace System.Text
                 else if (lastChar > 0)
                 {
                     // Had a high surrogate, expected a low surrogate, fall back the high surrogate.
-                    byte[] byteBuffer = null;
+                    byte[]? byteBuffer = null;
                     if (bigEndian)
                     {
                         byteBuffer = new byte[]
@@ -1656,7 +1656,7 @@ namespace System.Text
                 if (lastChar > 0)
                 {
                     // No hanging high surrogates allowed, do fallback and remove count for it
-                    byte[] byteBuffer = null;
+                    byte[]? byteBuffer = null;
                     if (bigEndian)
                     {
                         byteBuffer = new byte[]
@@ -1840,7 +1840,7 @@ namespace System.Text
         }
 
 
-        public override bool Equals(object value)
+        public override bool Equals(object? value)
         {
             if (value is UnicodeEncoding that)
             {
index 065c938..acd9247 100644 (file)
@@ -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.
 
+#nullable enable
 using System.Runtime.CompilerServices;
 
 namespace System.Text
index bed3905..e2bbcfd 100644 (file)
@@ -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.
 
+#nullable enable
 using System.Runtime.CompilerServices;
 using System.Diagnostics;
 
index 31f51ce..de7fc50 100644 (file)
@@ -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.
 
+#nullable enable
 using System.Buffers;
 using System.Diagnostics;
 using System.Runtime.CompilerServices;
@@ -11,7 +12,7 @@ namespace System.Text
 {
     internal ref partial struct ValueStringBuilder
     {
-        private char[] _arrayToReturnToPool;
+        private char[]? _arrayToReturnToPool;
         private Span<char> _chars;
         private int _pos;
 
@@ -277,7 +278,7 @@ namespace System.Text
 
             _chars.CopyTo(poolArray);
 
-            char[] toReturn = _arrayToReturnToPool;
+            char[]? toReturn = _arrayToReturnToPool;
             _chars = _arrayToReturnToPool = poolArray;
             if (toReturn != null)
             {
@@ -288,7 +289,7 @@ namespace System.Text
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public void Dispose()
         {
-            char[] toReturn = _arrayToReturnToPool;
+            char[]? toReturn = _arrayToReturnToPool;
             this = default; // for safety, to avoid using pooled array if this instance is erroneously appended to again
             if (toReturn != null)
             {